source: products/quintagroup.transmogrifier/branches/plone-2.1/quintagroup.transmogrifier/quintagroup/transmogrifier/manifest.py @ 1237

Last change on this file since 1237 was 436, checked in by crchemist, 18 years ago

Fix an error in PingTool?.py

File size: 4.3 KB
Line 
1import os.path
2from xml.dom import minidom
3
4from zope.interface import classProvides, implements
5from zope.app.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
61        # communication with logger
62        self.anno = IAnnotations(transmogrifier)
63        self.storage = self.anno.setdefault(VALIDATIONKEY, [])
64
65        # we need this dictionary to store manifest data, because reader section
66        # uses recursion when walking through content folders
67        self.manifests = {}
68
69    def __iter__(self):
70        for item in self.previous:
71            pathkey = self.pathkey(*item.keys())[0]
72            fileskey = self.fileskey(*item.keys())[0]
73
74            # skip items without path
75            if not pathkey: continue
76
77            path  = item[pathkey]
78
79            if path != '':
80                parent, item_id = os.path.split(path)
81                manifest = self.manifests.get(parent, {})
82
83                # skip that are not listed in their parent's manifest
84                if item_id not in manifest: continue
85
86                item[self.typekey] = manifest.pop(item_id)
87                # remove empty manifest dict
88                if not manifest:
89                    del self.manifests[parent]
90
91            # this item is folderish - parse manifest
92            if fileskey and 'manifest' in item[fileskey]:
93                self.extractManifest(path, item[fileskey]['manifest']['data'])
94
95            yield item
96
97        # now we yield items that were defined in manifests but not generated by
98        # previous sections - it is posible
99        if self.manifests:
100            containers = self.manifests.keys()
101            containers.sort()
102            for i in containers:
103                manifest = self.manifests[i]
104                ids = manifest.keys()
105                ids.sort()
106                for id_ in ids:
107                    if i == '':
108                        path = id_
109                    else:
110                        path = '/'.join([i, id_])
111                    self.storage.append(path)
112                    yield {pathkey: path, self.typekey: manifest[id_]}
113       
114        # cleanup
115        if VALIDATIONKEY in self.anno:
116            del self.anno[VALIDATIONKEY]
117
118    def extractManifest(self, path, data):
119        doc = minidom.parseString(data)
120        objects = {}
121        for record in doc.getElementsByTagName('record'):
122            type_ = str(record.getAttribute('type'))
123            object_id = str(record.firstChild.nodeValue.strip())
124            objects[object_id] = type_
125        self.manifests[path] = objects
Note: See TracBrowser for help on using the repository browser.