source: products/quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/exportimport.py @ 1589

Last change on this file since 1589 was 1485, checked in by mylan, 14 years ago

Fix #126

File size: 6.1 KB
Line 
1# -*- coding: utf-8 -*-
2import os
3import tempfile
4
5from zope.interface import implements
6from zope.annotation import IAnnotations
7
8from collective.transmogrifier.interfaces import ITransmogrifier
9from collective.transmogrifier.transmogrifier import _load_config, constructPipeline
10from collective.transmogrifier.transmogrifier import configuration_registry
11
12from Products.GenericSetup.context import TarballExportContext, TarballImportContext
13from Products.GenericSetup.interfaces import IFilesystemImporter
14
15from quintagroup.transmogrifier.writer import WriterSection
16from quintagroup.transmogrifier.reader import ReaderSection
17from quintagroup.transmogrifier.configview import ANNOKEY
18
19EXPORT_CONFIG = 'export'
20IMPORT_CONFIG = 'import'
21
22CONFIGFILE = None
23def registerPersistentConfig(site, type_):
24    """ Try to get persistent pipeline configuration of given type (export or import)
25        and register it for use with transmogrifier.
26    """
27    global CONFIGFILE
28    anno = IAnnotations(site)
29    key = '%s.%s' % (ANNOKEY, type_)
30    config = anno.has_key(key) and anno[key] or None
31
32    # unregister old config
33    name = 'persitent-%s' % type_
34    if name in configuration_registry._config_ids:
35        configuration_registry._config_ids.remove(name)
36        del configuration_registry._config_info[name]
37
38    # register new
39    if config is not None:
40        title = description = u'Persistent %s pipeline'
41        tf = tempfile.NamedTemporaryFile('w+t', suffix='.cfg')
42        tf.write(config)
43        tf.seek(0)
44        CONFIGFILE = tf
45        configuration_registry.registerConfiguration(name, title, description, tf.name)
46        return name
47    else:
48        return None
49
50def exportSiteStructure(context):
51
52    transmogrifier = ITransmogrifier(context.getSite())
53
54    # we don't use transmogrifer's __call__ method, because we need to do
55    # some modification in pipeline sections
56
57    config_name = registerPersistentConfig(context.getSite(), 'export')
58    if config_name is None:
59        transmogrifier._raw = _load_config(EXPORT_CONFIG)
60    else:
61        transmogrifier._raw = _load_config(config_name)
62        global CONFIGFILE
63        CONFIGFILE = None
64    transmogrifier._data = {}
65
66    options = transmogrifier._raw['transmogrifier']
67    sections = options['pipeline'].splitlines()
68    pipeline = constructPipeline(transmogrifier, sections)
69
70    last_section = pipeline.gi_frame.f_locals['self']
71
72    # if 'quintagroup.transmogrifier.writer' section's export context is
73    # tarball replace it with given function argument
74    while hasattr(last_section, 'previous'):
75        if isinstance(last_section, WriterSection) and \
76            isinstance(last_section.export_context, TarballExportContext):
77            last_section.export_context = context
78        last_section = last_section.previous
79        # end cycle if we get empty starter section
80        if type(last_section) == type(iter(())):
81            break
82        last_section = last_section.gi_frame.f_locals['self']
83
84    # Pipeline execution
85    for item in pipeline:
86        pass # discard once processed
87
88def importSiteStructure(context):
89
90    # Only run step if a flag file is present
91    if context.readDataFile('quintagroup.transmogrifier-import.txt') is None:
92        if getattr(context, '_archive', None) is None:
93            return
94
95    transmogrifier = ITransmogrifier(context.getSite())
96
97    # we don't use transmogrifer's __call__ method, because we need to do
98    # some modification in pipeline sections
99
100    config_name = registerPersistentConfig(context.getSite(), 'import')
101    if config_name is None:
102        transmogrifier._raw = _load_config(IMPORT_CONFIG)
103    else:
104        transmogrifier._raw = _load_config(config_name)
105        global CONFIGFILE
106        CONFIGFILE = None
107    transmogrifier._data = {}
108
109    # this function is also called when adding Plone site, so call standard handler
110    path = ''
111    prefix = 'structure'
112    if 'reader' in transmogrifier._raw:
113        path = transmogrifier._raw['reader'].get('path', '')
114        prefix = transmogrifier._raw['reader'].get('prefix', 'structure')
115    if not context.readDataFile('.objects.xml', subdir=os.path.join(path, prefix)):
116        try:
117            from Products.GenericSetup.interfaces import IFilesystemImporter
118            IFilesystemImporter(context.getSite()).import_(context, 'structure', True)
119        except ImportError:
120            pass
121        return
122
123    options = transmogrifier._raw['transmogrifier']
124    sections = options['pipeline'].splitlines()
125    pipeline = constructPipeline(transmogrifier, sections)
126
127    last_section = pipeline.gi_frame.f_locals['self']
128
129    # if 'quintagroup.transmogrifier.writer' section's export context is
130    # tarball replace it with given function argument
131    while hasattr(last_section, 'previous'):
132        if isinstance(last_section, ReaderSection) and \
133            isinstance(last_section.import_context, TarballImportContext):
134            last_section.import_context = context
135        last_section = last_section.previous
136        # end cycle if we get empty starter section
137        if type(last_section) == type(iter(())):
138            break
139        last_section = last_section.gi_frame.f_locals['self']
140
141    # Pipeline execution
142    for item in pipeline:
143        pass # discard once processed
144
145
146class PloneSiteImporter(object):
147    """ Importer of plone site.
148    """
149    implements(IFilesystemImporter)
150
151    def __init__(self, context):
152        self.context = context
153
154    def import_(self, import_context, subdir="structure", root=False):
155        # When performing import steps we need to use standart importing adapter,
156        # if 'object.xml' file is absent in 'structure' directory of the profile.
157        # This may be because it is the base plone profile or extension profile, that has
158        # structure part in other format.
159
160        objects_xml = import_context.readDataFile('.objects.xml', subdir)
161        if objects_xml is not None:
162            importSiteStructure(import_context)
163        else:
164            from Products.CMFCore.exportimport.content import StructureFolderWalkingAdapter
165            StructureFolderWalkingAdapter(self.context).import_(import_context, "structure", True)
Note: See TracBrowser for help on using the repository browser.