diff --git a/README.txt b/README.txt index 3dfe836..ed5f501 100755 --- a/README.txt +++ b/README.txt @@ -837,52 +837,11 @@ informations about all parents of an object. Import/Export ============= -Nodes may be exported to and loaded from external sources, typically -file representations that allow the transfer of nodes from one Zope -instance to another. - - >>> from loops.external import NodesLoader - >>> loader = NodesLoader(views) - >>> data = [{'name': 'm2', 'path': '', 'description': u'desc 1', - ... 'title': u'M 2', 'body': u'test m2', 'nodeType': 'menu' }, - ... {'name': 'm21', 'path': 'm2', 'description': u'', - ... 'title': u'M 21', 'body': u'test m21', 'nodeType': 'page' }, - ... {'name': 'm114', 'path': 'm1/m11', 'description': u'', - ... 'title': u'M 114', 'body': u'test m114', 'nodeType': 'page' },] - >>> loader.load(data) - >>> views['m2']['m21'].title - u'M 21' - >>> views['m1']['m11']['m114'].title - u'M 114' - - >>> from loops.external import NodesExporter, NodesImporter - >>> exporter = NodesExporter(views) - >>> data = exporter.extractData() - >>> len(data) - 8 - >>> data[3]['path'] - u'm1/m11' - >>> data[3]['name'] - u'm112' - - >>> dumpname = os.path.dirname(__file__) + '/test.tmp' - >>> exporter.filename = dumpname - >>> exporter.dumpData() - -Load them again from the exported file: - - >>> importer = NodesImporter(views) - >>> importer.filename = dumpname - >>> imported = importer.getData() - >>> imported == data - True - - >>> loader.load(imported) +Obsolete - see package loops.external. Fin de partie ============= - >>> os.unlink(dumpname) >>> placefulTearDown() diff --git a/browser/configure.zcml b/browser/configure.zcml index 1176ebe..4108841 100644 --- a/browser/configure.zcml +++ b/browser/configure.zcml @@ -391,20 +391,16 @@ menu="zmi_views" title="Contents" /> - - + diff --git a/configure.zcml b/configure.zcml index c76f812..ef93674 100644 --- a/configure.zcml +++ b/configure.zcml @@ -325,9 +325,11 @@ + + diff --git a/external/README.txt b/external/README.txt index 1e55046..c4a7761 100644 --- a/external/README.txt +++ b/external/README.txt @@ -48,6 +48,16 @@ Creating the corresponding objects >>> adapted(concepts['myquery']).viewName 'mystuff.html' +Working with nodes +------------------ + + >>> input = ("node('home', u'Home', '', u'menu', body=u'Welcome')\n" + ... "node('myquery', u'My Query', 'home', u'page', " + ... " target='concepts/myquery')") + >>> reader = PyReader() + >>> elements = reader.read(input) + >>> loader.load(elements) + Exporting loops Objects ======================= @@ -60,7 +70,7 @@ Extracting elements >>> extractor = Extractor(loopsRoot) >>> elements = list(extractor.extract()) >>> len(elements) - 13 + 15 Writing object information to the external storage -------------------------------------------------- @@ -76,7 +86,9 @@ Writing object information to the external storage type(u'query', u'Query', options=u'', typeInterface='loops.query.IQueryConcept', viewName=u'')... concept(u'myquery', u'My Query', u'query', options=u'', viewName='mystuff.html')... - child(u'projects', u'customer', u'standard')... + child(u'projects', u'customer', u'standard') + node('home', u'Home', '', u'menu', body=u'Welcome') + node('myquery', u'My Query', 'home', u'page', target=u'concepts/myquery')... The Export/Import View diff --git a/external/__init__.py b/external/__init__.py index 1b17f2a..ea79f84 100644 --- a/external/__init__.py +++ b/external/__init__.py @@ -2,4 +2,4 @@ $Id$ """ -from loops.external.external import NodesLoader, NodesExporter, NodesImporter +#from loops.external.external import NodesLoader, NodesExporter, NodesImporter diff --git a/external/base.py b/external/base.py index 914f676..b8dec5e 100644 --- a/external/base.py +++ b/external/base.py @@ -28,7 +28,7 @@ import itertools from zope import component from zope.cachedescriptors.property import Lazy from zope.interface import implements -from zope.traversing.api import getName +from zope.traversing.api import getName, getParent from cybertools.composer.interfaces import IInstance from cybertools.composer.schema.interfaces import ISchemaFactory @@ -49,6 +49,14 @@ class Base(object): def concepts(self): return self.context.getConceptManager() + @Lazy + def resources(self): + return self.context.getResourceManager() + + @Lazy + def views(self): + return self.context.getViewManager() + @Lazy def typeConcept(self): return self.concepts.getTypeConcept() @@ -84,8 +92,7 @@ class Extractor(Base): self.extractChildren(), #self.extractResources(), #self.extractResourceRelations(), - #self.extractNodes(), - #self.extractTargets(), + self.extractNodes(), ) def extractTypes(self): @@ -141,3 +148,21 @@ class Extractor(Base): args.append(r.relevance) yield childElement(*args) + def extractNodes(self, parent=None, path=''): + if parent is None: + parent = self.views + element = elementTypes['node'] + for name, obj in parent.items(): + data = {} + for attr in ('description', 'body', 'viewName'): + value = getattr(obj, attr) + if value: + data[attr] = value + target = obj.target + if target is not None: + data['target'] = '/'.join((getName(getParent(target)), getName(target))) + yield element(name, obj.title, path, obj.nodeType, **data) + childPath = path and '/'.join((path, name)) or name + for elem in self.extractNodes(obj, childPath): + yield elem + diff --git a/external/element.py b/external/element.py index 150d2ec..25f7ffb 100644 --- a/external/element.py +++ b/external/element.py @@ -26,7 +26,7 @@ $Id$ from zope.cachedescriptors.property import Lazy from zope.dottedname.resolve import resolve from zope.interface import implements -from zope.traversing.api import getName +from zope.traversing.api import getName, traverse from loops.external.interfaces import IElement @@ -57,7 +57,7 @@ class ConceptElement(Element): def __call__(self, loader): type = loader.concepts[self['type']] kw = dict((k, v) for k, v in self.items() - if k not in ('name', 'title', 'type')) + if k not in self.posArgs) loader.addConcept(self['name'], self['title'], type, **kw) @@ -81,11 +81,6 @@ class TypeElement(ConceptElement): loader.addConcept(self['name'], self['title'], 'type', **kw) -class ResourceElement(ConceptElement): - - elementType = 'resource' - - class ChildElement(Element): elementType = 'child' @@ -99,9 +94,56 @@ class ChildElement(Element): loader.assignChild(self['first'], self['second'], self['predicate']) +class NodeElement(Element): + + elementType = 'node' + posArgs = ('name', 'title', 'path', 'type') + + def __init__(self, *args, **kw): + for idx, arg in enumerate(args): + self[self.posArgs[idx]] = arg + for k, v in kw.items(): + self[k] = v + + def __call__(self, loader): + type = self['type'] + cont = traverse(loader.views, self['path']) + target = self.pop('target', None) + kw = dict((k, v) for k, v in self.items() + if k not in self.posArgs) + node = loader.addNode(self['name'], self['title'], cont, type, **kw) + if target is not None: + node.target = traverse(loader.context, target) + + +# not yet implemented + +class ResourceElement(Element): + + elementType = 'resource' + posArgs = ('name', 'title', 'type') + + def __call__(self, loader): + type = loader.concepts[self['type']] + kw = dict((k, v) for k, v in self.items() + if k not in self.posArgs) + loader.addResource(self['name'], self['title'], type, **kw) + + +class ResourceRelationElement(ChildElement): + + elementType = 'resourceRelation' + + def __call__(self, loader): + loader.assignResource(self['first'], self['second'], self['predicate']) + + +# element registry + elementTypes = dict( type=TypeElement, concept=ConceptElement, resource=ResourceElement, child=ChildElement, + node=NodeElement, ) diff --git a/external/external.py b/external/external.py index 80851c0..6d7381a 100644 --- a/external/external.py +++ b/external/external.py @@ -19,6 +19,8 @@ """ Adapter implementations for export, import, ... +Obsolete, replaced by functionality in loops.external.base and other modules + $Id$ """