Index: /quintagroup.transmogrify.simpleblog2quills/trunk/README.txt
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/README.txt (revision 1489)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/README.txt (revision 1490)
@@ -1,3 +1,3 @@
-quintagroup.transmogrifier.simpleblog2quills
+quintagroup.transmogrify.simpleblog2quills
============================================
@@ -26,5 +26,5 @@
problem with absolute links, because site URL isn't known. To make it possible
to fix absolute links please edit export configuration file 'export.cfg',
- which is located in 'quintagroup/transmogrifier/simpleblog2quills' folder.
+ which is located in 'quintagroup.transmogrify.simpleblog2quills' folder.
Find in that file line that starts with "site-urls = " and change values
that come after it to your site URL.
@@ -34,5 +34,5 @@
Quills_ or QuillsEnabled_ plone product is required. When migrating blog to
QuillsEnabled please edit import configuration file 'import.cfg' located in
- 'quintagroup/transmogrifier/simpleblog2quills' folder (comments in that file
+ 'quintagroup.transmogrify.simpleblog2quills' folder (comments in that file
will guide you through necessary modifications) and install this product in
QuickInstaller (this will enable 'Large Folder' content type and change
@@ -46,5 +46,5 @@
Run next command:
- bin/instance test -s quintagroup.transmogrifier.simpleblog2quills \
+ bin/instance test -s quintagroup.transmogrify.simpleblog2quills \
-m test_import
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/docs/HISTORY.txt
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/docs/HISTORY.txt (revision 1489)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/docs/HISTORY.txt (revision 1490)
@@ -1,7 +1,7 @@
-Changelog for quintagroup.transmogrifier.simpleblog2quills
+Changelog for quintagroup.transmogrify.simpleblog2quills
(name of developer listed in brackets)
-quintagroup.transmogrifier.simpleblog2quills - 0.1 Unreleased
+quintagroup.transmogrify.simpleblog2quills - 0.1 Unreleased
- Initial package structure.
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/docs/INSTALL.txt
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/docs/INSTALL.txt (revision 1489)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/docs/INSTALL.txt (revision 1490)
@@ -1,18 +1,18 @@
-quintagroup.transmogrifier.simpleblog2quills Installation
+quintagroup.transmogrify.simpleblog2quills Installation
==========================
-To install quintagroup.transmogrifier.simpleblog2quills into the global Python environment (or a workingenv),
+To install quintagroup.transmogrify.simpleblog2quills into the global Python environment (or a workingenv),
using a traditional Zope 2 instance, you can do this:
* When you're reading this you have probably already run
- ``easy_install quintagroup.transmogrifier.simpleblog2quills``. Find out how to install setuptools
+ ``easy_install quintagroup.transmogrify.simpleblog2quills``. Find out how to install setuptools
(and EasyInstall) here:
http://peak.telecommunity.com/DevCenter/EasyInstall
- * Create a file called ``quintagroup.transmogrifier.simpleblog2quills-configure.zcml`` in the
+ * Create a file called ``quintagroup.transmogrify.simpleblog2quills-configure.zcml`` in the
``/path/to/instance/etc/package-includes`` directory. The file
should only contain this::
-
+
@@ -20,5 +20,5 @@
recipe to manage your project, you can do this:
- * Add ``quintagroup.transmogrifier.simpleblog2quills`` to the list of eggs to install, e.g.:
+ * Add ``quintagroup.transmogrify.simpleblog2quills`` to the list of eggs to install, e.g.:
[buildout]
@@ -26,5 +26,5 @@
eggs =
...
- quintagroup.transmogrifier.simpleblog2quills
+ quintagroup.transmogrify.simpleblog2quills
* Tell the plone.recipe.zope2instance recipe to install a ZCML slug:
@@ -34,5 +34,5 @@
...
zcml =
- quintagroup.transmogrifier.simpleblog2quills
+ quintagroup.transmogrify.simpleblog2quills
* Re-run buildout, e.g. with:
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/docs/LICENSE.txt
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/docs/LICENSE.txt (revision 1489)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/docs/LICENSE.txt (revision 1490)
@@ -1,3 +1,3 @@
- quintagroup.transmogrifier.simpleblog2quills is copyright Quintagroup
+ quintagroup.transmogrify.simpleblog2quills is copyright Quintagroup
This program is free software; you can redistribute it and/or modify
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/__init__.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/__init__.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/__init__.py (revision 1490)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/__init__.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/__init__.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/__init__.py (revision 1490)
@@ -0,0 +1,21 @@
+# register our extension profile if we have GenericSetup (Plone 2.5 or later)
+try:
+ # if we have GenericSetup product we don't need to register steps in python
+ import os
+ from Products.GenericSetup import EXTENSION
+ from Products.GenericSetup import profile_registry
+ from Products.CMFPlone.interfaces import IPloneSiteRoot
+
+ profile_path = os.path.join(os.path.split(__file__)[0], 'profiles/default')
+ profile_registry.registerProfile(
+ name="default",
+ title="quintagroup.transmogrify.simpleblog2quills (enables Large Plone Folder)",
+ description="Extension profile for applying settings needed to migrate blog.",
+ path=profile_path,
+ product="quintagroup.transmogrify.simpleblog2quills", # this is required
+ profile_type=EXTENSION,
+ for_=IPloneSiteRoot
+ )
+
+except ImportError:
+ pass
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/activator.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/activator.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/activator.py (revision 1490)
@@ -0,0 +1,80 @@
+from zope.interface import classProvides, implements
+from zope import event
+
+from collective.transmogrifier.interfaces import ISectionBlueprint
+from collective.transmogrifier.interfaces import ISection
+from collective.transmogrifier.utils import defaultMatcher
+
+from Products.CMFCore import utils
+from Products.CMFCore.WorkflowCore import WorkflowException
+
+try:
+ from zope.interface import alsoProvides
+ from quills.core.interfaces.enabled import IWeblogEnhanced, IPossibleWeblog
+ from Products.QuillsEnabled.activation import WeblogActivationEvent
+except ImportError:
+ # this try: ... except: ... clause is needed for this package to work on
+ # plone 2.1, because zcml:condition attribute in zcml doesn't work
+ pass
+
+from quintagroup.transmogrify.simpleblog2quills.adapters import IMAGE_FOLDER
+
+class BlogActivatorSection(object):
+ classProvides(ISectionBlueprint)
+ implements(ISection)
+
+ def __init__(self, transmogrifier, name, options, previous):
+ self.transmogrifier = transmogrifier
+ self.context = transmogrifier.context
+ self.wftool = utils.getToolByName(self.context, 'portal_workflow')
+
+ self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
+ self.flagkey = options.get('flag-key', '_old_type').strip()
+ self.previous = previous
+
+ def __iter__(self):
+ for item in self.previous:
+ pathkey = self.pathkey(*item.keys())[0]
+
+ if not pathkey:
+ yield item; continue
+
+ type_ = item.get(self.flagkey, None)
+ newtype = item.get('_type', None)
+ if type_ != 'Blog' and newtype != 'Large Plone Folder':
+ yield item; continue
+
+ path = item[pathkey]
+ if type_ is None and newtype == 'Large Plone Folder':
+ parts = path.rsplit('/', 1)
+ if len(parts) == 2:
+ parent, id_ = parts
+ else:
+ yield item; continue
+ if id_ != IMAGE_FOLDER:
+ yield item; continue
+
+ obj = self.context.unrestrictedTraverse(path, None)
+ if obj is None: # path doesn't exist
+ yield item; continue
+
+ if type_ == 'Blog' and newtype == 'Large Plone Folder':
+ # mark as blog
+ if not IWeblogEnhanced.providedBy(obj) and \
+ IPossibleWeblog.providedBy(obj):
+ alsoProvides(obj, IWeblogEnhanced)
+ event.notify(WeblogActivationEvent(obj))
+ elif type_ is None and newtype == 'Large Plone Folder':
+ # pulish 'images' subfolder
+ parent = self.context.unrestrictedTraverse(parent, None)
+ if IWeblogEnhanced.providedBy(parent) :
+ try:
+ self.wftool.doActionFor(obj, 'publish')
+ except WorkflowException:
+ pass
+
+ yield item
+
+ # reindex provided interfaces
+ catalog = utils.getToolByName(self.context, 'portal_catalog')
+ catalog.reindexIndex('object_provides', None)
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/adapters.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/adapters.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/adapters.py (revision 1490)
@@ -0,0 +1,377 @@
+import re
+from xml.dom import minidom
+from types import ListType
+from types import TupleType
+
+from zope.interface import implements, classProvides
+from zope.app.annotation.interfaces import IAnnotations
+
+from Products.CMFPlone.Portal import PloneSite
+from Products.CMFCore import utils
+
+from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
+from collective.transmogrifier.utils import defaultMatcher
+
+from quintagroup.transmogrifier.interfaces import IExportDataCorrector, IImportDataCorrector
+from quintagroup.transmogrifier.adapters.exporting import ReferenceExporter
+from quintagroup.transmogrifier.manifest import ManifestExporterSection
+from quintagroup.transmogrifier.logger import VALIDATIONKEY
+
+from quintagroup.transmogrify.simpleblog2quills.interfaces import IExportItemManipulator, IBlog
+
+# URL of the site, where blog is located (this is needed to fix links in entries)
+SITE_URLS = []
+IMAGE_FOLDER = 'images'
+IMAGE_FOLDER_TYPE = 'Large Plone Folder'
+# this registries are needed to avoid loosing images with equal ids
+IMAGE_IDS = []
+IMAGE_PATHS = {}
+
+class BlogManifest(object):
+ implements(IExportDataCorrector)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, data):
+ # flag that indicated whether 'images' folder must added to manifest
+ need_to_add = True
+
+ doc = minidom.parseString(data['data'])
+ root = doc.documentElement
+ for child in root.getElementsByTagName('record'):
+ if child.getAttribute('type') not in ('BlogEntry', 'BlogFolder'):
+ root.removeChild(child)
+ elif str(child.firstChild.nodeValue.strip()) == IMAGE_FOLDER:
+ # blog already contains object with IMAGE_FOLDER id
+ need_to_add = False
+
+ if need_to_add:
+ folder = doc.createElement('record')
+ folder.setAttribute('type', IMAGE_FOLDER_TYPE)
+ folder.appendChild(doc.createTextNode(IMAGE_FOLDER))
+ root.appendChild(folder)
+
+ data['data'] = doc.toxml('utf-8')
+ return data
+
+class BlogFolderManifest(object):
+ implements(IExportDataCorrector)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, data):
+ doc = minidom.parseString(data['data'])
+ root = doc.documentElement
+ for child in root.getElementsByTagName('record'):
+ if child.getAttribute('type') not in ('BlogEntry', 'BlogFolder'):
+ root.removeChild(child)
+ data['data'] = doc.toxml('utf-8')
+ return data
+
+class BlogEntryManifest(object):
+ implements(IExportItemManipulator)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, item, **kw):
+ # remove manifest data from item - content contained in BlogEntry isn't exported
+ if '_files' in item and 'manifest' in item['_files']:
+ del item['_files']['manifest']
+ return item
+
+def recurseToInterface(item, ifaces):
+ """Recurse up the aq_chain until an object providing `iface' is found,
+ and return that.
+ """
+ if not isinstance(ifaces, (ListType, TupleType)):
+ ifaces = [ifaces]
+ parent = item.aq_parent
+ for iface in ifaces:
+ if iface.providedBy(item):
+ return item
+ for iface in ifaces:
+ if iface.providedBy(parent):
+ return parent
+ if isinstance(parent, PloneSite):
+ # Stop when we get to the portal root.
+ return None
+ return recurseToInterface(parent, ifaces)
+
+def getUniqueId(image_id):
+ """ Generate id that is unique in IMAGE_IDS registry.
+ """
+ if '.' in image_id:
+ name, ext = image_id.rsplit('.', 1)
+ ext = '.' + ext
+ else:
+ name, ext = image_id, ''
+ if image_id in IMAGE_IDS:
+ c = 1
+ new_id = name + str(c) + ext
+ while new_id in IMAGE_IDS:
+ c += 1
+ new_id = name + str(c) + ext
+ image_id = new_id
+
+ return image_id
+
+class BlogEntryExporter(ReferenceExporter):
+ implements(IExportDataCorrector)
+
+ SRC = re.compile(r'src="([^"]+)"')
+
+ def __init__(self, context):
+ self.context = context
+ self.portal_url = utils.getToolByName(self.context, 'portal_url')
+ self.portal = self.portal_url.getPortalObject()
+
+ def __call__(self, data):
+ data = super(BlogEntryExporter, self).__call__(data)
+ doc = minidom.parseString(data['data'])
+ try:
+ elem = [i for i in doc.getElementsByTagName('field') if i.getAttribute('name') == 'body'][0]
+ except IndexError:
+ return data
+
+ text = elem.firstChild.nodeValue
+ urls = self.SRC.findall(text)
+ blog = recurseToInterface(self.context, IBlog)
+ blog_path = blog.getPhysicalPath()
+ context_path = self.context.getPhysicalPath()
+ for url in urls:
+ url = str(url)
+ image_id = url.rsplit('/', 1)[-1]
+ # skip links with illegal url schema
+ if '://' in url and not url.startswith('http://'):
+ continue
+ # convert all all links to relative
+ if url.startswith('http://'):
+ for site in SITE_URLS:
+ if url.startswith(site):
+ # check whether image is stored in blog
+ relative_url = url[len(site):]
+ relative_url = relative_url.strip('/')
+ # if link is broken we'll get an AttributeError
+ try:
+ image = self.portal.unrestrictedTraverse(relative_url)
+ except AttributeError:
+ break
+ in_blog = recurseToInterface(image, IBlog) is not None and True or False
+ if in_blog:
+ image_id = self.fixImageId(image, image_id, blog_path)
+ level = len(context_path) - len(blog_path) - 1
+ new_url = '/'.join(['..' for i in range(level)])
+ new_url = '/'.join((new_url, IMAGE_FOLDER, image_id))
+ text = text.replace(url, new_url, 1)
+ else:
+ # find how many levels self.context is under portal root
+ level = len(context_path) - 3
+ new_url = '/'.join(['..' for i in range(level)])
+ new_url = new_url + '/' + relative_url
+ text = text.replace(url, new_url, 1)
+ break
+ else:
+ if url.startswith('/'):
+ # if link is broken we'll get an AttributeError
+ try:
+ image = self.portal.unrestrictedTraverse(url.strip('/'))
+ except AttributeError:
+ continue
+ else:
+ # if link is broken we'll get an AttributeError
+ try:
+ image = self.context.unrestrictedTraverse(url)
+ except AttributeError:
+ continue
+ in_blog = recurseToInterface(image, IBlog) is not None and True or False
+ if in_blog:
+ image_id = self.fixImageId(image, image_id, blog_path)
+ level = len(context_path) - len(blog_path) - 1
+ new_url = '/'.join(['..' for i in range(level)])
+ new_url = '/'.join([new_url, IMAGE_FOLDER, image_id])
+ text = text.replace(url, new_url, 1)
+ elif url.startswith('../'):
+ # remove '../' from the start of string
+ new_url = url[3:]
+ text = text.replace(url, new_url, 1)
+ elif url.startswith('/'):
+ # these links didn't work so rewrite them with '..'
+ # find how many levels self.context is under portal root
+ level = len(context_path) - 3
+ new_url = '/'.join(['..' for i in range(level)])
+ new_url = new_url + url
+ text = text.replace(url, new_url, 1)
+
+ elem.firstChild.nodeValue = text
+ data['data'] = doc.toxml('utf-8')
+ return data
+
+ def fixImageId(self, image, image_id, blog_path):
+ """ Check whether image is good or generate new if it's bad.
+ """
+ image_path = '/'.join(image.getPhysicalPath())
+ if image_id in IMAGE_IDS and image_path not in IMAGE_PATHS:
+ image_id = getUniqueId(image_id)
+ if image_id not in IMAGE_IDS:
+ IMAGE_IDS.append(image_id)
+ IMAGE_PATHS[image_path] = '/'.join(blog_path[2:] + (IMAGE_FOLDER, image_id))
+
+ return image_id
+
+class PathRewriter(object):
+ implements(IExportItemManipulator)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, item, **kw):
+ pathkey = kw.get('path')
+ if pathkey is None:
+ return item
+
+ path = item[pathkey]
+ blog = recurseToInterface(self.context, IBlog)
+ if blog is None:
+ return item
+
+ blog_path = blog.getPhysicalPath()
+ full_path = '/'.join(self.context.getPhysicalPath())
+ image_id = path.rsplit('/', 1)[-1]
+ modified = False
+
+ if full_path in IMAGE_PATHS:
+ new_path = IMAGE_PATHS[full_path]
+ else:
+ unique_id = getUniqueId(image_id)
+ modified = image_id != unique_id
+ new_path = '/'.join(blog_path[2:] + (IMAGE_FOLDER, unique_id))
+
+ IMAGE_IDS.append(image_id)
+ IMAGE_PATHS[full_path] = new_path
+
+ # change item's path
+ item[pathkey] = new_path
+ item['_oldpath'] = path
+
+ # now we need to fix object id in .marshall.xml
+ if modified:
+ if '_files' in item and 'marshall' in item['_files']:
+ doc = minidom.parseString(item['_files']['marshall']['data'])
+ elem = [i for i in doc.getElementsByTagName('field') if i.getAttribute('name') == 'id'][0]
+ elem.firstChild.nodeValue = '\n\t\t%s\n\t' % unique_id
+ item['_files']['marshall']['data'] = doc.toxml('utf-8')
+
+ return item
+
+class ImageFolderSection(object):
+ """ This section will generate manifest files for image folders in blog.
+ """
+ classProvides(ISectionBlueprint)
+ implements(ISection)
+
+ def __init__(self, transmogrifier, name, options, previous):
+ self.previous = previous
+ self.transmogrifier = transmogrifier
+
+ self.flagkey = defaultMatcher(options, 'old-path-key', name, 'oldpath')
+ self.typekey = defaultMatcher(options, 'type-key', name, 'type')
+ self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
+
+
+ site_urls = options.get('site-urls', '')
+ site_urls = filter(None, [i.strip() for i in site_urls.splitlines()])
+ for i in site_urls:
+ SITE_URLS.append(i)
+
+ self.anno = IAnnotations(transmogrifier)
+
+ def __iter__(self):
+ folders = {}
+
+ # safely get logging storage
+ if VALIDATIONKEY in self.anno:
+ log_storage = self.anno[VALIDATIONKEY]
+ else:
+ log_storage = None
+
+ for item in self.previous:
+ item_keys = item.keys()
+ pathkey = self.pathkey(*item_keys)[0]
+ typekey = self.typekey(*item_keys)[0]
+ oldpathkey = self.flagkey(*item_keys)[0]
+
+ # collect data about images moved to folders
+ if pathkey and typekey and oldpathkey:
+ path = item[pathkey]
+ old_path = item[oldpathkey]
+ type_ = item[typekey]
+ folder_path, image_id = path.rsplit('/', 1)
+ folders.setdefault(folder_path, []).append((image_id, type_))
+
+ # update logging data (path) for this item
+ if log_storage and log_storage[-1] == old_path:
+ log_storage.pop()
+ log_storage.append(path)
+
+ yield item
+
+ # generate manifests for those image folders
+ items = []
+ for folder, entries in folders.items():
+ items.append({'_entries': entries, pathkey: folder})
+ exporter = ManifestExporterSection(self.transmogrifier, 'manifest', {'blueprint': 'manifest'}, iter(items))
+ for item in exporter:
+ yield item
+
+ # clean registries
+ while IMAGE_IDS: IMAGE_IDS.pop()
+ while SITE_URLS: SITE_URLS.pop()
+ IMAGE_PATHS.clear()
+
+class WorkflowImporter(object):
+ """ This adapter tries to convert all possible workflow histories to
+ simple_publication_workflow history.
+ """
+ implements(IImportDataCorrector)
+
+ def __init__(self, context):
+ self.context = context
+
+ def __call__(self, data):
+ doc = minidom.parseString(data['data'])
+ wh = [i for i in doc.getElementsByTagName('cmf:workflow')]
+ if not wh:
+ # we don't have such workflow history
+ return data
+
+ wh = wh[0]
+ workflow_id = wh.getAttribute('id')
+ if workflow_id == 'simple_publication_workflow':
+ return data
+ wh.setAttribute('id', 'simple_publication_workflow')
+ if workflow_id == 'simpleblog_workflow':
+ self.fixSimpleBlogWorkflow(wh)
+ else:
+ self.fixWorkflow(wh)
+
+ data['data'] = doc.toxml('utf-8')
+ return data
+
+ def fixSimpleBlogWorkflow(self, wh):
+ for history in wh.getElementsByTagName('cmf:history'):
+ for var in history.getElementsByTagName('cmf:var'):
+ id_ = var.getAttribute('id')
+ value = var.getAttribute('value')
+ if id_ == 'review_state' and value == 'draft':
+ var.setAttribute('value', 'private')
+
+ def fixWorkflow(self, wh):
+ for history in wh.getElementsByTagName('cmf:history'):
+ for var in history.getElementsByTagName('cmf:var'):
+ id_ = var.getAttribute('id')
+ value = var.getAttribute('value')
+ if id_ == 'review_state' and value == 'visible':
+ var.setAttribute('value', 'published')
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-folder.xsl
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-folder.xsl (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-folder.xsl (revision 1490)
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Folder
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-largefolder.xsl
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-largefolder.xsl (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-largefolder.xsl (revision 1490)
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Large Plone Folder
+
+
+
+
+
+
+ simple_publication_workflow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ review_state
+ str
+ published
+
+
+
+
+
+
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-weblog.xsl
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-weblog.xsl (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blog-weblog.xsl (revision 1490)
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Weblog
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-document.xsl
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-document.xsl (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-document.xsl (revision 1490)
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
+ simple_publication_workflow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ review_state
+ str
+ private
+
+
+
+
+
+
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-weblogentry.xsl
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-weblogentry.xsl (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogentry-weblogentry.xsl (revision 1490)
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ WeblogEntry
+
+
+
+
+
+
+ plone_workflow
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-folder.xsl
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-folder.xsl (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-folder.xsl (revision 1490)
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Folder
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-largefolder.xsl
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-largefolder.xsl (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/blogfolder-largefolder.xsl (revision 1490)
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Large Plone Folder
+
+
+
+
+
+
+ simple_publication_workflow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ review_state
+ str
+ published
+
+
+
+
+
+
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/configure.zcml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/configure.zcml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/configure.zcml (revision 1490)
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/export.cfg
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/export.cfg (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/export.cfg (revision 1490)
@@ -0,0 +1,65 @@
+[transmogrifier]
+pipeline =
+ sitewalker
+ condition
+ manifestexporter
+ fileexporter
+ marshaller
+ propertiesexporter
+ commentsexporter
+ datacorrector
+ itemmanipulator
+ imagefolder
+ writer
+ EXPORTING
+
+[sitewalker]
+blueprint = quintagroup.transmogrifier.sitewalker
+excluded-types =
+ ATAudio
+ TrackBack
+
+[condition]
+blueprint = collective.transmogrifier.sections.condition
+condition = python:not bool([i for i in ('Members', 'news', 'events') if item['_path'].startswith(i)])
+
+[manifestexporter]
+blueprint = quintagroup.transmogrifier.manifestexporter
+
+[fileexporter]
+blueprint = quintagroup.transmogrifier.fileexporter
+
+[marshaller]
+blueprint = quintagroup.transmogrifier.marshaller
+
+[propertiesexporter]
+blueprint = quintagroup.transmogrifier.propertiesexporter
+exclude = title
+
+[commentsexporter]
+blueprint = quintagroup.transmogrifier.commentsexporter
+
+[datacorrector]
+blueprint = quintagroup.transmogrifier.datacorrector
+sources =
+ manifest
+ marshall
+
+[itemmanipulator]
+blueprint = quintagroup.transmogrifier.itemmanipulator
+type = export
+
+# in this section you must write you site URL
+[imagefolder]
+blueprint = quintagroup.transmogrify.simpleblog2quills.imagefolder
+site-urls =
+
+[writer]
+blueprint = quintagroup.transmogrifier.writer
+prefix = structure
+
+[EXPORTING]
+blueprint = quintagroup.transmogrifier.logger
+keys =
+ _type
+ _path
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/import.cfg
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/import.cfg (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/import.cfg (revision 1490)
@@ -0,0 +1,44 @@
+[transmogrifier]
+pipeline =
+ reader
+ manifestimporter
+ substitution
+ constructor
+ xslt
+ datacorrector
+ fileimporter
+ demarshaller
+ referencesimporter
+ propertiesimporter
+ commentsimporter
+ activator
+ IMPORTING
+include = quintagroup.transmogrifier:import.cfg
+
+# don't yield items that are in manifest, but don't exists in import context
+[manifestimporter]
+enable-source-behaviour = false
+
+# this section depends on what blogging product you use - Quills or QuillsEnabled
+[substitution]
+blueprint = quintagroup.transmogrifier.substitution
+key = _type
+
+# next options is for Quills (comment them if you are using QuillsEnabled)
+# Blog = Weblog
+# BlogFolder = Folder
+# BlogEntry = WeblogEntry
+
+# next is for QuillsEnabled (uncomment them if you are using QuillsEnabled)
+Blog = Large Plone Folder
+BlogFolder = Large Plone Folder
+BlogEntry = Document
+
+[xslt]
+blueprint = quintagroup.transmogrifier.xslt
+source = marshall
+from-key = _old_type
+to-key = _type
+
+[activator]
+blueprint = quintagroup.transmogrify.simpleblog2quills.activator
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/interfaces.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/interfaces.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/interfaces.py (revision 1490)
@@ -0,0 +1,37 @@
+from zope.interface import Interface
+
+class IBlog(Interface):
+ """ Marker interface for SimpleBlog blog object.
+ """
+
+class IBlogFolder(Interface):
+ """ Marker interface for SimpleBlog blog folder object.
+ """
+
+class IBlogEntry(Interface):
+ """ Marker interface for SimpleBlog blog entry object.
+ """
+
+class IItemManipulator(Interface):
+ """ Interface for adapters that are looked up in 'itemmanipulator'
+ pipeline section.
+ """
+
+ def __call__(item, **kw):
+ """ Do something with a pipeline item and return it.
+ kw - dictionary with extra arguments, for example some useful keys
+ in item (pathkey, ...)
+ """
+
+class IExportItemManipulator(IItemManipulator):
+ """ Exporting adapter.
+ """
+
+class IImportItemManipulator(IItemManipulator):
+ """ Importing adapter
+ """
+
+try:
+ from Products.Archetypes.interfaces import IBaseObject
+except ImportError:
+ from plone.app.transmogrifier.interfaces import IBaseObject
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/itemmanipulator.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/itemmanipulator.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/itemmanipulator.py (revision 1490)
@@ -0,0 +1,47 @@
+from zope.interface import classProvides, implements
+from zope.component import queryAdapter
+
+from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
+from collective.transmogrifier.utils import defaultMatcher
+
+from quintagroup.transmogrify.simpleblog2quills.interfaces import \
+ IItemManipulator, IExportItemManipulator, IImportItemManipulator
+
+class ItemManipulatorSection(object):
+ classProvides(ISectionBlueprint)
+ implements(ISection)
+
+ def __init__(self, transmogrifier, name, options, previous):
+ self.previous = previous
+ self.context = transmogrifier.context
+
+ self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
+
+ # 'type' options specifies adapter interface
+ type_ = options.get('type', 'general')
+ if type_ == 'general':
+ self.interface = IItemManipulator
+ elif type_ == 'export':
+ self.interface = IExportItemManipulator
+ elif type_ == 'import':
+ self.interface = IImportItemManipulator
+ else:
+ self.interface = None
+
+ def __iter__(self):
+ for item in self.previous:
+ pathkey = self.pathkey(*item.keys())[0]
+
+ if not (pathkey and self.interface is not None):
+ yield item; continue
+
+ path = item[pathkey]
+ obj = self.context.unrestrictedTraverse(path, None)
+ if obj is None: # path doesn't exist
+ yield item; continue
+
+ adapter = queryAdapter(obj, self.interface, name='')
+ if adapter:
+ item = adapter(item, path=pathkey)
+
+ yield item
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/overrides.zcml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/overrides.zcml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/overrides.zcml (revision 1490)
@@ -0,0 +1,12 @@
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/metadata.xml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/metadata.xml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/metadata.xml (revision 1490)
@@ -0,0 +1,4 @@
+
+
+ 0.1
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/types/Large_Plone_Folder.xml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/types/Large_Plone_Folder.xml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/profiles/default/types/Large_Plone_Folder.xml (revision 1490)
@@ -0,0 +1,6 @@
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/__init__.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/__init__.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/__init__.py (revision 1490)
@@ -0,0 +1,1 @@
+# i'm a package
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/base.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/base.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/base.py (revision 1490)
@@ -0,0 +1,43 @@
+import os.path
+
+from zope.interface import classProvides, implements
+
+from collective.transmogrifier.interfaces import ISectionBlueprint, ISection
+
+class Source(object):
+ classProvides(ISectionBlueprint)
+ implements(ISection)
+
+ def __init__(self, transmogrifier, name, options, previous):
+ self.previous = previous
+ self.source = options.get('source', '').strip()
+ self.allow_empty = options.get('allow-empty-items', '').strip() == 'yes' and True or False
+ items_source = options.get('items', '').strip()
+ self.items = []
+ for line in items_source.splitlines():
+ self.items.append([i.strip() for i in line.split(';')])
+
+ def __iter__(self):
+ for item in self.previous:
+ yield item
+
+ for path, type_, fname in self.items:
+ if not fname.startswith('/'):
+ fname = os.path.join(os.path.dirname(__file__), fname)
+ try:
+ fp = file(fname)
+ data = fp.read()
+ fp.close()
+ except IOError, e:
+ if self.allow_empty:
+ yield dict(_type=type_, _path=path)
+ continue
+
+ item = dict(
+ _type=type_,
+ _path=path,
+ _files={
+ self.source: {'data': data}
+ }
+ )
+ yield item
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/blog.xml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/blog.xml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/blog.xml (revision 1490)
@@ -0,0 +1,41 @@
+
+
+ Test Blog
+
+
+ This is test blog.
+
+
+ 2005-08-29T11:32:01Z
+
+
+ 2006-04-26T11:04:31Z
+
+
+ blog
+
+
+ descriptionOnly
+
+
+ 15
+
+
+ Zope
+
+
+ Plone
+
+
+ Python
+
+
+ Testing
+
+
+ True
+
+
+ Blog
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/folder.xml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/folder.xml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/folder.xml (revision 1490)
@@ -0,0 +1,20 @@
+
+
+ Blog folder
+
+
+ Folder in blog.
+
+
+ 2005-11-04T11:31:06Z
+
+
+ folder
+
+
+ <ul><li>Zope</li><li>Plone</li>
+
+
+ BlogFolder
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/root_entry.xml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/root_entry.xml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/root_entry.xml (revision 1490)
@@ -0,0 +1,47 @@
+
+
+ Root entry
+
+
+ This entry was created in root of blog.
+
+
+ 2007-11-14T10:32:11Z
+
+
+ root-entry
+
+
+ <p>We are testing importing of blog entry.</p>
+
+
+ Plone
+
+
+ Zope
+
+
+ BlogEntry
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/source.txt
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/source.txt (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/source.txt (revision 1490)
@@ -0,0 +1,53 @@
+Test source section
+===================
+
+>>> source = """
+... [transmogrifier]
+... pipeline =
+... source
+... printer
+...
+... [source]
+... blueprint = quintagroup.transmogrify.simpleblog2quills.tests.source
+... source = marshall
+... items =
+... not-existing; Document; not-existing-path
+... not-existing; File; /not/existing/absolute/path
+... plone-blog; Blog; blog.xml
+...
+... [printer]
+... blueprint = collective.transmogrifier.sections.tests.pprinter
+... """
+>>> registerConfig(u'quintagroup.transmogrify.simpleblog2quills.tests.source', source)
+>>> transmogrifier(u'quintagroup.transmogrify.simpleblog2quills.tests.source') # doctest: +ELLIPSIS, +REPORT_NDIFF
+{'_files': {'marshall': {'data': ...}},
+ '_path': 'plone-blog',
+ '_type': 'Blog'}
+
+Now we are testing ``allow-empty-items`` option:
+
+>>> source = """
+... [transmogrifier]
+... pipeline =
+... source
+... printer
+...
+... [source]
+... blueprint = quintagroup.transmogrify.simpleblog2quills.tests.source
+... allow-empty-items = yes
+... source = marshall
+... items =
+... not-existing; Document; not-existing-path
+... not-existing; File; /not/existing/absolute/path
+... plone-blog; Blog; blog.xml
+...
+... [printer]
+... blueprint = collective.transmogrifier.sections.tests.pprinter
+... """
+>>> registerConfig(u'quintagroup.transmogrify.simpleblog2quills.tests.source-with-empties', source)
+>>> transmogrifier(u'quintagroup.transmogrify.simpleblog2quills.tests.source-with-empties') # doctest: +ELLIPSIS, +REPORT_NDIFF
+{'_type': 'Document', '_path': 'not-existing'}
+{'_type': 'File', '_path': 'not-existing'}
+{'_files': {'marshall': {'data': ...}},
+ '_path': 'plone-blog',
+ '_type': 'Blog'}
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_base.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_base.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_base.py (revision 1490)
@@ -0,0 +1,23 @@
+import unittest
+
+from zope.testing import doctest, cleanup
+
+from Products.Five import zcml
+
+from collective.transmogrifier.tests import tearDown
+from quintagroup.transmogrifier.tests import sectionsSetUp
+
+import quintagroup.transmogrify.simpleblog2quills.tests
+
+def sourceSetUp(test):
+ sectionsSetUp(test)
+ zcml.load_config('test_import.zcml', quintagroup.transmogrify.simpleblog2quills.tests)
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTests((
+ doctest.DocFileSuite(
+ 'source.txt',
+ setUp=sourceSetUp, tearDown=tearDown),
+ ))
+ return suite
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.cfg
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.cfg (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.cfg (revision 1490)
@@ -0,0 +1,34 @@
+[transmogrifier]
+pipeline =
+ source
+ substitution
+ constructor
+ xslt
+ datacorrector
+ demarshaller
+ referencesimporter
+include = quintagroup.transmogrifier:import.cfg
+
+[source]
+blueprint = quintagroup.transmogrify.simpleblog2quills.tests.source
+source = marshall
+allow-empty-items = yes
+items =
+# path; type; file
+ blog; Blog; blog.xml
+ blog/root-entry; BlogEntry; root_entry.xml
+ blog/folder; BlogFolder; folder.xml
+ blog/folder/folder-entry; BlogEntry; folder_entry.xml
+
+[substitution]
+blueprint = quintagroup.transmogrifier.substitution
+key = _type
+Blog = Weblog
+BlogEntry = WeblogEntry
+BlogFolder = Folder
+
+[xslt]
+blueprint = quintagroup.transmogrifier.xslt
+source = marshall
+from-key = _old_type
+to-key = _type
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.py (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.py (revision 1490)
@@ -0,0 +1,87 @@
+import unittest
+import os.path
+
+import transaction
+
+from Products.Five import zcml
+from Products.Five import fiveconfigure
+from Testing import ZopeTestCase as ztc
+
+from Products.PloneTestCase import PloneTestCase as ptc
+from Products.PloneTestCase.layer import onsetup
+
+from collective.transmogrifier.interfaces import ITransmogrifier
+
+ztc.installProduct('Quills')
+ztc.installProduct('fatsyndication')
+
+@onsetup
+def setup_product():
+ fiveconfigure.debug_mode = True
+ import Products.Five
+ zcml.load_config('configure.zcml', Products.Five)
+ import quintagroup.transmogrify.simpleblog2quills
+ zcml.load_config('configure.zcml', quintagroup.transmogrify.simpleblog2quills)
+ import quintagroup.transmogrify.simpleblog2quills.tests
+ zcml.load_config('test_import.zcml', quintagroup.transmogrify.simpleblog2quills.tests)
+ # this is needed because 'importStep' unknown directive error is raised somewhere
+ import Products.GenericSetup
+ zcml.load_config('meta.zcml', Products.GenericSetup)
+ import Products.Quills
+ zcml.load_config('configure.zcml', Products.Quills)
+ fiveconfigure.debug_mode = False
+
+setup_product()
+ptc.setupPloneSite(products=['Quills'])
+
+class TestImport(ptc.PloneTestCase):
+ """ Test importing of PloneFormGen content.
+ """
+
+ def afterSetUp(self):
+ self.addProduct('Quills')
+ if 'blog' not in self.portal:
+ # run transmogrifier pipeline
+ transmogrifier = ITransmogrifier(self.portal)
+ transmogrifier('test_import')
+
+ def beforeTearDown(self):
+ transaction.commit()
+
+ def test_site_structure(self):
+ self.failIf('blog' not in self.portal)
+ self.failIf('root-entry' not in self.portal.blog)
+ self.failIf('folder' not in self.portal.blog)
+ self.failIf('folder-entry' not in self.portal.blog.folder)
+
+ def test_blog(self):
+ blog = self.portal['blog']
+
+ self.assertEqual(blog.getPortalTypeName(), 'Weblog')
+ self.assertEqual(blog['title'], 'Test Blog')
+ self.assertEqual(blog.Description(), 'This is test blog.')
+
+ def test_blog_entry(self):
+ entry = self.portal['blog']['root-entry']
+
+ self.assertEqual(entry.getPortalTypeName(), 'WeblogEntry')
+ self.assertEqual(entry['title'], 'Root entry')
+ self.assertEqual(entry.Description(), 'This entry was created in root of blog.')
+ self.assertEqual(entry.getText(), '
We are testing importing of blog entry.
')
+ self.assertEqual(entry.Subject(), ('Plone', 'Zope'))
+ self.assertEqual(entry.modified().HTML4(), '2007-11-14T10:32:11Z')
+ # now workflow of WeblogEntry is assumed to be 'plone_workflow'
+ # but it must be configured in type configuration
+ self.failIf('plone_workflow' not in entry.workflow_history)
+
+ def test_blog_folder(self):
+ folder = self.portal['blog']['folder']
+
+ self.assertEqual(folder.getPortalTypeName(), 'Folder')
+ self.assertEqual(folder['title'], 'Blog folder')
+ self.assertEqual(folder.Description(), 'Folder in blog.')
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TestImport))
+ return suite
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.zcml
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.zcml (revision 1490)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/quintagroup/transmogrify/simpleblog2quills/tests/test_import.zcml (revision 1490)
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
Index: /quintagroup.transmogrify.simpleblog2quills/trunk/setup.py
===================================================================
--- /quintagroup.transmogrify.simpleblog2quills/trunk/setup.py (revision 1489)
+++ /quintagroup.transmogrify.simpleblog2quills/trunk/setup.py (revision 1490)
@@ -4,5 +4,5 @@
version = '0.1'
-setup(name='quintagroup.transmogrifier.simpleblog2quills',
+setup(name='quintagroup.transmogrify.simpleblog2quills',
version=version,
description="Configuration of collective.transmogrifier pipeline for migrating SimpleBlog content to Quills content",
@@ -20,5 +20,5 @@
license='GPL',
packages=find_packages(exclude=['ez_setup']),
- namespace_packages=['quintagroup', 'quintagroup.transmogrifier'],
+ namespace_packages=['quintagroup', 'quintagroup.transmogrify'],
include_package_data=True,
zip_safe=False,