From e7b83a83ad61b8de4f661d8f06d56cb983dea8ae Mon Sep 17 00:00:00 2001 From: helmutm Date: Sat, 12 Apr 2008 14:00:36 +0000 Subject: [PATCH] options/config management basically working git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2521 fd906abe-77d9-0310-91a1-e0d9ade77398 --- config/README.txt | 30 ++++++++++++++++++++++++------ config/base.py | 32 ++++++++++++++++++++++++++------ config/configure.zcml | 15 +++++++++++++++ configure.zcml | 1 + organize/tracking/README.txt | 2 ++ organize/tracking/change.py | 8 +++++--- tests/setup.py | 3 +++ util.py | 4 ++++ 8 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 config/configure.zcml diff --git a/config/README.txt b/config/README.txt index 3287953..247a4db 100644 --- a/config/README.txt +++ b/config/README.txt @@ -34,9 +34,6 @@ Options Adapters Global and site options ----------------------- - >>> from loops.config.base import LoopsOptions - >>> component.provideAdapter(LoopsOptions) - >>> from cybertools.meta.interfaces import IOptions >>> opt = IOptions(loopsRoot) >>> opt @@ -49,15 +46,16 @@ some options. >>> loopsRoot.options = ['useVersioning', 'organize.tracking:changes, access'] >>> opt = IOptions(loopsRoot) - >>> print opt - organize(tracking=['changes', 'access']) - useVersioning=True >>> opt.organize.tracking ['changes', 'access'] >>> opt.useVersioning True + >>> print opt + organize(tracking=['changes', 'access']) + useVersioning=True + If we query an option that is not defined on the site level we get a dummy element that corresponds to False. @@ -66,6 +64,26 @@ dummy element that corresponds to False. >>> bool(opt.i18n.languages) False +We can use a utility for providing global settings. + + >>> from cybertools.meta.interfaces import IOptions + >>> globalOpt = component.getUtility(IOptions) + >>> globalOpt.i18n.languages = ['en', 'de'] + >>> globalOpt.i18n.languages + ['en', 'de'] + +If we call the site options with the key we want to query the global +options will be used as a fallback. + + >>> opt('i18n.languages') + ['en', 'de'] + +User options (preferences) +-------------------------- + +Type- and object-based settings +------------------------------- + Fin de partie ============= diff --git a/config/base.py b/config/base.py index 9bab435..7f83470 100644 --- a/config/base.py +++ b/config/base.py @@ -22,15 +22,26 @@ Adapters and others classes for analyzing resources. $Id$ """ +import os from zope.cachedescriptors.property import Lazy from zope import component from zope.component import adapts from zope.traversing.api import getName, getParent from cybertools.meta.config import Options +from cybertools.meta.config import GlobalOptions as BaseGlobalOptions +from cybertools.meta.interfaces import IOptions from cybertools.meta.namespace import Executor, ExecutionError from cybertools.typology.interfaces import IType from loops.interfaces import ILoops +from loops import util + + +class GlobalOptions(BaseGlobalOptions): + + @Lazy + def _filename(self): + return os.path.join(util.getEtcDirectory(), 'loops.cfg') class LoopsOptions(Options): @@ -39,11 +50,24 @@ class LoopsOptions(Options): builtins = Options.builtins + ('True', 'False') True, False = True, False + _initialized = False def __init__(self, context, *args, **kw): self.context = context super(LoopsOptions, self).__init__(*args, **kw) - self.loadContextOptions() + #self.loadContextOptions() + + def __getitem__(self, key): + if not self._initialized: + self._initialized = True + self.loadContextOptions() + return super(LoopsOptions, self).__getitem__(key) + + def __call__(self, key, default=None): + value = super(LoopsOptions, self).__call__(key) + if value is None: + value = component.getUtility(IOptions)(key, default) + return value def parseContextOptions(self): def result(): @@ -61,8 +85,4 @@ class LoopsOptions(Options): code = self.parseContextOptions() rc = Executor(self).execute(code) if rc: - raise ExecutionError('\n' + result) - - #def __getitem__(self, key): - # opt = self.baseOptions.get(key) - # return opt + raise ExecutionError('\n' + rc) diff --git a/config/configure.zcml b/config/configure.zcml new file mode 100644 index 0000000..aaa1958 --- /dev/null +++ b/config/configure.zcml @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/configure.zcml b/configure.zcml index f237c72..b965ad4 100644 --- a/configure.zcml +++ b/configure.zcml @@ -400,6 +400,7 @@ + diff --git a/organize/tracking/README.txt b/organize/tracking/README.txt index a571b7c..8c08d90 100644 --- a/organize/tracking/README.txt +++ b/organize/tracking/README.txt @@ -48,6 +48,8 @@ Recording changes to objects >>> from loops.organize.tracking.change import recordModification >>> component.provideHandler(recordModification) + >>> loopsRoot.options = ['organize.tracking:changes'] + >>> tTask = concepts['task'] >>> from loops.concept import Concept >>> from loops.setup import addAndConfigureObject diff --git a/organize/tracking/change.py b/organize/tracking/change.py index 4921801..c2e7da4 100644 --- a/organize/tracking/change.py +++ b/organize/tracking/change.py @@ -28,6 +28,7 @@ from zope.cachedescriptors.property import Lazy from zope.component import adapter from zope.lifecycleevent.interfaces import IObjectModifiedEvent, IObjectCreatedEvent +from cybertools.meta.interfaces import IOptions from cybertools.tracking.btree import Track, getTimeStamp from loops.concept import ConceptManager from loops.resource import ResourceManager @@ -49,14 +50,15 @@ class ChangeManager(object): @Lazy def options(self): - return IOptions(self.context) + #return IOptions(self.context) + return IOptions(self.loopsRoot) @Lazy def valid(self): - return not (self.context is None or + return (not (self.context is None or self.storage is None or self.person is None) - # and 'changes' in self.options.tracking + and 'changes' in self.options('organize.tracking', ())) @Lazy def loopsRoot(self): diff --git a/tests/setup.py b/tests/setup.py index dcac7fc..3b77193 100644 --- a/tests/setup.py +++ b/tests/setup.py @@ -47,6 +47,7 @@ from loops.browser.node import ViewPropertiesConfigurator from loops.common import NameChooser from loops.concept import Concept from loops.concept import IndexAttributes as ConceptIndexAttributes +from loops.config.base import GlobalOptions, LoopsOptions from loops.interfaces import ILoopsObject, IIndexAttributes from loops.interfaces import IDocument, IFile, ITextDocument from loops.organize.memberinfo import MemberInfoProvider @@ -119,6 +120,8 @@ class TestSite(object): component.provideHandler(grantAcquiredSecurity) component.provideHandler(revokeAcquiredSecurity) component.provideAdapter(BaseSecuritySetter) + component.provideAdapter(LoopsOptions) + component.provideUtility(GlobalOptions()) component.provideAdapter(Instance) component.provideAdapter(Editor, name='editor') diff --git a/util.py b/util.py index 0aab98d..b34f5a8 100644 --- a/util.py +++ b/util.py @@ -108,3 +108,7 @@ def getVarDirectory(request=None): os.path.dirname(cybertools.__file__)))) varDir = os.path.join(instanceHome, 'var') return varDir + +def getEtcDirectory(request=None): + varDir = getVarDirectory(request) + return os.path.join(os.path.dirname(varDir), 'etc')