Fix #382 Add Video Playback feature

This feature adds the ability to play back the last recorded video after
a video has been recorded. The playback button is hidden until a last
video exists.

This feature is supported on Linux and Windows.

Closes #382
Signed-off-by: Thanh Ha <thanh.ha@alumni.carleton.ca>
Feature #373: Declarative configs and profile / configuration refactor

New concepts:
    - ProfileManager, Profile
    - ConfigStorage, Config, Option

Profiles and Profile Management
===============================

`~/.freeseer/profiles` is now managed by a `ProfileManager`. It handles
creating profiles.

Each profile is now modeled by a `Profile` object. It can be used to get
files from within its folder in a pythonic-manner.

See `freeseer.framework.config.profile`.

Configuration
==============

`FreeseerConfig` and future "configuration classes" have been reworked
to remove needless boilerplate, provide stricter type checking, and
be easily persisted to a file or some other backend. Configs written in
a similar declarative manner like Django or SqlAlchemy models:

    from freeseer.framework.config import Config
    from freeseer.framework.config import options

    class MyConfig(Config):
        name = options.StringOption('foo')
        age = options.IntegerOption()

Upon instantiation, those options can be accessed as if they were
regular class attributes. Any changes to their values will be stored
internally. As you can imagine, values assigned are validated by the
various options (e.g. age only accepts integers).

Persistance of configs is handled by ConfigStorages. I've only
implemented two so far inside `freeseer.framework.config.persist`: one
that uses `ConfigParser` for INI-style files, and one that uses a JSON
file.

    from freeseer.framework.config.persist import ConfigParserStorage

    # load the config, if the file doesn't exist it'll use defaults
    storage = ConfigParserStorage('/tmp/path/to/file.conf')
    config = storage.load(MyConfig(), 'section')

    # make your changes
    config.name = 'michael'
    config.age = 22

    # save them
    storage.store(config, 'section')

This will create a file that looks like:

    [section]
    name = michael
    age = 22

In conjunction with the `Profile` abstraction, you have a nice way of
storing config files inside a profile (e.g. freeseer.conf and
plugins.conf).