"""BibliographyIdCooker main class""" import re import unicodedata # Zope stuff from zope.interface import implements from zope.interface import Interface from App.class_init import InitializeClass from AccessControl import ClassSecurityInfo from OFS.Folder import Folder from OFS.SimpleItem import SimpleItem from OFS.PropertyManager import PropertyManager import Products # PLONE things from plone.i18n.normalizer import filenamenormalizer from Products.CMFCore.utils import getToolByName from Products.CMFBibliographyAT.interface import \ IBibliographyIdCooker as z3IBibliographyIdCooker from Products.CMFBibliographyAT.interface import IBibliographyIdCookerFolder from bibliograph.core.utils import _encode, _decode class IBibliographyIdCooker(Interface): """ Interface for the bibliography ID cookers in the bibliography tool. """ def getId(): """ returns the id of the reference id cooker """ def Title(): """ returns the title of the reference id cooker """ def Description(): """ a short text that explains the basic functionality of the id cooker """ def isEnabled(): """ is the renderer enabled by the portal manager (default: yes)? """ def getCookedBibRefId(): """ returns a cooked id for a bibliography reference dictionary or object """ class BibliographyIdCooker(SimpleItem, PropertyManager): """ Base class for the id cookers of the bibliography tool. """ implements(z3IBibliographyIdCooker) meta_type = 'Bibliography IdCooker' idcooker_enabled = True manage_options = ( PropertyManager.manage_options + SimpleItem.manage_options ) _properties = PropertyManager._properties + ( {'id': 'idcooker_enabled', 'type': 'boolean', 'mode': 'w', }, ) security = ClassSecurityInfo() def __init__(self, id, title=''): """ minimal initialization """ self.id = id self.title = title def getId(self): """ returns the id of the id cooker """ return self.id def Title(self): """ returns the title of the id cooker """ domain='cmfbibliographyat' msgid='title_idcooker_%s' % self.getId().lower() return self.translate(domain=domain, msgid=msgid, default='%s' % self.title) def Description(self): """ a short text that explains the basic functionality of the id cooker """ domain='cmfbibliographyat' msgid='help_idcooker_%s' % self.getId() return self.translate(domain=domain, msgid=msgid, default='%s' % self.__doc__) def isEnabled(self): """ if the id cooker is enabled or not can be configured in the PropertyManager """ return self.idcooker_enabled def _cleanId(self, text): """remove all characters not allowed in Zope ids""" if not isinstance(text, unicode): try: text = unicode(text, 'utf-8') except UnicodeError: text = unicode(text, 'iso-8859-15') return unicodedata.normalize('NFKD', text).encode('ascii', 'ignore') def _object2ref(self, ref): """ If the passed on argument 'ref' is a BibRef Item (object), translate the import fields (authors, publication_year, title) to a ref dictionary (as in the parsers' code). """ if type(ref) != type({}): obj = ref bib_tool = getToolByName(self, 'portal_bibliography') ref = bib_tool.getEntryDict(obj) ref['UID'] = obj.UID() return ref def _refHasAuthorNames(self, ref): return ref.has_key('authors') and (len([ author['lastname'] for author in ref['authors'] if author.get('lastname', None) ]) >= 1) def _cookIdCore(self, ref, new_id='', **kwargs): """ the core id cooking method that is overridden in the individual id cookers """ return new_id # needs to be provided by the individual id cookers def getCookedBibRefId(self, ref, use_pid_on_import=True, **kwargs): """ cook id for ref dict or object, ref dict / object may be a single reference only """ isReferenceObject = (type(ref) != type({})) if isReferenceObject: ref = self._object2ref(ref) new_id = 'nobody1000' if use_pid_on_import and ref.get('pid'): new_id = ref['pid'] else: new_id = self._cookIdCore(ref, new_id=new_id) return _encode(_decode(self._cleanId(new_id))) InitializeClass(BibliographyIdCooker) class IdCookerFolder(Folder): """ A folder that only offers to add objects that implement the IBibliographyIdCooker interface. """ implements(IBibliographyIdCookerFolder) meta_type = 'IdCooker Folder' id = 'IdCookers' title = "BibliographyTool's id cooker folder" # we don't want 'View' manage_options = ( Folder.manage_options[0], ) \ + Folder.manage_options[2:] index_html = None def __init__(self, id, title=''): """ minimal initialization """ self.id = id # self.title = title def all_meta_types(self): product_infos = Products.meta_types possibles = [] for p in product_infos: try: if IBibliographyIdCooker in p.get('interfaces', []): possibles.append(p) except TypeError: pass definites = map(lambda x: x.meta_type, self.objectValues()) return filter(lambda x,y=definites: x['name'] not in y, possibles) InitializeClass(IdCookerFolder)