Back to index

plone3  3.1.7
namechooser.py
Go to the documentation of this file.
00001 from zope.interface import implements
00002 from zope.component import getUtility
00003 from zope.component import queryUtility
00004 
00005 from zope.app.container.interfaces import INameChooser
00006 
00007 from plone.app.content.interfaces import INameFromTitle
00008 from plone.i18n.normalizer.interfaces import IUserPreferredURLNormalizer
00009 from plone.i18n.normalizer.interfaces import IURLNormalizer
00010 
00011 from Acquisition import aq_inner, aq_parent, aq_base
00012 from Products.CMFCore.interfaces import IPropertiesTool
00013 
00014 ATTEMPTS = 1000
00015 
00016 class NormalizingNameChooser(object):
00017     """A name chooser for a Zope object manager.
00018     
00019     If the object is adaptable to or provides INameFromTitle, use the
00020     title to generate a name.
00021     """
00022     
00023     implements(INameChooser)
00024     
00025     def __init__(self, context):
00026         self.context = context
00027 
00028     def checkName(self, name, object):
00029         return not self._getCheckId(object)(name, required=1)
00030 
00031     def chooseName(self, name, object):
00032         container = aq_inner(self.context)
00033         if not name:
00034             nameFromTitle = INameFromTitle(object, None)
00035             if nameFromTitle is not None:
00036                 name = nameFromTitle.title
00037             if not name:
00038                 name = getattr(aq_base(object), 'id', None)
00039             if not name:
00040                 name = getattr(aq_base(object), 'portal_type', None)
00041             if not name:
00042                 name = object.__class__.__name__
00043 
00044         if not isinstance(name, unicode):
00045             charset = self._getCharset(object)
00046             name = unicode(name, charset)
00047 
00048         request = getattr(object.__of__(container), 'REQUEST', None)
00049         if request is not None:
00050             name = IUserPreferredURLNormalizer(request).normalize(name)
00051         else:
00052             name = getUtility(IURLNormalizer).normalize(name)
00053             
00054         return self._findUniqueName(name, object)
00055             
00056 
00057     def _findUniqueName(self, name, object):
00058         """Find a unique name in the parent folder, based on the given id, by
00059         appending -n, where n is a number greater than 1, or just the id if
00060         it's ok.
00061         """
00062         check_id = self._getCheckId(object)
00063 
00064         if not check_id(name, required=1):
00065             return name
00066 
00067         idx = 1
00068         while idx <= ATTEMPTS:
00069             new_name = "%s-%d" % (name, idx)
00070             if not check_id(new_name, required=1):
00071                 return new_name
00072             idx += 1
00073 
00074         raise ValueError("Cannot find a unique name based on %s after %d attemps." % (name, ATTEMPTS,))
00075         
00076     def _getCheckId(self, object):
00077         """Return a function that can act as the check_id script.
00078         """
00079         check_id = getattr(object, 'check_id', None)
00080         if check_id is None:
00081             parent = aq_inner(self.context)
00082             parent_ids = parent.objectIds()
00083             check_id = lambda id, required: id in parent_ids
00084         return check_id
00085         
00086     def _getCharset(self, object):
00087         """Returns the site default charset, or utf-8.
00088         """
00089         properties = queryUtility(IPropertiesTool)
00090         if properties is not None:
00091             site_properties = getattr(properties, 'site_properties', None)
00092             if site_properties is not None:
00093                 return site_properties.getProperty('default_charset', 'utf-8')
00094         return 'utf-8'