Author: jmorliaguet
Date: Sat Jun 24 01:22:23 2006
New Revision: 3507

Added:
   CPSSkins4Five/trunk/doc/migration.txt   (contents, props changed)
   CPSSkins4Five/trunk/migration.py   (contents, props changed)
   CPSSkins4Five/trunk/tests/
   CPSSkins4Five/trunk/tests/__init__.py   (contents, props changed)
   CPSSkins4Five/trunk/tests/setup-v2.tgz   (contents, props changed)
   CPSSkins4Five/trunk/tests/test_migration.py   (contents, props changed)

Log:

- moved the migration stuff here



Added: CPSSkins4Five/trunk/doc/migration.txt
==============================================================================
--- (empty file)
+++ CPSSkins4Five/trunk/doc/migration.txt       Sat Jun 24 01:22:23 2006
@@ -0,0 +1,29 @@
+
+=========================
+MIGRATION OF ZOPE 2 SITES
+=========================
+
+    >>> import os
+    >>> import Products.CPSSkins4Five.tests
+
+    >>> from Products.CPSSkins4Five.migration import Migration
+
+    >>> test_dir = os.path.dirname(Products.CPSSkins4Five.tests.__file__)
+    >>> file = open(os.path.join(test_dir, u'setup-v2.tgz'))
+
+    >>> from cpsskins.tests.setup import addThemeManager
+    >>> from cpsskins.tests.setup import makeSite
+
+    >>> root = getRootFolder()
+    >>> themes = addThemeManager(root, makeSite(root))
+
+    >>> migrator = Migrator(themes)
+    >>> migrator.migrate(file)
+
+    >>> themes.getThemes()
+    [Theme('CPS3 Default Theme')]
+
+    >>> themes.getPages(themes['default'])
+    [ThemePage('Front'), ThemePage('Default')]
+
+

Added: CPSSkins4Five/trunk/migration.py
==============================================================================
--- (empty file)
+++ CPSSkins4Five/trunk/migration.py    Sat Jun 24 01:22:23 2006
@@ -0,0 +1,199 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Nuxeo and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from xml.dom.minidom import parseString
+from zope.app.container.interfaces import INameChooser
+from zope.component import getUtility, createObject
+
+from cpsskins.elements.interfaces import IFormattable
+from cpsskins.setup.archives import TarArchive
+from cpsskins.setup.interfaces import IResourceManager
+from cpsskins.standard.fields.image import WebImage
+from cpsskins.thememanager import ThemeManagementFolder
+
+class Migrator(object):
+    """Migration utility for importing CPSSkins v2 themes
+    """
+    meta_types = {
+        'Portal Theme': 'cpsskins.canvas.theme',
+        'Theme Page': 'cpsskins.canvas.themepage',
+        'Page Block': 'cpsskins.canvas.pageblock',
+        'Portal Box Group Templet': 'cpsskins.canvas.slot',
+    }
+    children_types = {
+        'Portal Theme': ('Theme Page',),
+        'Theme Page': ('Page Block',),
+        'Page Block': ('',),
+    }
+
+    def __init__(self, themes):
+        self.themes = themes
+        self.resources = getUtility(IResourceManager)
+
+    def migrate(self, file):
+        self.archive = TarArchive(mode='r', data=file.read())
+        self.objects = {}
+        for theme_name in self.getThemeNames():
+            self.importTheme(theme_name)
+            self.importImages(theme_name)
+
+    def getThemeNames(self):
+        names = []
+        for item in self.archive['themes/']:
+            if item.endswith(u'.xml'):
+                continue
+            names.append(item[len('themes/'):-1])
+        return names
+
+    def importTheme(self, theme_name=u''):
+        themes = self.themes
+        archive = self.archive
+        path = 'themes/%s.xml' % theme_name
+
+        doc = parseString(archive[path])
+        theme_node = doc.childNodes[0]
+        theme_name = theme_node.getAttribute('name')
+        props = self.getProperties(theme_node, 'title', 'author', 'copyright',
+                                  'license')
+        theme = createObject('cpsskins.canvas.theme', **props)
+        self.themes.addTheme(theme, name=theme_name)
+
+        # first stage: import themes > pages > page blocks
+        self.importObject(theme_node, theme, 'themes/%s' % theme_name)
+
+        # second stage: create cells inside pageblocks
+        for pageblock_info in self.objects['Page Block']:
+            pageblock_node = pageblock_info['node']
+            pageblock_path = pageblock_info['path']
+            props = self.getProperties(pageblock_node, 'maxcols', 'width',
+                                       'height')
+            container = pageblock_info['object']
+            cells = {}
+
+            # set pageblock width
+            pageblock = pageblock_info['object']
+            IFormattable(pageblock).getFormat('layout').update({
+                'width': props['width'],
+                'height': props['height'],
+            })
+
+            # add cells
+            for c in range(int(props['maxcols'])):
+                cells[c] = self.addObject('cpsskins.canvas.cell', container)
+
+            # set cell size
+            for sizer_name in self.getObjects(pageblock_node, (u'Cell 
Sizer',)):
+                sizer_path = '%s/%s.xml' % (pageblock_path, sizer_name)
+                sizer_doc = parseString(archive[sizer_path])
+                sizer_node = sizer_doc.childNodes[0]
+                sizer_props = self.getProperties(sizer_node, 'cellwidth',
+                                                 'xpos')
+                xpos = int(sizer_props['xpos'])
+                # the sizer is outside the screen
+                if xpos >= len(cells):
+                    continue
+                cell = cells[xpos]
+                IFormattable(cell).getFormat('layout').update({
+                    'width': sizer_props['cellwidth'],
+                })
+
+            # add slots into cells
+            for slot_name in self.getObjects(pageblock_node,
+                                     (u'Portal Box Group Templet',)):
+                slot_path = '%s/%s.xml' % (pageblock_info['path'], slot_name)
+                slot_doc = parseString(archive[slot_path])
+                slot_node = slot_doc.childNodes[0]
+                slot_props = self.getProperties(slot_node, 'title', 
'box_group',
+                                                'xpos')
+                xpos = int(slot_props['xpos'])
+                slot_props['name'] = slot_props['box_group']
+                del slot_props['xpos']
+                del slot_props['box_group']
+                self.addObject('cpsskins.canvas.slot', cells[xpos], slot_props)
+
+
+    def addObject(self, type, container, props=None, name=u''):
+        if props is None:
+            props = {}
+        object = createObject(type, **props)
+        namechooser = INameChooser(container)
+        new_name = namechooser.chooseName(name, object)
+        container[new_name] = object
+        return object
+
+    def importObject(self, node, container, current_path):
+        archive = self.archive
+        meta_type = node.getAttribute('meta_type')
+        meta_types = self.meta_types
+        children_types = self.children_types[meta_type]
+        names = self.getObjects(node, children_types)
+
+        self.objects.setdefault(meta_type, []).append({
+            'path': current_path,
+            'object': container,
+            'node': node,
+        })
+
+        for name in names:
+            path = '%s/%s.xml' % (current_path, name)
+            child_doc = parseString(archive[path])
+            child_node = child_doc.childNodes[0]
+            child_type = child_node.getAttribute('meta_type')
+            props = self.getProperties(child_node, 'title')
+            object = self.addObject(meta_types[child_type], container, props)
+            self.importObject(child_node, object, current_path + '/' + name)
+
+    def importImages(self, theme_name):
+        resources = self.resources
+        archive = self.archive
+        themes = self.themes
+        for item in archive['themes/%s/icons/' % theme_name] + \
+                    archive['themes/%s/backgrounds/' % theme_name]:
+            image = WebImage(data=archive[item])
+            name = self.getFileName(item)
+            resources.register(name=theme_name, resource=image, context=themes)
+
+    ### utilities
+
+    def getProperties(self, node=None, *props):
+        info = {}
+        for property in node.getElementsByTagName('property'):
+            nodes = property.childNodes
+            name = property.getAttribute('name')
+            if name not in props:
+                continue
+            value = u''
+            if nodes:
+                value = nodes[0].nodeValue
+            info[str(name)] = value
+        return info
+
+    def getObjects(self, node=None, types=()):
+        objects = []
+        for obj in node.getElementsByTagName('object'):
+            meta_type = obj.getAttribute('meta_type')
+            if meta_type and meta_type not in types:
+                continue
+            name = obj.getAttribute('name')
+            objects.append(name)
+        return objects
+
+    def getFileName(self, path):
+        return path.split('/')[-1]
+

Added: CPSSkins4Five/trunk/tests/__init__.py
==============================================================================
--- (empty file)
+++ CPSSkins4Five/trunk/tests/__init__.py       Sat Jun 24 01:22:23 2006
@@ -0,0 +1,21 @@
+##############################################################################
+#
+# Copyright (c) 2006 Nuxeo and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+
+__docformat__ = "reStructuredText"
+
+

Added: CPSSkins4Five/trunk/tests/setup-v2.tgz
==============================================================================
Binary file. No diff available.

Added: CPSSkins4Five/trunk/tests/test_migration.py
==============================================================================
--- (empty file)
+++ CPSSkins4Five/trunk/tests/test_migration.py Sat Jun 24 01:22:23 2006
@@ -0,0 +1,29 @@
+##############################################################################
+#
+# Copyright (c) 2005-2006 Nuxeo and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Migration tests
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+from zope.app.testing.functional import FunctionalDocFileSuite
+
+def test_suite():
+    return unittest.TestSuite((
+        FunctionalDocFileSuite('../doc/migration.txt'),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
-- 
http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins

Reply via email to