Changeset 1446 in products
- Timestamp:
- Dec 8, 2009 7:53:25 AM (14 years ago)
- Location:
- quintagroup.transmogrifier/trunk
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
quintagroup.transmogrifier/trunk
- Property svn:mergeinfo changed from /quintagroup.transmogrifier/branches/plone-2.1/quintagroup.transmogrifier:1387-1389,1394-1413 to /quintagroup.transmogrifier/branches/plone-2.1/quintagroup.transmogrifier:1387-1389,1394-1413,1426-1444
-
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/adapters/exporting.py
r460 r1446 10 10 from Products.Archetypes import config as atcfg 11 11 12 from collective.transmogrifier.interfaces import ITransmogrifier 13 12 14 from quintagroup.transmogrifier.interfaces import IExportDataCorrector 13 15 … … 16 18 """ 17 19 implements(IExportDataCorrector) 18 adapts(IBaseObject )20 adapts(IBaseObject, ITransmogrifier) 19 21 20 def __init__(self, context ):22 def __init__(self, context, transmogrifier): 21 23 self.context = context 24 self.transmogrifier = transmogrifier 22 25 23 26 def __call__(self, data): … … 57 60 58 61 implements(IExportDataCorrector) 59 adapts(IATTopicCriterion )62 adapts(IATTopicCriterion, ITransmogrifier) 60 63 61 def __init__(self, context ):64 def __init__(self, context, transmogrifier): 62 65 self.context = context 66 self.transmogrifier = transmogrifier 63 67 self.marshaller = getComponent('atxml') 64 68 -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/adapters/importing.py
r460 r1446 7 7 from Products.Archetypes.interfaces import IBaseObject 8 8 from Products.Archetypes import atapi 9 10 from collective.transmogrifier.interfaces import ITransmogrifier 9 11 10 12 from quintagroup.transmogrifier.interfaces import IImportDataCorrector … … 17 19 """ 18 20 implements(IImportDataCorrector) 19 adapts(IBaseObject )21 adapts(IBaseObject, ITransmogrifier) 20 22 21 def __init__(self, context ):23 def __init__(self, context, transmogrifier): 22 24 self.context = context 25 self.transmogrifier = transmogrifier 23 26 24 27 def __call__(self, data): -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/binary.py
r1414 r1446 9 9 10 10 from collective.transmogrifier.interfaces import ISection, ISectionBlueprint 11 from collective.transmogrifier.utils import defaultMatcher 11 from collective.transmogrifier.utils import defaultMatcher, Condition 12 12 13 13 class FileExporterSection(object): … … 24 24 #self.excludekey = defaultMatcher(options, 'exclude-key', name, 'excluded_fields') 25 25 self.excludekey = options.get('exclude-key', '_excluded_fields').strip() 26 26 27 self.exclude_fieldtypes = filter(None, [i.strip() for i in 28 options.get('exclude-fieldtypes', '').splitlines()]) 27 29 self.doc = minidom.Document() 30 self.condition = Condition(options.get('condition', 'python:True'), 31 transmogrifier, name, options) 28 32 29 33 def __iter__(self): … … 45 49 for field in schema.keys(): 46 50 if obj.isBinary(field): 51 binary_field_names.append(field) 52 if not self.condition(item, context=obj, fname=field): 53 continue 47 54 fname, ct, data = self.extractFile(obj, field) 48 binary_field_names.append(field)49 55 if fname == '' or data == '': 50 56 # empty file fields have empty filename and empty data … … 139 145 self.contextkey = defaultMatcher(options, 'context-key', name, 'import_context') 140 146 147 self.condition = Condition(options.get('condition', 'python:True'), 148 transmogrifier, name, options) 149 141 150 def __iter__(self): 142 151 for item in self.previous: … … 167 176 if data is None: 168 177 continue 178 if not self.condition(item, context=obj, fname=field, 179 filename=fname, data=data, mimetype=ct): 180 continue 169 181 mutator = obj.getField(field).getMutator(obj) 170 182 mutator(data, filename=fname, mimetype=ct) -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/binary.txt
r453 r1446 17 17 section. 18 18 19 Also this section provides condition option which, if specified, exports/imports 20 this or another binary field only if condition expression evaluates to true. 21 19 22 >>> import pprint 20 23 >>> binary = """ … … 32 35 ... [fileexporter] 33 36 ... blueprint = quintagroup.transmogrifier.fileexporter 37 ... condition = python:fname != 'image' 34 38 ... 35 39 ... [dataprinter] … … 58 62 'name': '.file-fields.xml'}}, 59 63 '_path': 'spam/eggs/foo'} 60 <?xml version="1.0" ?>64 <?xml version="1.0" encoding="utf-8"?> 61 65 <manifest> 62 66 <field name="file"> 63 <filename>archive.tar.gz</filename> 64 <mimetype>application/x-tar</mimetype> 67 <filename> 68 archive.tar.gz 69 </filename> 70 <mimetype> 71 application/x-tar 72 </mimetype> 65 73 </field> 66 74 </manifest> … … 70 78 71 79 TODO: write test for getting data for fields from import context 80 81 The ``condition`` expression hass access to the following: 82 83 =================== ========================================================== 84 ``item`` the current pipeline item 85 ``transmogrifier`` the transmogrifier 86 ``name`` the name of the splitter section 87 ``options`` the splitter options 88 ``modules`` sys.modules 89 ``context`` the current content object 90 ``fname`` the name of the field being processed 91 ``filename`` the file name binary field is loaded into (import only) 92 ``data`` data read from the file (import only) 93 ``mimetype`` data mimetype (import only) 94 =================== ========================================================== -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/datacorrector.py
r277 r1446 1 1 from zope.interface import classProvides, implements 2 from zope.component import query Adapter2 from zope.component import queryMultiAdapter 3 3 4 4 from collective.transmogrifier.interfaces import ISection, ISectionBlueprint … … 14 14 def __init__(self, transmogrifier, name, options, previous): 15 15 self.previous = previous 16 self.transmogrifier = transmogrifier 16 17 self.context = transmogrifier.context 17 18 … … 52 53 if not name in file_store: 53 54 continue 54 adapter = queryAdapter(obj, self.interface, name) 55 adapter = queryMultiAdapter((obj, self.transmogrifier), 56 self.interface, name) 55 57 if adapter: 56 58 file_store[name] = adapter(file_store[name]) -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/exportimport.py
r1416 r1446 1 # -*- coding: utf-8 -*- 1 2 import os 2 3 import tempfile -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/manifest.txt
r1240 r1446 60 60 'name': '.objects.xml'}}, 61 61 '_path': ''} 62 <?xml version="1.0" ?>62 <?xml version="1.0" encoding="utf-8"?> 63 63 <manifest> 64 <record type="Folder">news</record> 65 <record type="Folder">events</record> 66 <record type="Document">front-page</record> 67 <record type="Document">only-in-manifest</record> 64 <record type="Folder"> 65 news 66 </record> 67 <record type="Folder"> 68 events 69 </record> 70 <record type="Document"> 71 front-page 72 </record> 73 <record type="Document"> 74 only-in-manifest 75 </record> 68 76 </manifest> 69 77 <BLANKLINE> … … 73 81 '_path': 'news', 74 82 '_type': 'Folder'} 75 <?xml version="1.0" ?>83 <?xml version="1.0" encoding="utf-8"?> 76 84 <manifest> 77 <record type="Topic">aggregator</record> 78 <record type="File">once-more</record> 85 <record type="Topic"> 86 aggregator 87 </record> 88 <record type="File"> 89 once-more 90 </record> 79 91 </manifest> 80 92 <BLANKLINE> -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/propertymanager.py
r453 r1446 1 from copy import deepcopy 1 2 from xml.dom import minidom 2 3 … … 14 15 NodeAdapterBase class. 15 16 """ 17 18 _encoding = 'utf-8' 19 16 20 def __init__(self): 17 21 pass … … 29 33 return text 30 34 35 def _extractProperties(self): 36 fragment = self._doc.createDocumentFragment() 37 38 for prop_map in self.context._propertyMap(): 39 prop_id = prop_map['id'] 40 if prop_id == 'i18n_domain': 41 continue 42 43 # Don't export read-only nodes 44 if 'w' not in prop_map.get('mode', 'wd'): 45 continue 46 47 node = self._doc.createElement('property') 48 node.setAttribute('name', prop_id) 49 50 prop = self.context.getProperty(prop_id) 51 if isinstance(prop, (tuple, list)): 52 for value in prop: 53 if isinstance(value, str): 54 value = value.decode(self._encoding) 55 child = self._doc.createElement('element') 56 child.appendChild(self._doc.createTextNode(value)) 57 node.appendChild(child) 58 else: 59 if prop_map.get('type') == 'boolean': 60 prop = unicode(bool(prop)) 61 elif isinstance(prop, str): 62 prop = prop.decode(self._encoding) 63 elif not isinstance(prop, basestring): 64 prop = unicode(prop) 65 child = self._doc.createTextNode(prop) 66 node.appendChild(child) 67 68 if 'd' in prop_map.get('mode', 'wd') and not prop_id == 'title': 69 prop_type = prop_map.get('type', 'string') 70 node.setAttribute('type', unicode(prop_type)) 71 select_variable = prop_map.get('select_variable', None) 72 if select_variable is not None: 73 node.setAttribute('select_variable', select_variable) 74 75 if hasattr(self, '_i18n_props') and prop_id in self._i18n_props: 76 node.setAttribute('i18n:translate', '') 77 78 fragment.appendChild(node) 79 80 return fragment 81 82 def _initProperties(self, node): 83 obj = self.context 84 if node.hasAttribute('i18n:domain'): 85 i18n_domain = str(node.getAttribute('i18n:domain')) 86 obj._updateProperty('i18n_domain', i18n_domain) 87 for child in node.childNodes: 88 if child.nodeName != 'property': 89 continue 90 prop_id = str(child.getAttribute('name')) 91 prop_map = obj.propdict().get(prop_id, None) 92 93 if prop_map is None: 94 if child.hasAttribute('type'): 95 val = str(child.getAttribute('select_variable')) 96 prop_type = str(child.getAttribute('type')) 97 obj._setProperty(prop_id, val, prop_type) 98 prop_map = obj.propdict().get(prop_id, None) 99 else: 100 raise ValueError("undefined property '%s'" % prop_id) 101 102 if not 'w' in prop_map.get('mode', 'wd'): 103 raise BadRequest('%s cannot be changed' % prop_id) 104 105 elements = [] 106 remove_elements = [] 107 for sub in child.childNodes: 108 if sub.nodeName == 'element': 109 if len(sub.childNodes) > 0: 110 value = sub.childNodes[0].nodeValue 111 if isinstance(value, unicode): 112 value = value.encode(self._encoding) 113 if self._convertToBoolean(sub.getAttribute('remove') 114 or 'False'): 115 remove_elements.append(value) 116 if value in elements: 117 elements.remove(value) 118 else: 119 elements.append(value) 120 if value in remove_elements: 121 remove_elements.remove(value) 122 123 if elements or prop_map.get('type') == 'multiple selection': 124 prop_value = tuple(elements) or () 125 elif prop_map.get('type') == 'boolean': 126 prop_value = self._convertToBoolean(self._getNodeText(child)) 127 else: 128 # if we pass a *string* to _updateProperty, all other values 129 # are converted to the right type 130 prop_value = self._getNodeText(child).encode(self._encoding) 131 132 if not self._convertToBoolean(child.getAttribute('purge') 133 or 'True'): 134 # If the purge attribute is False, merge sequences 135 prop = obj.getProperty(prop_id) 136 if isinstance(prop, (tuple, list)): 137 prop_value = (tuple([p for p in prop 138 if p not in prop_value and 139 p not in remove_elements]) + 140 tuple(prop_value)) 141 142 obj._updateProperty(prop_id, prop_value) 143 31 144 class PropertiesExporterSection(object): 32 145 classProvides(ISectionBlueprint) … … 76 189 continue 77 190 if elem.getAttribute('name') not in excluded_props: 78 node.appendChild( elem)191 node.appendChild(deepcopy(elem)) 79 192 if node.hasChildNodes(): 80 193 doc.appendChild(node) -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/sitewalker.py
r415 r1446 3 3 4 4 from collective.transmogrifier.interfaces import ISection, ISectionBlueprint 5 from collective.transmogrifier.utils import Condition 5 6 6 7 from Products.CMFCore.interfaces import IFolderish … … 23 24 self.storage = self.anno.setdefault(VALIDATIONKEY, []) 24 25 26 self.condition = Condition(options.get('condition', 'python:True'), 27 transmogrifier, name, options) 28 29 def getContained(self, obj): 30 contained = [(k, v) for k, v in obj.contentItems() 31 if self.condition(None, context=v)] 32 return tuple(contained) 33 25 34 def walk(self, obj): 26 35 if IFolderish.providedBy(obj) or IBaseFolder.providedBy(obj): 27 contained = [(k, v.getPortalTypeName()) for k, v in obj.contentItems()]28 yield obj, tuple( contained)29 for v in obj.contentValues():36 contained = self.getContained(obj) 37 yield obj, tuple([(k, v.getPortalTypeName()) for k, v in contained]) 38 for k, v in contained: 30 39 for x in self.walk(v): 31 40 yield x -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/sitewalker.txt
r275 r1446 11 11 pairs of contained items. 12 12 13 You can also specify an optional ``condition`` option; if given, content object 14 is going into pipeline only if the condition, which is also a TALES is true. 15 13 16 >>> sitewalker = """ 14 17 ... [transmogrifier] … … 19 22 ... [sitewalker] 20 23 ... blueprint = quintagroup.transmogrifier.sitewalker 21 ... 24 ... condition = python:context.getPortalTypeName() not in ('File', 'Image') 25 ... 22 26 ... [printer] 23 27 ... blueprint = collective.transmogrifier.sections.tests.pprinter … … 38 42 {'_type': 'Document', '_path': 'folder1/document2'} 39 43 {'_type': 'Document', '_path': 'document3'} 44 45 46 The ``condition`` expression has an access to the following: 47 48 =================== ========================================================== 49 ``context`` the current content object 50 ``transmogrifier`` the transmogrifier 51 ``name`` the name of the splitter section 52 ``options`` the splitter options 53 ``modules`` sys.modules 54 =================== ========================================================== -
quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/tests.py
r1381 r1446 485 485 test.globs['transmogrifier'].context = test.globs['plone'] 486 486 487 from collective.transmogrifier.interfaces import ITransmogrifier 487 488 from quintagroup.transmogrifier.interfaces import IExportDataCorrector, \ 488 489 IImportDataCorrector … … 490 491 class MockExportAdapter(object): 491 492 implements(IExportDataCorrector) 492 adapts(MockPortal )493 def __init__(self, context ):493 adapts(MockPortal, ITransmogrifier) 494 def __init__(self, context, transmogrifier): 494 495 self.context = context 496 self.transmogrifier = transmogrifier 495 497 496 498 def __call__(self, data): … … 501 503 class MockImportAdapter(object): 502 504 implements(IImportDataCorrector) 503 adapts(MockPortal )504 def __init__(self, context ):505 adapts(MockPortal, ITransmogrifier) 506 def __init__(self, context, transmogrifier): 505 507 self.context = context 508 self.transmogrifier = transmogrifier 506 509 507 510 def __call__(self, data): … … 810 813 return 'binary data' 811 814 else: 812 return ' '815 return 'image' 813 816 814 817 def getMutator(self, obj):
Note: See TracChangeset
for help on using the changeset viewer.