-
Notifications
You must be signed in to change notification settings - Fork 110
Conversation
There are still many things to do.
|
} | ||
|
||
videodir = options.FolderOption('/home/mtomwing/Videos', auto_create=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should use something like ~/Videos or similar so that when someone else tests this it works with their home.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, forgot to change that back.
Fixed in b68e52f
Here's a better overview of the config architecture: And some better example code: from freeseer.framework.config.core import Config
from freeseer.framework.config.profile import ProfileManager
from freeseer.framework.config.persist import ConfigParserStorage
import freeseer.framework.config.options as options
class MyConfig(Config):
foo = options.BooleanOption(True)
bar = options.IntegerOption(10)
if __name__ == '__main__':
# Create a ProfileManager for our main profiles folder
profile_manager = ProfileManager('/tmp/freeseer/profiles')
# Get a specific profile (and create it if it does not exist) from the
# manager. i.e. /tmp/freeseer/profiles/default
profile = profile_manager.get('default')
# Setup a ConfigStorage instance using the ConfigParser module as a
# persistence mechanism. i.e. /tmp/freeseer/profiles/default/freeseer.conf
storage = ConfigParserStorage(profile, 'freeseer.conf')
# Create config with default values (if specified)
config = MyConfig()
# Options can be accessed as if they were proper attributes
assert(config.foo == True)
assert(config.bar == 10)
# A config instance can be saved to disk (or somewhere) using the
# ConfigStorage instance. 'Global' is a section heading required by
# ConfigParser.
storage.store(config, 'Global')
# Changes are only persisted when using ConfigStorage.store(...)
config.foo = False
config.bar = 9001
# The config instance can be 'reset' to its previously saved state.
storage.load(config, 'Global')
# Verified
assert(config.foo == True)
assert(config.bar == 10) |
# TODO: This should probably be in a constants file somewhere | ||
resmap = { | ||
'default': '0x0', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment to explain what 0x0 means (e.g. no scaling)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to reimplemente scaling. I meant the scaling map is not used at the moment because it's not been reimplemented yet since the rewrite of the backend. so moving it around should be easy. |
As far as I can tell, my refactor is complete. I've also added more than 100 new tests that should cover all of my new Config-related code. |
Awesome, thanks! It might take a while until I get to look at the changes though, still going through some other reviews. |
I did some tests using the config tool and recording tool and as far as I can tell the main functionality still works. Thanks for your contribution. Can you rebase when you get a chance? |
@zxiiro I will try and get to that today. |
… 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).
… 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).
dct['options'] = options | ||
cls = super(ConfigBase, meta).__new__(meta, name, bases, dct) | ||
for opt_name, option in options.iteritems(): | ||
opt_get = functools.partial(cls.get_value, name=opt_name, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line and L113 should be able to fit on a single line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 3a836d9.
@@ -80,8 +80,8 @@ def __init__(self, recordapp=None): | |||
self.avWidget = AVWidget() | |||
self.pluginloaderWidget = PluginLoaderWidget() | |||
|
|||
self.config = Config(settings.configdir) | |||
self.plugman = PluginManager(settings.configdir) | |||
# TODO: Make a better PluginManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have an issue open for this already? It would be a good place to provide more info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making the changes, looks good to me! 👍 |
I still need to fix up the docstring format as per the Freeseer guidelines. Same thing for any lines I cut to 80 chars instead of 120. |
When that's done and you squash the commits, I think it'll be ready to be merged. |
Do you think the diagram you made and the example code in #373 (comment) would be useful in the docs? |
@dideler not in it's current state. I made some slight changes to the architecture. |
… 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).
Rebased against master again. Rio's stuff is now included. |
Merged. Thanks for your contribution! |
This new config framework makes it easier to make persistent configuration files with Pythonic access.
This creates a profile @
$HOME/.freeseer/profiles/default
and creates a default config infreeseer.conf
with the defaults of any options defined inside the FreeseerConfig class.And the file it created:
The config object can be modified further and saved to disk whenever: