Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

merged from http://svn.plone.org/svn/collective/collective.portlet.ng…

  • Loading branch information...
commit 4a1a6ad27e955c592b0113a44c38f9dfd154ed1c 2 parents c946d7a + 5475cb0
@vmaksymiv vmaksymiv authored
View
40 collective/portlet/ngcollection/manager.py
@@ -1,4 +1,5 @@
import os
+import re
from zope.interface import implements
from zope.component import getGlobalSiteManager
@@ -6,9 +7,25 @@
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from collective.portlet.ngcollection.interfaces import IPortletTemplateManager
+from collective.portlet.ngcollection import migration
from Products.CMFCore.FSMetadata import FSMetadata
+osjoin = os.path.join
+
+def getDirKey(package, directory):
+ if package is not None:
+ packpath = package.__path__[0]
+ reldir = directory[len(packpath):].strip('/\\')
+ # bind-out from OS separators
+ '/'.join(reldir.split(os.sep))
+ return "%s-%s" % (package.__name__, reldir)
+ else:
+ return directory
+
+def getTemplateKey(dirkey, filename):
+ return ":".join([dirkey, filename])
+
class PortletTemplateManagerFactory(object):
def __init__(self):
self.manager = PortletTemplateManager()
@@ -16,28 +33,36 @@ def __init__(self):
def __call__(self, layer):
return self.manager
+
class PortletTemplateManager(object):
implements(IPortletTemplateManager)
def __init__(self):
self._templates = {}
- def registerDirectory(self, directory):
+ def registerDirectory(self, directory, package):
"""See interface"""
+ dirkey = getDirKey(package, directory)
for filename in os.listdir(directory):
if len(filename) > 3 and filename.endswith('.pt'):
- path = "%s/%s" % (directory, filename)
+ path = osjoin(directory, filename)
+ tmplkey = getTemplateKey(dirkey, filename)
metadata = FSMetadata(path)
metadata.read()
properties = metadata.getProperties()
title = properties.get('title', filename[:-3])
- self._templates[path] = (title.decode('utf-8'),
- ViewPageTemplateFile(path))
+ self._templates[tmplkey] = (title.decode('utf-8'),
+ ViewPageTemplateFile(path))
+ migration.add_to_migration_map(tmplkey, path)
- def unregisterDirectory(self, directory):
+ def unregisterDirectory(self, directory, package):
"""See interface"""
+ # HOOK: Generate remove key by passing directory key with
+ # EMPTY FILE NAME to getTemplateKey function
+ rmkey = getTemplateKey(getDirKey(package, directory), "")
for path, template in self.templates.items():
- del self._templates[path]
+ if path.startswith(rmkey):
+ del self._templates[path]
def hasTemplate(self, path):
"""See interface"""
@@ -62,4 +87,7 @@ def getPortletTemplateManagers(obj):
"""
gsm = getGlobalSiteManager()
for name, adapter in gsm.getAdapters((obj,), IPortletTemplateManager):
+ if migration.DO_MIGRATE:
+ migration.migrate(obj, adapter)
yield adapter
+
View
15 collective/portlet/ngcollection/metaconfigure.py
@@ -4,7 +4,7 @@
from collective.portlet.ngcollection import manager
from collective.portlet.ngcollection.interfaces import IPortletTemplateManager
-def handler(directory, interface):
+def handler(directory, interface, package):
gsm = component.getGlobalSiteManager()
# check if a portlet template manager already exists
@@ -16,17 +16,20 @@ def handler(directory, interface):
base_factories = set(factory for name, factory in gsm.adapters.lookupAll(
(implementedBy(interface.__bases__),), IPortletTemplateManager))
+ dirkey = manager.getDirKey(package, directory)
try:
factory = factories.difference(base_factories).pop()
except KeyError:
factory = manager.PortletTemplateManagerFactory()
component.provideAdapter(
- factory, (interface,), IPortletTemplateManager, name=directory)
+ factory, (interface,), IPortletTemplateManager, name=dirkey)
- factory(interface).registerDirectory(directory)
-
+ factory(interface).registerDirectory(directory, package)
+
+
def portletTemplatesDirective(_context, directory, interface):
+ package = _context.package
_context.action(
- discriminator = ('portletTemplates', directory, interface),
+ discriminator = ('portletTemplates', directory, interface, package),
callable = handler,
- args = (directory, interface))
+ args = (directory, interface, package ))
View
128 collective/portlet/ngcollection/migration.py
@@ -0,0 +1,128 @@
+"""
+ This module contains 2 parts:
+ * fill-in MIGRATION_MAP structure for migration to new-fashion keys
+ * migrator, which find proper template key (new) and
+ replace in object old (file systeme dependent) to new one
+
+ To turn-on migration you should set DO_MIGRATE constant into True value
+ and vice-versa.
+ Migration will be performed automatically on portlets rendering.
+"""
+
+
+import re
+import logging
+logger = logging.getLogger("collective.portlet.ngcollection")
+
+
+#DO_MIGRATE = False
+DO_MIGRATE = True
+
+SEPEXPR = re.compile(r"[/\\]")
+MIGRATION_MAP = {}
+
+class KeyTail(object):
+ """Object to save key and tail"""
+
+ def __init__(self, key='', tail=()):
+ self.key = str(key)
+ self.tail = list(tail)
+
+ def __str__(self):
+ return "%s : %s" % (self.key, self.tail)
+
+ def __repr__(self):
+ return "KeyTail <%s> %s : %s" % (id(self), self.key, self.tail[:5])
+
+
+def add_to_migration_map(key, path):
+ """Entry point for the MIGRATION_MAP filling"""
+ tail = SEPEXPR.split(path)
+ if len(tail) < 2:
+ logger.warn("Problematic path: '%s' (too small path items) "
+ "to resolve old NG Collector temlate key (%s)" % (path, key))
+ return
+
+ tail.reverse()
+ head, tail = tuple(tail[:2]), tail[2:]
+ keytail = KeyTail(key, tail)
+
+ addToMM(head, keytail, MIGRATION_MAP)
+
+
+def addToMM(head, keytail, branch):
+
+ val = branch.setdefault(head, keytail)
+ # If val is keytail - it's already added
+ # to the branch with key == head
+ if not val is keytail:
+ # if val is not keytail - this should be :
+ # * or mapping
+ # * or KeyTail type
+ if type(val) is type({}):
+ # go into recursion
+ newhead = keytail.tail.pop(0)
+ addToMM(newhead, keytail, val)
+
+ elif type(val) is KeyTail:
+ # This algorythm not review following collisions:
+ # * when tail tuple became empty (it's shouldn't
+ # happen in the case of this product)
+ key_val = val.tail.pop(0)
+ key_keytail = keytail.tail.pop(0)
+ newbranch = {
+ key_val : KeyTail(val.key, val.tail),
+ key_keytail : KeyTail(keytail.key, keytail.tail),
+ }
+ branch[head] = newbranch
+
+###########
+# Migrator
+###########
+
+def migrate(obj, adapter):
+ try:
+ template = obj.template
+ if isOldFashionKey(template):
+ new_template = getNewFashionKey(template)
+ obj.template = new_template
+ except:
+ logger.warn("Problem when try to migrate from file-system bind "
+ "template key to fs-independent for obj: %s" % str(obj))
+
+def isOldFashionKey(template):
+ # Check is path starts as path from the root in
+ # Unix-based or Windows-based systems
+ return template.startswith('/') or template[1] == ':'
+
+_marker = []
+def getNewFashionKey(old_key):
+ res = old_key
+
+ # Prepare path to use it parts for new
+ # key finding in MIGRATION_MAP
+ old_key_lst = SEPEXPR.split(old_key)
+ old_key_lst.reverse()
+ # First key - is tuple of template name and name of parent directory
+ old_key_lst = [tuple(old_key_lst[:2]),] + old_key_lst[2:]
+ data = MIGRATION_MAP
+ passed_keys = []
+ for k in old_key_lst:
+ val = data.get(k, _marker)
+ if val is _marker:
+ logger.warn("PROBLEM IN PATH RESOLUTION: \n"
+ " path : '%s'\n"
+ " passed keys : %s\n"
+ " not found key : '%s'" % (old_key, passed_keys, k))
+ break
+ else:
+ passed_keys.append(k)
+ if type(val) == KeyTail:
+ res = val.key
+ break
+ elif type(val) == type({}):
+ data = val
+
+ logger.info("Resolved '%s' file-system path to '%s' template key" % (old_key, res))
+ return res
+
View
1  collective/portlet/ngcollection/tests/test_portlet.py
@@ -160,6 +160,7 @@ def test_template(self):
fiveconfigure.debug_mode = False
t_path = path.join(dir_path, 'test.pt')
+ t_path = "%s:%s" % (dir_path, 'test.pt')
r = self.renderer(context=self.portal,
assignment=ngcollection.Assignment(header=u"title",
target_collection='/Members/test_user_1_/collection',
Please sign in to comment.
Something went wrong with that request. Please try again.