source: products/quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/manifest.py @ 1240

Last change on this file since 1240 was 1240, checked in by koval, 15 years ago

added enable-source-behaviour option to manifestimporter section

File size: 4.5 KB
Line 
1import os.path
2from xml.dom import minidom
3
4from zope.interface import classProvides, implements
5from zope.annotation.interfaces import IAnnotations
6
7from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
8from collective.transmogrifier.utils import defaultMatcher
9
10from quintagroup.transmogrifier.logger import VALIDATIONKEY
11
12class ManifestExporterSection(object):
13    classProvides(ISectionBlueprint)
14    implements(ISection)
15
16    def __init__(self, transmogrifier, name, options, previous):
17        self.previous = previous
18        self.context = transmogrifier.context
19
20        self.entrieskey = defaultMatcher(options, 'entries-key', name, 'entries')
21        self.fileskey = options.get('files-key', '_files').strip()
22
23    def __iter__(self):
24        for item in self.previous:
25            entrieskey = self.entrieskey(*item.keys())[0]
26            if not entrieskey:
27                yield item; continue
28
29            manifest = self.createManifest(item[entrieskey])
30
31            if manifest:
32                files = item.setdefault('_files', {})
33                item[self.fileskey]['manifest'] = {
34                    'name': '.objects.xml',
35                    'data': manifest,
36                }
37
38            yield item
39
40    def createManifest(self, entries):
41        if not entries:
42            return None
43        manifest = '<?xml version="1.0" ?>\n<manifest>\n'
44        for obj_id, obj_type in entries:
45            manifest += '  <record type="%s">%s</record>\n' % (obj_type, obj_id)
46        manifest += "</manifest>\n"
47        return manifest
48
49class ManifestImporterSection(object):
50    classProvides(ISectionBlueprint)
51    implements(ISection)
52
53    def __init__(self, transmogrifier, name, options, previous):
54        self.previous = previous
55        self.context = transmogrifier.context
56
57        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
58        self.fileskey = defaultMatcher(options, 'files-key', name, 'files')
59        self.typekey = options.get('type-key', '_type').strip()
60        self.enable_source_behaviour = options.get('enable-source-behaviour', 'true') == 'true' and True or False
61
62        # communication with logger
63        self.anno = IAnnotations(transmogrifier)
64        self.storage = self.anno.setdefault(VALIDATIONKEY, [])
65
66        # we need this dictionary to store manifest data, because reader section
67        # uses recursion when walking through content folders
68        self.manifests = {}
69
70    def __iter__(self):
71        for item in self.previous:
72            pathkey = self.pathkey(*item.keys())[0]
73            fileskey = self.fileskey(*item.keys())[0]
74
75            # skip items without path
76            if not pathkey: continue
77
78            path  = item[pathkey]
79
80            if path != '':
81                parent, item_id = os.path.split(path)
82                manifest = self.manifests.get(parent, {})
83
84                # skip that are not listed in their parent's manifest
85                if item_id not in manifest: continue
86
87                item[self.typekey] = manifest.pop(item_id)
88                # remove empty manifest dict
89                if not manifest:
90                    del self.manifests[parent]
91
92            # this item is folderish - parse manifest
93            if fileskey and 'manifest' in item[fileskey]:
94                self.extractManifest(path, item[fileskey]['manifest']['data'])
95
96            yield item
97
98        # now we yield items that were defined in manifests but not generated by
99        # previous sections - it is possible
100        if self.manifests and self.enable_source_behaviour:
101            containers = self.manifests.keys()
102            containers.sort()
103            for i in containers:
104                manifest = self.manifests[i]
105                ids = manifest.keys()
106                ids.sort()
107                for id_ in ids:
108                    if i == '':
109                        path = id_
110                    else:
111                        path = '/'.join([i, id_])
112                    self.storage.append(path)
113                    yield {pathkey: path, self.typekey: manifest[id_]}
114
115        # cleanup
116        if VALIDATIONKEY in self.anno:
117            del self.anno[VALIDATIONKEY]
118
119    def extractManifest(self, path, data):
120        doc = minidom.parseString(data)
121        objects = {}
122        for record in doc.getElementsByTagName('record'):
123            type_ = str(record.getAttribute('type'))
124            object_id = str(record.firstChild.nodeValue.strip())
125            objects[object_id] = type_
126        self.manifests[path] = objects
Note: See TracBrowser for help on using the repository browser.