class Tool(UniqueObject, SimpleItem): """ Contentrules subscription tool """ id = SUBSCRIPTION_TOOL meta_type = 'Contentrules Subscription Tool' plone_tool = 1 def __init__(self): self.subscriptions = PersistentDict() def registerUser(self, rule_id, email): """ Insert the given email address in the given rule_id """ if not rule_id in self.subscriptions: self.subscriptions[rule_id] = [email] else: if email in self.subscriptions[rule_id]: factory = getUtility(IVocabularyFactory, "contentrules.subscription.vocabularies.SubscriptionRulesVocabulary") vocabulary = factory(self) rule_term = vocabulary.getTerm(rule_id) msg = _('already_subscribed_error', default='The given email is already present for "${title}"', mapping=dict(title=rule_term.title)) return False, msg else: self.subscriptions[rule_id].append(email) return True, "" def getSubscriptions(self): """ Return the list of subscriptions """ return self.subscriptions def getActionUIDS(self): """ return a list of email addresses for the given rule_id """ return self.subscriptions.keys() def getRegisteredList(self, rule_id): """ return a list of email addresses for the given rule_id """ return self.subscriptions.get(rule_id, [])
class UserAnnotation(object): """Stores annotations.""" def __init__(self, principalId, store=None): self.principalId = principalId # _v_store is used to remember a mapping object that we should # be saved in if we ever change self._v_store = store self._data = PersistentDict() if store is None else store.get(principalId, PersistentDict()) def __bool__(self): return bool(self._data) __nonzero__ = __bool__ def __getitem__(self, key): return self._data[key] def get(self, key, default=None): return self._data.get(key, default) def keys(self): return self._data.keys() def __iter__(self): return iter(self._data) def __len__(self): return len(self._data) def __setitem__(self, key, value): if getattr(self, '_v_store', None) is not None: # _v_store is used to remember a mapping object that we should # be saved in if we ever change self._v_store[self.principalId] = self._data del self._v_store self._data[key] = value def __delitem__(self, key): del self._data[key] def __contains__(self, key): return key in self._data def items(self): return self._data.items()
class UserAnnotation(object): """Stores annotations.""" def __init__(self, principalId, store=None): self.principalId = principalId # _v_store is used to remember a mapping object that we should # be saved in if we ever change self._v_store = store self._data = PersistentDict() if store is None else store.get( principalId, PersistentDict()) def __bool__(self): return bool(self._data) __nonzero__ = __bool__ def __getitem__(self, key): return self._data[key] def get(self, key, default=None): return self._data.get(key, default) def keys(self): return self._data.keys() def __iter__(self): return iter(self._data) def __len__(self): return len(self._data) def __setitem__(self, key, value): if getattr(self, '_v_store', None) is not None: # _v_store is used to remember a mapping object that we should # be saved in if we ever change self._v_store[self.principalId] = self._data del self._v_store self._data[key] = value def __delitem__(self, key): del self._data[key] def __contains__(self, key): return key in self._data def items(self): return self._data.items()
class MarscatsSettingsStorage(Persistent): implements(IMarscatsSettingsStorage) def __init__(self): self._fields = PersistentDict() def setStartupDir(self, fieldname, startup_dir, portal_type=None): field = self._fields.setdefault(fieldname, PersistentDict()) if portal_type is not None: portal_types = field.setdefault('portal_types', PersistentDict()) portal_types[portal_type] = startup_dir else: self._fields[fieldname]['startup_directory'] = startup_dir def getStartupDir(self, fieldname, portal_type=None, fallback=True, ispath=False): sd = '' if fallback: sd = CAT_CONTAINER if fieldname in self._fields.keys(): field = self._fields.get(fieldname) sd = field.get('startup_directory', sd) if portal_type is not None: pts = field.get('portal_types') if pts is not None: sd = pts.get(portal_type, sd) if ispath: if not sd.startswith(CAT_CONTAINER): sd = CAT_CONTAINER + '/' + sd # sd = '/' + sd return sd def getFieldNames(self): return list(self._fields) def getTypesForField(self, fieldname): if fieldname in self._fields: field = self._fields[fieldname] if 'portal_types' in field and len(field['portal_types']): return list(field['portal_types']) return list()
class MockContainer(PortalContent): """ """ implements(IUIDKeyedContainer, IAttributeUUID) def __init__(self, id, items=None): super(MockContainer, self).__init__() self.id = id self._items = PersistentDict(items) def get(self, uid, default=None): v = self._items.get(str(uid), None) if v and getattr(v, '_v_parent', None) is None: v._v_parent = self # container marks obtained item with context return v # just here for test use: def register(self, uid, item): self._items[uid] = item def unregister(self, uid): del (self._items[uid]) def __contains__(self, uid): return uid in self._items # here for indexing purposes, even though these indexes may # be handled differently in real life (e.g. indexer adapter): def UID(self): return IUUID(self) def contains(self): return self._items.keys() # UUIDs of contained items def items(self): return self._items.items()
class MockContainer(PortalContent): """ """ implements(IUIDKeyedContainer, IAttributeUUID) def __init__(self, id, items=None): super(MockContainer, self).__init__() self.id = id self._items = PersistentDict(items) def get(self, uid, default=None): v = self._items.get(str(uid), None) if v and getattr(v, '_v_parent', None) is None: v._v_parent = self # container marks obtained item with context return v # just here for test use: def register(self, uid, item): self._items[uid] = item def unregister(self, uid): del(self._items[uid]) def __contains__(self, uid): return uid in self._items # here for indexing purposes, even though these indexes may # be handled differently in real life (e.g. indexer adapter): def UID(self): return IUUID(self) def contains(self): return self._items.keys() # UUIDs of contained items def items(self): return self._items.items()
class BaseContainer(PersistentMapping): """ Provides a basis for `container` objects >>> container = BaseContainer() >>> container[u'foo'] = u'bar' >>> container[u'foo'] u'bar' >>> container.items() [(u'foo', u'bar')] >>> container.keys() [u'foo'] >>> container.values() [u'bar'] """ def __init__(self): self.data = PersistentDict() def __getitem__(self, key): return self.data.__getitem__(key) def __setitem__(self, key, value): """ Acts as a proxy to the self.data PersistentDict. As it is a persistent object, it will also try and assign the __parent__ attrubute to any object stored through this interface. >>> container = BaseContainer() >>> container.__setitem__('foo', 'bar') >>> 'foo' in container.data True >>> container['foo'].__parent__ # doctest: +ELLIPSIS Traceback (most recent call last): ... AttributeError: 'str' object has no attribute '__parent__' >>> class Child(object): ... __parent__ = None ... >>> container.__setitem__('baz', Child()) >>> 'baz' in container.data True >>> container['baz'].__parent__ == container True """ ret = self.data.__setitem__(key, value) try: self.data[key].__parent__ = self except: pass return ret def items(self): return self.data.items() def keys(self): return self.data.keys() def values(self): return self.data.values() def update(self, _data={}, **kwargs): """ BaseContainers can be updated much the same as any Python dictionary. By passing another mapping object: >>> container = BaseContainer() >>> container.update({'foo':'bar'}) By passing a list of iterables with length 2: >>> container = BaseContainer() >>> container.update([('foo', 'bar'),]) By passing a set of keyword arguments: >>> container = BaseContainer() >>> container.update(foo='bar') """ if kwargs: for k,v in kwargs.items(): self.__setitem__(k,v) return elif isinstance(_data, dict): for k,v in _data.items(): self.__setitem__(k,v) elif isinstance(_data, dict): for k,v in _data: self.__setitem__(k,v)
class Taxonomy(SimpleItem): implements(ITaxonomy) def __init__(self, name, title, default_language): super(Taxonomy, self).__init__(self) self.data = PersistentDict() self.name = name self.title = title self.default_language = default_language def __call__(self, context): if not self.data: return Vocabulary(self.name, {}, {}) request = getattr(context, "REQUEST", None) current_language = self.getCurrentLanguage(request) data = self.data[current_language] inverted_data = self.inverted_data[current_language] return Vocabulary(self.name, data, inverted_data) @property @ram.cache(lambda method, self: (self.name, self.data._p_mtime)) def inverted_data(self): inv_data = {} for (language, elements) in self.data.items(): inv_data[language] = {} for (path, identifier) in elements.items(): inv_data[language][identifier] = path return inv_data def getShortName(self): return self.name.split('.')[-1] def getGeneratedName(self): return 'collective.taxonomy.generated.' + self.getShortName() def getVocabularyName(self): return 'collective.taxonomy.' + self.getShortName() def getCurrentLanguage(self, request): try: portal_state = getMultiAdapter( (self, request), name=u'plone_portal_state' ) language = portal_state.language().split('-', 1)[0] except ComponentLookupError: language = '' # Force to return default language. if language in self.data: return language elif self.default_language in self.data: return self.default_language else: # our best guess! return self.data.keys()[0] def registerBehavior(self, **kwargs): context = getSite() sm = context.getSiteManager() new_args = copy(kwargs) new_args['name'] = self.name new_args['title'] = self.title new_args['description'] = kwargs.get('field_description', u'') new_args['field_description'] = new_args['description'] behavior = TaxonomyBehavior(**new_args) sm.registerUtility(behavior, IBehavior, name=self.getGeneratedName()) behavior.addIndex() behavior.activateSearchable() def cleanupFTI(self): """Cleanup the FTIs""" generated_name = self.getGeneratedName() context = getSite() sm = context.getSiteManager() for (name, fti) in sm.getUtilitiesFor(IDexterityFTI): if generated_name in fti.behaviors: fti.behaviors = [behavior for behavior in fti.behaviors if behavior != generated_name] modified(fti, DexterityFTIModificationDescription("behaviors", '')) def updateBehavior(self, **kwargs): sm = getSite().getSiteManager() behavior_name = self.getGeneratedName() short_name = self.getShortName() utility = sm.queryUtility(IBehavior, name=behavior_name) if utility: utility.deactivateSearchable() utility.activateSearchable() utility.title = kwargs['field_title'] delattr(generated, short_name) for (name, fti) in sm.getUtilitiesFor(IDexterityFTI): if behavior_name in fti.behaviors: modified(fti, DexterityFTIModificationDescription("behaviors", '')) def unregisterBehavior(self): context = getSite() sm = context.getSiteManager() behavior_name = self.getGeneratedName() utility = sm.queryUtility(IBehavior, name=behavior_name) if utility is None: return self.cleanupFTI() utility.removeIndex() utility.deactivateSearchable() utility.unregisterInterface() sm.unregisterUtility(utility, IBehavior, name=behavior_name) def clean(self): self.data.clear() def add(self, language, identifier, path): if not language in self.data: self.data[language] = OOBTree() self.data[language][path] = identifier def translate(self, msgid, mapping=None, context=None, target_language=None, default=None): if target_language is None or \ target_language not in self.inverted_data: target_language = str(self.getCurrentLanguage( getattr(context, 'REQUEST') )) if msgid not in self.inverted_data[target_language]: return '' path = self.inverted_data[target_language][msgid] pretty_path = path[1:].replace(PATH_SEPARATOR, u' ยป ') return pretty_path
class RegistrationApproval(PloneBaseTool, UniqueObject, SimpleItem): implements(IRegistrationApproval) id = 'wcc_membership_registration_approval' meta_type = 'WCC Registration Approval Tool' toolicon = 'skins/plone_images/site_icon.png' security = ClassSecurityInfo() def __init__(self): self._data = PersistentDict() def is_memberid_allowed(self, key): return not (key in self._data.keys()) def values(self): for x in self._data.values(): if not x.has_key('username'): x['username'] = x['email'] return sorted(self._data.values(), key=(lambda x: x['username'])) def add(self, key, data): if key in self._data.keys(): raise ConflictError(u'User already exist in pending') data['username'] = key self._data[key] = data notify(UserRegisteredEvent(data)) def get(self, key): return self._data[key] def approve(self, key): if key not in self._data.keys(): raise KeyError(key) portal = getSite() registration = getToolByName(self, 'portal_registration') portal_props = getToolByName(self, 'portal_properties') mt = getToolByName(self, 'portal_membership') props = portal_props.site_properties use_email_as_login = props.getProperty('use_email_as_login') data = self._data[key] if use_email_as_login: data['username'] = data['email'] user_id = data['username'] password = registration.generatePassword() request = getRequest() try: registration.addMember(user_id, password, REQUEST=request) except (AttributeError, ValueError), err: logging.exception(err) IStatusMessage(request).addStatusMessage(err, type="error") return # set additional properties using the user schema adapter schema = getUtility(IUserDataSchemaProvider).getSchema() adapter = getAdapter(portal, schema) adapter.context = mt.getMemberById(user_id) for name in getFieldNamesInOrder(schema): if name in data: setattr(adapter, name, data[name]) notify(UserApprovedEvent(data)) del self._data[key]
class Taxonomy(SimpleItem): order = None count = None version = None def __init__(self, name, title, default_language): self.data = PersistentDict() self.order = PersistentDict() self.count = PersistentDict() self.version = PersistentDict() self.name = name self.title = title self.default_language = default_language @property def sm(self): return api.portal.get().getSiteManager() def __call__(self, context): if not self.data: return Vocabulary(self.name, {}, {}, {}, 2) request = getattr(context, "REQUEST", None) language = self.getCurrentLanguage(request) return self.makeVocabulary(language) @property @ram.cache(lambda method, self: (self.name, self.data._p_mtime)) def inverted_data(self): inv_data = {} for (language, elements) in self.data.items(): inv_data[language] = {} for (path, identifier) in elements.items(): inv_data[language][identifier] = path return inv_data def getShortName(self): return self.name.split('.')[-1] def getGeneratedName(self): return 'collective.taxonomy.generated.' + self.getShortName() def getVocabularyName(self): return 'collective.taxonomy.' + self.getShortName() def makeVocabulary(self, language): self._fixup() data = self.data.get(language, {}) order = self.order.get(language) version = self.version.get(language, 1) inverted_data = self.inverted_data.get(language, {}) return Vocabulary(self.name, data, inverted_data, order, version) def getCurrentLanguage(self, request): language = get_lang_code() if language in self.data: return language elif self.default_language in self.data: return self.default_language else: # our best guess! return self.data.keys()[0] def getLanguages(self): return tuple(self.data) def iterLanguage(self, language=None): if language is None: language = self.default_language vocabulary = self.makeVocabulary(language) for path, identifier in vocabulary.iterEntries(): parent_path = path.rsplit(PATH_SEPARATOR, 1)[0] if parent_path: parent = vocabulary.getTermByValue(parent_path) else: parent = None yield path, identifier, parent def registerBehavior(self, **kwargs): new_args = copy(kwargs) new_args['name'] = self.getGeneratedName() new_args['title'] = self.title new_args['description'] = kwargs.get('field_description', u'') new_args['field_description'] = new_args['description'] behavior = TaxonomyBehavior(**new_args) self.sm.registerUtility(behavior, IBehavior, name=self.getGeneratedName()) behavior.addIndex() behavior.activateSearchable() def cleanupFTI(self): """Cleanup the FTIs""" generated_name = self.getGeneratedName() for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI): if generated_name in fti.behaviors: fti.behaviors = [behavior for behavior in fti.behaviors if behavior != generated_name] modified(fti, DexterityFTIModificationDescription("behaviors", '')) def updateBehavior(self, **kwargs): behavior_name = self.getGeneratedName() short_name = self.getShortName() utility = self.sm.queryUtility(IBehavior, name=behavior_name) if utility: utility.deactivateSearchable() utility.activateSearchable() if 'field_title' in kwargs: utility.title = kwargs.pop('field_title') for k, v in kwargs.items(): setattr(utility, k, v) delattr(generated, short_name) for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI): if behavior_name in fti.behaviors: modified(fti, DexterityFTIModificationDescription("behaviors", '')) def unregisterBehavior(self): behavior_name = self.getGeneratedName() utility = self.sm.queryUtility(IBehavior, name=behavior_name) if utility is None: return self.cleanupFTI() utility.removeIndex() utility.deactivateSearchable() utility.unregisterInterface() self.sm.unregisterUtility(utility, IBehavior, name=behavior_name) def clean(self): self.data.clear() def add(self, language, value, key): self._fixup() tree = self.data.get(language) if tree is None: tree = self.data[language] = OOBTree() else: # Make sure we update the modification time. self.data[language] = tree update = key in tree tree[key] = value order = self.order.get(language) if order is None: order = self.order[language] = IOBTree() count = self.count[language] = 0 else: if update: pop_value(tree, key) count = self.count[language] + 1 self.count[language] = count order[count] = key def update(self, language, items, clear=False): self._fixup() tree = self.data.setdefault(language, OOBTree()) if clear: tree.clear() # A new tree always uses the newest version. if not tree: version = self.version[language] = 2 else: version = self.version.get(language, 1) order = self.order.setdefault(language, IOBTree()) count = self.count.get(language, 0) if clear: order.clear() count = 0 # Always migrate to newest version. if version == 1: def fix(path): return path.replace(LEGACY_PATH_SEPARATOR, PATH_SEPARATOR) for i in list(order): path = order[i] order[i] = fix(path) for path in list(tree): value = tree.pop(path) tree[fix(path)] = value version = self.version[language] = 2 logger.info( "Taxonomy '%s' upgraded to version %d for language '%s'." % ( self.name, version, language ) ) # Make sure we update the modification time. self.data[language] = tree # The following structure is used to expunge updated entries. inv = {} if not clear: for i, key in order.items(): inv[key] = i seen = set() for key, value in items: if key in seen: logger.warning("Duplicate key entry: %r" % (key, )) continue seen.add(key) update = key in tree tree[key] = value order[count] = key count += 1 # If we're updating, then we have to pop out the old ordering # information in order to maintain relative ordering of new items. if update: i = inv.get(key) if i is not None: del order[i] self.count[language] = count def translate(self, msgid, mapping=None, context=None, target_language=None, default=None, msgid_plural=None, default_plural=None, number=None): if target_language is None or \ target_language not in self.inverted_data: target_language = str(api.portal.get_current_language()) if msgid not in self.inverted_data[target_language]: return '' if self.version is not None and self.version.get(target_language) != 2: path_sep = LEGACY_PATH_SEPARATOR else: path_sep = PATH_SEPARATOR path = self.inverted_data[target_language][msgid] pretty_path = path[1:].replace(path_sep, PRETTY_PATH_SEPARATOR) if mapping is not None and mapping.get(NODE): pretty_path = pretty_path.rsplit(PRETTY_PATH_SEPARATOR, 1)[-1] return pretty_path def _fixup(self): # due to compatibility reasons this method fixes data structure # for old Taxonomy instances. # XXX: remove this in version 2.0 to prevent write on read if self.order is None: safeWrite(self, getRequest()) self.order = PersistentDict() self.count = PersistentDict() if self.version is None: safeWrite(self, getRequest()) self.version = PersistentDict()
class UserIdentities(Persistent): def __init__(self, userid): self.userid = userid self._identities = PersistentDict() self._sheet = None self._secret = str(uuid.uuid4()) @property def secret(self): return self._secret def check_password(self, password): return password == self._secret def handle_result(self, result): """add a authomatic result to this user """ self._sheet = None # invalidate property sheet self._identities[result.provider.name] = UserIdentity(result) def identity(self, provider): """users identity at a distinct provider """ return self._identities.get(provider, None) def providers(self): """List linked providers """ return self._identities.keys() def unlink(self, provider): return self._identities.pop(provider) def update_userdata(self, result): self._sheet = None # invalidate property sheet identity = self._identities[result.provider.name] identity.update(result.user.to_dict()) @property def propertysheet(self): if self._sheet is not None: return self._sheet # build sheet from identities pdata = dict(id=self.userid) cfgs_providers = authomatic_cfg() for provider_name in cfgs_providers: identity = self.identity(provider_name) if identity is None: continue logger.debug(identity) cfg = cfgs_providers[provider_name] for akey, pkey in cfg.get('propertymap', {}).items(): # Always search first on the user attributes, then on the raw # data this guaratees we do not break existing configurations ainfo = identity.get(akey, identity['data'].get(akey, None)) if ainfo is None: continue if isinstance(pkey, dict): for k, v in pkey.items(): pdata[k] = ainfo.get(v) else: pdata[pkey] = ainfo self._sheet = UserPropertySheet(**pdata) return self._sheet
class PlominoDocument(CatalogAware, CMFBTreeFolder, Contained): """ These represent the contents in a Plomino database. A document contains *items* that may or may not correspond to fields on one or more forms. """ security = ClassSecurityInfo() implements(interfaces.IPlominoDocument, IAttributeAnnotatable) portal_type = "PlominoDocument" meta_type = "PlominoDocument" security.declarePublic('__init__') def __init__(self, id): """ Initialization """ CMFBTreeFolder.__init__(self, id) self.id = id self.items = PersistentDict() self.plomino_modification_time = DateTime().toZone('UTC') security.declarePublic('checkBeforeOpenDocument') def checkBeforeOpenDocument(self): """ Check read permission and open view. .. NOTE:: if ``READ_PERMISSION`` is set on the ``view`` action itself, it causes an error ('maximum recursion depth exceeded') if user hasn't permission. """ if self.isReader(): return self.OpenDocument() else: raise Unauthorized, "You cannot read this content" def doc_path(self): return self.getPhysicalPath() def doc_url(self): """ return valid and nice url: - hide plomino_documents - use physicalPathToURL if REQUEST available """ path = self.doc_path() short_path = [p for p in path if p != "plomino_documents"] if hasattr(self, "REQUEST"): return self.REQUEST.physicalPathToURL(short_path) else: return "/".join(short_path) security.declarePublic('setItem') def setItem(self, name, value): """ """ items = self.items if type(value) == type(''): db = self.getParentDatabase() translation_service = getToolByName(db, 'translation_service') value = translation_service.asunicodetype(value) items[name] = value self.items = items self.plomino_modification_time = DateTime().toZone('UTC') security.declarePublic('getItem') def getItem(self, name, default=''): """ """ if (self.items.has_key(name)): return deepcopy(self.items[name]) else: return default security.declarePublic('hasItem') def hasItem(self, name): """ """ return self.items.has_key(name) security.declarePublic('removeItem') def removeItem(self, name): """ """ if (self.items.has_key(name)): items = self.items del items[name] self.items = items security.declarePublic('getItems') def getItems(self): """ """ return self.items.keys() security.declarePublic('getItemClassname') def getItemClassname(self, name): """ """ return self.getItem(name).__class__.__name__ security.declarePublic('getLastModified') def getLastModified(self, asString=False): """ """ if not hasattr(self, 'plomino_modification_time'): self.plomino_modification_time = self.bobobase_modification_time( ).toZone('UTC') if asString: return str(self.plomino_modification_time) else: return self.plomino_modification_time security.declarePublic('getRenderedItem') def getRenderedItem(self, itemname, form=None, formid=None, convertattachments=False): """ Return the item rendered according to the corresponding field. The used form can be, in order of precedence: - passed as the `form` parameter, - specified with the `formid` parameter and looked up, - looked up from the document. If no form or field is found, return the empty string. If `convertattachments` is True, then we assume that field attachments are text and append them to the rendered value. """ db = self.getParentDatabase() result = '' if not form: if formid: form = db.getForm(formid) else: form = self.getForm() if form: field = form.getFormField(itemname) if field: result = field.getFieldRender(form, self, False) if (field.getFieldType() == 'ATTACHMENT' and convertattachments): result += ' ' + db.getIndex().convertFileToText( self, itemname).decode('utf-8') result = result.encode('utf-8') return result security.declarePublic('tojson') def tojson(self, REQUEST=None, item=None, formid=None, rendered=False): """return item value as JSON (return all items if item=None) """ if not self.isReader(): raise Unauthorized, "You cannot read this content" datatables_format = False if REQUEST: REQUEST.RESPONSE.setHeader('content-type', 'application/json; charset=utf-8') item = REQUEST.get('item', item) formid = REQUEST.get('formid', formid) rendered_str = REQUEST.get('rendered', None) if rendered_str: rendered = True datatables_format_str = REQUEST.get('datatables', None) if datatables_format_str: datatables_format = True if not item: return json.dumps(self.items.data) if not formid: form = self.getForm() else: form = self.getParentDatabase().getForm(formid) if form: field = form.getFormField(item) if field: if field.getFieldType() == 'DATAGRID': adapt = field.getSettings() fieldvalue = adapt.getFieldValue(form, self, False, False, REQUEST) fieldvalue = adapt.rows(fieldvalue, rendered=rendered) if datatables_format: fieldvalue = { 'iTotalRecords': len(fieldvalue), 'aaData': fieldvalue } else: if rendered: fieldvalue = self.getRenderedItem(item, form) else: adapt = field.getSettings() fieldvalue = adapt.getFieldValue( form, self, False, False, REQUEST) else: fieldvalue = self.getItem(item) else: fieldvalue = self.getItem(item) return json.dumps(fieldvalue) security.declarePublic('computeItem') def computeItem(self, itemname, form=None, formid=None, store=True, report=True): """ return the item value according the formula of the field defined in the given form (use default doc form if None) and store the value in the doc (if store=True) """ result = None db = self.getParentDatabase() if not form: if not formid: form = self.getForm() else: form = db.getForm(formid) if form: result = form.computeFieldValue(itemname, self, report=report) if store: self.setItem(itemname, result) return result security.declarePublic('getPlominoReaders') def getPlominoReaders(self): """ """ if self.hasItem('Plomino_Readers'): return asList(self.Plomino_Readers) else: return ['*'] security.declarePublic('isReader') def isReader(self): """ """ return self.getParentDatabase().isCurrentUserReader(self) security.declarePublic('isAuthor') def isAuthor(self): """ """ return self.getParentDatabase().isCurrentUserAuthor(self) security.declareProtected(REMOVE_PERMISSION, 'delete') def delete(self, REQUEST=None): """delete the current doc """ db = self.getParentDatabase() db.deleteDocument(self) if not REQUEST is None: return_url = REQUEST.get('returnurl') REQUEST.RESPONSE.redirect(return_url) security.declareProtected(EDIT_PERMISSION, 'validation_errors') def validation_errors(self, REQUEST): """check submitted values """ db = self.getParentDatabase() form = db.getForm(REQUEST.get('Form')) errors = form.validateInputs(REQUEST, doc=self) if len(errors) > 0: return self.errors_json(errors=json.dumps({ 'success': False, 'errors': errors })) else: return self.errors_json(errors=json.dumps({'success': True})) security.declareProtected(EDIT_PERMISSION, 'saveDocument') def saveDocument(self, REQUEST, creation=False): """save a document using the form submitted content """ db = self.getParentDatabase() form = db.getForm(REQUEST.get('Form')) errors = form.validateInputs(REQUEST, doc=self) if len(errors) > 0: return form.notifyErrors(errors) self.setItem('Form', form.getFormName()) # process editable fields (we read the submitted value in the request) form.readInputs(self, REQUEST, process_attachments=True) # refresh computed values, run onSave, reindex self.save(form, creation) redirect = REQUEST.get('plominoredirecturl') if not redirect: redirect = self.getItem("plominoredirecturl") if not redirect: redirect = self.absolute_url() REQUEST.RESPONSE.redirect(redirect) security.declareProtected(EDIT_PERMISSION, 'refresh') def refresh(self, form=None): """ re-compute fields and re-index document (onSave event is not called, and authors are not updated """ self.save(form, creation=False, refresh_index=True, asAuthor=False, onSaveEvent=False) security.declareProtected(EDIT_PERMISSION, 'save') def save(self, form=None, creation=False, refresh_index=True, asAuthor=True, onSaveEvent=True): """refresh values according form, and reindex the document """ # we process computed fields (refresh the value) if form is None: form = self.getForm() else: self.setItem('Form', form.getFormName()) db = self.getParentDatabase() if form: for f in form.getFormFields(includesubforms=True, doc=self, applyhidewhen=False): mode = f.getFieldMode() fieldname = f.id if mode in ["COMPUTED", "COMPUTEDONSAVE" ] or (mode == "CREATION" and creation): result = form.computeFieldValue(fieldname, self) self.setItem(fieldname, result) else: # computed for display field are not stored pass # compute the document title title_formula = form.getDocumentTitle() if title_formula: # Use the formula if we have one try: title = self.runFormulaScript("form_" + form.id + "_title", self, form.DocumentTitle) if title != self.Title(): self.setTitle(title) except PlominoScriptException, e: e.reportError('Title formula failed') elif creation: # If we have no formula and we're creating, use Form's title title = form.Title() if title != self.Title(): # We may be calling save with 'creation=True' on # existing documents, in which case we may already have # a title. self.setTitle(title) # update the document id if creation and form.getDocumentId(): new_id = self.generateNewId() if new_id: transaction.savepoint(optimistic=True) db.documents.manage_renameObject(self.id, new_id) # update the Plomino_Authors field with the current user name if asAuthor: authors = self.getItem('Plomino_Authors') name = db.getCurrentUser().getUserName() if authors == '': authors = [] authors.append(name) elif name in authors: pass else: authors.append(name) self.setItem('Plomino_Authors', authors) # execute the onSaveDocument code of the form if form and onSaveEvent: try: result = self.runFormulaScript("form_" + form.id + "_onsave", self, form.onSaveDocument) if result and hasattr(self, 'REQUEST'): self.REQUEST.set('plominoredirecturl', result) except PlominoScriptException, e: if hasattr(self, 'REQUEST'): e.reportError( 'Document has been saved but onSave event failed.') doc_path = self.REQUEST.physicalPathToURL(self.doc_path()) self.REQUEST.RESPONSE.redirect(doc_path)
class PlominoDocument(CatalogAware, CMFBTreeFolder, Contained): """ These represent the contents in a Plomino database. A document contains *items*. An item may or may not correspond to fields on one or more forms. They may be manipulated by Formulas. """ security = ClassSecurityInfo() implements(IPlominoDocument, IAttributeAnnotatable) portal_type = "PlominoDocument" meta_type = "PlominoDocument" security.declarePublic('__init__') def __init__(self, id): """ Initialization """ CMFBTreeFolder.__init__(self, id) self.id = id self.items = PersistentDict() self.plomino_modification_time = DateTime().toZone(TIMEZONE) def absolute_url(self): db_url = self.getParentDatabase().absolute_url() return "%s/document/%s" % (db_url, self.id) def doc_path(self): db_path = self.getParentDatabase().getPhysicalPath() return list(db_path) + ["document", self.id] def doc_url(self): """ Return valid and nice url """ path = self.doc_path() if hasattr(self, "REQUEST"): return self.REQUEST.physicalPathToURL(path) else: return "/".join(path) security.declarePublic('setItem') def setItem(self, name, value): """ Set item on document, converting str to unicode. """ items = self.items if isinstance(value, str): db = self.getParentDatabase() translation_service = getToolByName(db, 'translation_service') value = translation_service.asunicodetype(value) items[name] = value self.items = items self.plomino_modification_time = DateTime().toZone(TIMEZONE) security.declarePublic('getItem') def getItem(self, name, default=''): """ Get item from document. """ if name in self.items: return deepcopy(self.items[name]) else: return default security.declarePublic('hasItem') def hasItem(self, name): """ Check if doc has item 'name'. """ return name in self.items security.declarePublic('removeItem') def removeItem(self, name): """ Delete item 'name', if it exists. """ if name in self.items: items = self.items del items[name] self.items = items security.declarePublic('getItems') def getItems(self): """ Return all item names. """ return self.items.keys() security.declarePublic('getItemClassname') def getItemClassname(self, name): """ Return class name of the item. """ return self.getItem(name).__class__.__name__ security.declarePublic('getLastModified') def getLastModified(self, asString=False): """ Return last modified date, setting it if absent. """ if not hasattr(self, 'plomino_modification_time'): self.plomino_modification_time =\ self.bobobase_modification_time().toZone(TIMEZONE) if asString: return DateToString( self.plomino_modification_time, db=self.getParentDatabase()) else: return self.plomino_modification_time security.declarePublic('getRenderedItem') def getRenderedItem(self, itemname, form=None, formid=None, convertattachments=False): """ Return the item rendered according to the corresponding field. The form used can be, in order of precedence: - passed as the `form` parameter, - specified with the `formid` parameter and looked up, - looked up from the document. If no form or field is found, return the empty string. If `convertattachments` is True, then we assume that field attachments are text and append them to the rendered value. """ db = self.getParentDatabase() result = '' if not form: if formid: form = db.getForm(formid) else: form = self.getForm() if form: field = form.getFormField(itemname) if field: result = field.getFieldRender(form, self, False) if (field.field_type == 'ATTACHMENT' and convertattachments): result += ' ' + db.getIndex().convertFileToText( self, itemname).decode('utf-8') result = result.encode('utf-8') return result security.declarePublic('tojson') def tojson( self, REQUEST=None, item=None, formid=None, rendered=False, lastmodified=None ): """ Return item value as JSON. Return all items if `item=None`. Values on the REQUEST overrides parameters. If the requested item corresponds to a field on the found form, the field value is returned. If not, it falls back to a plain item lookup on the document. `formid="None"` specifies plain item lookup. """ # TODO: Don't always return the entire dataset: allow batching. if not self.isReader(): raise Unauthorized("You cannot read this content") datatables_format = False if REQUEST: REQUEST.RESPONSE.setHeader( 'content-type', 'application/json; charset=utf-8') item = REQUEST.get('item', item) formid = REQUEST.get('formid', formid) lastmodified = REQUEST.get('lastmodified', lastmodified) rendered_str = REQUEST.get('rendered', None) if rendered_str: rendered = True datatables_format_str = REQUEST.get('datatables', None) if datatables_format_str: datatables_format = True if item: if formid == "None": form = None elif formid: form = self.getParentDatabase().getForm(formid) else: form = self.getForm() if form: field = form.getFormField(item) if field: if field.field_type == 'DATAGRID': adapt = field.getSettings() fieldvalue = adapt.getFieldValue( form, doc=self, request=REQUEST) fieldvalue = adapt.rows( fieldvalue, rendered=rendered) else: if rendered: fieldvalue = self.getRenderedItem(item, form) else: adapt = field.getSettings() fieldvalue = adapt.getFieldValue( form, doc=self, request=REQUEST) else: fieldvalue = self.getItem(item) else: fieldvalue = self.getItem(item) data = fieldvalue else: data = self.items.data if datatables_format: data = {'iTotalRecords': len(data), 'iTotalDisplayRecords': len(data), 'aaData': data} if lastmodified: data = {'lastmodified': self.getLastModified(), 'data': data} return json.dumps(data) security.declarePublic('computeItem') def computeItem(self, itemname, form=None, formid=None, store=True, report=True): """ Return the value of named item according to the formula - of the field defined in the given form (default), - or the named `formid`, - or use the default doc form if no form found. Store the value in the doc (if `store=True`). (Pass `report` to `PlominoForm.computeFieldValue`.) """ result = None if not form: if not formid: form = self.getForm() else: db = self.getParentDatabase() form = db.getForm(formid) if form: result = form.computeFieldValue(itemname, self, report=report) if store: # So this is a way to store the value of a DISPLAY field .. self.setItem(itemname, result) return result security.declarePublic('getPlominoReaders') def getPlominoReaders(self): """ Return list of readers; if none set, everyone can read. """ if self.hasItem('Plomino_Readers'): return asList(self.getItem('Plomino_Readers')) else: return ['*'] security.declarePublic('isReader') def isReader(self): """ """ return self.getParentDatabase().isCurrentUserReader(self) security.declarePublic('isAuthor') def isAuthor(self): """ """ return self.getParentDatabase().isCurrentUserAuthor(self) security.declareProtected(REMOVE_PERMISSION, 'delete') def delete(self, REQUEST=None): """ Delete the current doc; redirect to `returnurl` if available. """ db = self.getParentDatabase() db.deleteDocument(self) if REQUEST: return_url = REQUEST.get('returnurl') if not return_url: return_url = db.absolute_url() REQUEST.RESPONSE.redirect(return_url) security.declareProtected(EDIT_PERMISSION, 'validation_errors') def validation_errors(self, REQUEST): """ Check submitted values. """ db = self.getParentDatabase() form = db.getForm(REQUEST.get('Form')) errors = form.validateInputs(REQUEST, doc=self) if errors: return self.errors_json( errors=json.dumps({'success': False, 'errors': errors})) else: return self.errors_json( errors=json.dumps({'success': True})) security.declareProtected(EDIT_PERMISSION, 'saveDocument') def saveDocument(self, REQUEST, creation=False): """ Save a document using the form submitted content """ db = self.getParentDatabase() form = db.getForm(REQUEST.get('Form')) errors = form.validateInputs(REQUEST, doc=self) # execute the beforeSave code of the form error = None try: error = self.runFormulaScript( SCRIPT_ID_DELIMITER.join(['form', form.id, 'beforesave']), self, form.beforeSaveDocument) except PlominoScriptException, e: e.reportError('Form submitted, but beforeSave formula failed') if error: errors.append(error) # if errors, stop here, and notify errors to user if errors: return form.notifyErrors(errors) self.setItem('Form', form.id) # process editable fields (we read the submitted value in the request) form.readInputs(self, REQUEST, process_attachments=True) # refresh computed values, run onSave, reindex self.save(form, creation) redirect = REQUEST.get('plominoredirecturl') if not redirect: redirect = self.getItem("plominoredirecturl") if type(redirect) is dict: # if dict, we assume it contains "callback" as an URL that will be # called asynchronously, "redirect" as the redirect url (optional, # default=doc url), and "method" (optional, default=GET) redirect = "./async_callback?" + urlencode(redirect) if not redirect: redirect = self.absolute_url() REQUEST.RESPONSE.redirect(addTokenToUrl(redirect))
class Taxonomy(SimpleItem): def __init__(self, name, title, default_language): self.data = PersistentDict() self.name = name self.title = title self.default_language = default_language @property def sm(self): return api.portal.get().getSiteManager() def __call__(self, context): if not self.data: return Vocabulary(self.name, {}, {}) request = getattr(context, "REQUEST", None) current_language = self.getCurrentLanguage(request) data = self.data[current_language] inverted_data = self.inverted_data[current_language] return Vocabulary(self.name, data, inverted_data) @property @ram.cache(lambda method, self: (self.name, self.data._p_mtime)) def inverted_data(self): inv_data = {} for (language, elements) in self.data.items(): inv_data[language] = {} for (path, identifier) in elements.items(): inv_data[language][identifier] = path return inv_data def getShortName(self): return self.name.split('.')[-1] def getGeneratedName(self): return 'collective.taxonomy.generated.' + self.getShortName() def getVocabularyName(self): return 'collective.taxonomy.' + self.getShortName() def getCurrentLanguage(self, request): language = get_lang_code() if language in self.data: return language elif self.default_language in self.data: return self.default_language else: # our best guess! return self.data.keys()[0] def registerBehavior(self, **kwargs): new_args = copy(kwargs) new_args['name'] = self.getGeneratedName() new_args['title'] = self.title new_args['description'] = kwargs.get('field_description', u'') new_args['field_description'] = new_args['description'] behavior = TaxonomyBehavior(**new_args) self.sm.registerUtility(behavior, IBehavior, name=self.getGeneratedName()) behavior.addIndex() behavior.activateSearchable() def cleanupFTI(self): """Cleanup the FTIs""" generated_name = self.getGeneratedName() for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI): if generated_name in fti.behaviors: fti.behaviors = [ behavior for behavior in fti.behaviors if behavior != generated_name ] modified(fti, DexterityFTIModificationDescription("behaviors", '')) def updateBehavior(self, **kwargs): behavior_name = self.getGeneratedName() short_name = self.getShortName() utility = self.sm.queryUtility(IBehavior, name=behavior_name) if utility: utility.deactivateSearchable() utility.activateSearchable() if 'field_title' in kwargs: utility.title = kwargs.pop('field_title') for k, v in kwargs.iteritems(): setattr(utility, k, v) delattr(generated, short_name) for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI): if behavior_name in fti.behaviors: modified(fti, DexterityFTIModificationDescription("behaviors", '')) def unregisterBehavior(self): behavior_name = self.getGeneratedName() utility = self.sm.queryUtility(IBehavior, name=behavior_name) if utility is None: return self.cleanupFTI() utility.removeIndex() utility.deactivateSearchable() utility.unregisterInterface() self.sm.unregisterUtility(utility, IBehavior, name=behavior_name) def clean(self): self.data.clear() def add(self, language, identifier, path): if language not in self.data: self.data[language] = OOBTree() self.data[language][path] = identifier def translate(self, msgid, mapping=None, context=None, target_language=None, default=None): if target_language is None or \ target_language not in self.inverted_data: target_language = str( self.getCurrentLanguage(getattr(context, 'REQUEST'))) if msgid not in self.inverted_data[target_language]: return '' path = self.inverted_data[target_language][msgid] pretty_path = path[1:].replace(PATH_SEPARATOR, u' ยป ') return pretty_path
class Taxonomy(SimpleItem): order = None count = None version = None def __init__(self, name, title, default_language): self.data = PersistentDict() self.order = PersistentDict() self.count = PersistentDict() self.version = PersistentDict() self.name = name self.title = title self.default_language = default_language @property def sm(self): return api.portal.get().getSiteManager() def __call__(self, context): if not self.data: return Vocabulary(self.name, {}, {}, {}, 2) request = getattr(context, "REQUEST", None) language = self.getCurrentLanguage(request) return self.makeVocabulary(language) @property @ram.cache(lambda method, self: (self.name, self.data._p_mtime)) def inverted_data(self): inv_data = {} for (language, elements) in self.data.items(): inv_data[language] = {} for (path, identifier) in elements.items(): inv_data[language][identifier] = path return inv_data def getShortName(self): return self.name.split('.')[-1] def getGeneratedName(self): return 'collective.taxonomy.generated.' + self.getShortName() def getVocabularyName(self): return 'collective.taxonomy.' + self.getShortName() def makeVocabulary(self, language): self._fixup() data = self.data.get(language, {}) order = self.order.get(language) version = self.version.get(language, 1) inverted_data = self.inverted_data.get(language, {}) return Vocabulary(self.name, data, inverted_data, order, version) def getCurrentLanguage(self, request): language = get_lang_code() if language in self.data: return language elif self.default_language in self.data: return self.default_language else: # our best guess! return self.data.keys()[0] def getLanguages(self): return tuple(self.data) def iterLanguage(self, language=None): if language is None: language = self.default_language vocabulary = self.makeVocabulary(language) for path, identifier in vocabulary.iterEntries(): parent_path = path.rsplit(PATH_SEPARATOR, 1)[0] if parent_path: parent = vocabulary.getTermByValue(parent_path) else: parent = None yield path, identifier, parent def registerBehavior(self, **kwargs): new_args = copy(kwargs) new_args['name'] = self.getGeneratedName() new_args['title'] = self.title new_args['description'] = kwargs.get('field_description', u'') new_args['field_description'] = new_args['description'] behavior = TaxonomyBehavior(**new_args) self.sm.registerUtility(behavior, IBehavior, name=self.getGeneratedName()) behavior.addIndex() behavior.activateSearchable() def cleanupFTI(self): """Cleanup the FTIs""" generated_name = self.getGeneratedName() for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI): if generated_name in fti.behaviors: fti.behaviors = [behavior for behavior in fti.behaviors if behavior != generated_name] modified(fti, DexterityFTIModificationDescription("behaviors", '')) def updateBehavior(self, **kwargs): behavior_name = self.getGeneratedName() short_name = self.getShortName() utility = self.sm.queryUtility(IBehavior, name=behavior_name) if utility: utility.deactivateSearchable() utility.activateSearchable() if 'field_title' in kwargs: utility.title = kwargs.pop('field_title') for k, v in kwargs.items(): setattr(utility, k, v) delattr(generated, short_name) for (name, fti) in self.sm.getUtilitiesFor(IDexterityFTI): if behavior_name in fti.behaviors: modified(fti, DexterityFTIModificationDescription("behaviors", '')) def unregisterBehavior(self): behavior_name = self.getGeneratedName() utility = self.sm.queryUtility(IBehavior, name=behavior_name) if utility is None: return self.cleanupFTI() utility.removeIndex() utility.deactivateSearchable() utility.unregisterInterface() self.sm.unregisterUtility(utility, IBehavior, name=behavior_name) def clean(self): self.data.clear() def add(self, language, value, key): self._fixup() tree = self.data.get(language) if tree is None: tree = self.data[language] = OOBTree() else: # Make sure we update the modification time. self.data[language] = tree update = key in tree tree[key] = value order = self.order.get(language) if order is None: order = self.order[language] = IOBTree() count = self.count[language] = 0 else: if update: pop_value(tree, key) count = self.count[language] + 1 self.count[language] = count order[count] = key def update(self, language, items, clear=False): self._fixup() tree = self.data.setdefault(language, OOBTree()) if clear: tree.clear() # A new tree always uses the newest version. if not tree: version = self.version[language] = 2 else: version = self.version.get(language, 1) order = self.order.setdefault(language, IOBTree()) count = self.count.get(language, 0) if clear: order.clear() count = 0 # Always migrate to newest version. if version == 1: def fix(path): return path.replace(LEGACY_PATH_SEPARATOR, PATH_SEPARATOR) for i in list(order): path = order[i] order[i] = fix(path) for path in list(tree): value = tree.pop(path) tree[fix(path)] = value version = self.version[language] = 2 logger.info( "Taxonomy '%s' upgraded to version %d for language '%s'." % ( self.name, version, language ) ) # Make sure we update the modification time. self.data[language] = tree # The following structure is used to expunge updated entries. inv = {} if not clear: for i, key in order.items(): inv[key] = i seen = set() for key, value in items: if key in seen: logger.warning("Duplicate key entry: %r" % (key, )) seen.add(key) update = key in tree tree[key] = value order[count] = key count += 1 # If we're updating, then we have to pop out the old ordering # information in order to maintain relative ordering of new items. if update: i = inv.get(key) if i is not None: del order[i] self.count[language] = count def translate(self, msgid, mapping=None, context=None, target_language=None, default=None, msgid_plural=None, default_plural=None, number=None): if target_language is None or \ target_language not in self.inverted_data: target_language = str(self.getCurrentLanguage( getattr(context, 'REQUEST') )) if msgid not in self.inverted_data[target_language]: return '' if self.version is not None and self.version.get(target_language) != 2: path_sep = LEGACY_PATH_SEPARATOR else: path_sep = PATH_SEPARATOR path = self.inverted_data[target_language][msgid] pretty_path = path[1:].replace(path_sep, PRETTY_PATH_SEPARATOR) if mapping is not None and mapping.get(NODE): pretty_path = pretty_path.rsplit(PRETTY_PATH_SEPARATOR, 1)[-1] return pretty_path def _fixup(self): # due to compatibility reasons this method fixes data structure # for old Taxonomy instances. # XXX: remove this in version 2.0 to prevent write on read if self.order is None: safeWrite(self, getRequest()) self.order = PersistentDict() self.count = PersistentDict() if self.version is None: safeWrite(self, getRequest()) self.version = PersistentDict()
class HebergementFolder(ATFolder): """ """ security = ClassSecurityInfo() __implements__ = (getattr(ATFolder, '__implements__', ())) # This name appears in the 'add' box archetype_name = 'HebergementFolder' meta_type = 'HebergementFolder' portal_type = 'HebergementFolder' allowed_content_types = [] filter_content_types = 0 global_allow = 1 #content_icon = 'HebergementFolder.gif' immediate_view = 'view' default_view = 'view' suppl_views = () typeDescription = "HebergementFolder" typeDescMsgId = 'description_edit_hebergementfolder' _at_rename_after_creation = True schema = HebergementFolder_schema ##code-section class-header #fill in your manual code here implements(IHebergementFolder, IMappableContent) ##/code-section class-header # Methods # Manually created methods security.declarePrivate('_createUniqueId') def _createUniqueId(self, dupId, idList): cpt = 1 while 1: new_id = "%s-%s" % (dupId, cpt) cpt += 1 if new_id not in idList: id = new_id break return id security.declareProtected("Modify portal content", 'updateHebergement') def updateHebergement(self): portal = getToolByName(self, 'portal_url').getPortalObject() ptool = portal.plone_utils wrapper = getSAWrapper('gites_wallons') Hebergement = wrapper.getMapper('hebergement') session = wrapper.session hebergements = session.query(Hebergement).all() self.known_gites_id = PersistentDict() for hebergement in hebergements: nom = hebergement.heb_nom id = hebergement.heb_id if not id: id = ptool.normalizeString(nom) if id in self.known_gites_id.keys(): id = self._createUniqueId(id, self.known_gites_id.keys()) hebergement.heb_id = id session.add(hebergement) self.known_gites_id[id] = hebergement.heb_pk security.declareProtected("Modify portal content", 'updateType') def updateType(self): portal = getToolByName(self, 'portal_url').getPortalObject() ptool = portal.plone_utils wrapper = getSAWrapper('gites_wallons') TypesHeb = wrapper.getMapper('type_heb') session = wrapper.session typesHebs = session.query(TypesHeb).all() self.known_types_id = PersistentDict() for typeHeb in typesHebs: nom = typeHeb.type_heb_nom pk = typeHeb.type_heb_pk id = typeHeb.type_heb_id if not id: id = ptool.normalizeString(nom) if id in self.known_types_id.keys(): id = self._createUniqueId(id, self.known_types_id.keys()) typeHeb.type_heb_id = id session.add(typeHeb) self.known_types_id[id] = pk nom = typeHeb.type_heb_nom_nl id = typeHeb.type_heb_id_nl if not id: id = ptool.normalizeString(nom) if id in self.known_types_id.keys(): id = self._createUniqueId(id, self.known_types_id.keys()) typeHeb.type_heb_id_nl = id session.add(typeHeb) self.known_types_id[id] = pk nom = typeHeb.type_heb_nom_uk id = typeHeb.type_heb_id_uk if not id: id = ptool.normalizeString(nom) if id in self.known_types_id.keys(): id = self._createUniqueId(id, self.known_types_id.keys()) typeHeb.type_heb_id_uk = id session.add(typeHeb) self.known_types_id[id] = pk id = typeHeb.type_heb_id_de nom = typeHeb.type_heb_nom_de if not id: id = ptool.normalizeString(nom) if id in self.known_types_id.keys(): id = self._createUniqueId(id, self.known_types_id.keys()) typeHeb.type_heb_id_de = id session.add(typeHeb) self.known_types_id[id] = pk nom = typeHeb.type_heb_nom_it id = typeHeb.type_heb_id_it if not id: id = ptool.normalizeString(nom) if id in self.known_types_id.keys(): id = self._createUniqueId(id, self.known_types_id.keys()) typeHeb.type_heb_id_it = id session.add(typeHeb) self.known_types_id[id] = pk security.declareProtected("Modify portal content", 'updateCommune') def updateCommune(self): portal = getToolByName(self, 'portal_url').getPortalObject() ptool = portal.plone_utils wrapper = getSAWrapper('gites_wallons') Commune = wrapper.getMapper('commune') session = wrapper.session communes = session.query(Commune).all() self.known_communes_id = PersistentDict() for commune in communes: nom = commune.com_nom id = commune.com_id if not id: id = ptool.normalizeString(nom) commune.com_id = id session.add(commune) self.known_communes_id[id] = commune.com_pk security.declareProtected("Modify portal content", 'updateHebergement') def update(self, REQUEST=None): """ """ alsoProvides(REQUEST, IDisableCSRFProtection) self.updateHebergement() self.updateCommune() self.updateType() memcache = memcachedClient() memcache.invalidateAll() def view(self, REQUEST): """ default give back a search form """ url = "%s/search_hosting.html" % self.absolute_url() return REQUEST.RESPONSE.redirect(url)
class Page(Persistent): __name__ = None __parent__ = None __children__ = [] title = u'' layout_template = u'' _default_behaviour = config['DEFAULT_PAGE_BEHAVIOUR'] def __init__(self, title): self.title = title self.__name__ = normalise_title(title) self._properties = PersistentDict({}) self._extra_behaviour = PersistentList([]) self._update_properties() ### Behaviour ### @property def behaviour(self): """ Collates the default and user-added behaviour into a list >>> page = Page('test') >>> page.behaviour == list(page._default_behaviour) + list(page._extra_behaviour) True """ return list(self._default_behaviour) + list(self._extra_behaviour) def add_behaviour(self, key, data=None, prefix=''): """ Adds additional behaviour as defined by a Schema object. We can't extend the page with behaviour that isn't provided for in the registry: >>> page = Page('test') >>> page.add_behaviour('test') Traceback (most recent call last): ... InvalidSchema: There is no Schema registered to provide `test` We must add the schema to the registry first: >>> from jingle.schemas import registry, Schema >>> from formencode.validators import UnicodeString >>> class TestSchema(Schema): ... behaviour = 'test' ... title = UnicodeString(default=u'', ... not_empty=True) >>> page.add_behaviour('test') ['page', 'test'] We can also pass some initial data in rather than having to make another call to update(): >>> page2 = Page('test2') >>> page2.update('test', {'title':u'Page 2'}) # doctest: +ELLIPSIS {...} >>> 'test.title' in page2.properties False >>> page2.add_behaviour('test', {'title':u'Page 2'}) # doctest: +ELLIPSIS {...} >>> 'test.title' in page2.properties and page2.properties['test.title'] == u'Page 2' True """ if key not in schemas.registry: raise schemas.InvalidSchema('There is no Schema registered to provide `%s`' % key) elif key not in self.behaviour: self._extra_behaviour.append(key) self._update_properties() if data is not None: return self.update(key, data, prefix) return self.behaviour def remove_behaviour(self, key, remove_properties=False): """ Removes additional behaviour. We can't remove behaviour that isn't there: >>> page = Page('test') >>> page.behaviour == page.remove_behaviour('test') True We also cannot delete default behaviour: >>> page.remove_behaviour('page') Traceback (most recent call last): ... Exception: Cannot remove default behaviour We can delete extra behaviour however: >>> from jingle.schemas import registry, Schema >>> from formencode.validators import UnicodeString >>> class TestSchema(Schema): ... behaviour = 'test' ... title = UnicodeString(default=u'', ... not_empty=True) >>> page.add_behaviour('test') ['page', 'test'] >>> page.remove_behaviour('test') ['page'] This will leave the schema values behind in the properties store in an attempt to userproof data deletion. >>> 'test.title' in page.properties True We can delete these values though: >>> page.remove_behaviour('test', remove_properties=True) ['page'] >>> 'test.title' in page.properties False """ if key in self._extra_behaviour: self._extra_behaviour.remove(key) elif key in self._default_behaviour: raise Exception('Cannot remove default behaviour') if remove_properties: # delete keys and values from the property store for k in self._properties.keys(): if k.startswith('%s.' % key): del self._properties[k] return self.behaviour ### Properties ### def _update_properties(self): for behaviour in self.behaviour: schema = schemas.registry.lookup(behaviour) for field, ob in schema.fields.items(): key = '%s.%s' % (behaviour, field) if key not in self._properties.keys(): self._properties[key] = ob.default @property def properties(self): # really should move this to update events on self.extra_behaviour self._update_properties() return dict(self._properties) def update(self, key, data, prefix=''): if key not in self.behaviour: return dict(self._properties) schema = schemas.registry.lookup(key) formatted = schema.to_python(data, prefix=prefix) for k,v in formatted.items(): self._properties['%s.%s' % (key, k)] = v return dict(self._properties) ### Navigation / Hierarchy ### def add_child(self, child): """ This method will process setting / syncing the __parent__ and children attributes Adding a child page should add a reference to the children attribute: >>> parent = Page('Parent') >>> child = Page('Child') >>> parent.add_child(child) [u'child'] >>> child.__parent__ == parent.__name__ True However, children must be Pages too: >>> parent.add_child(object()) Traceback (most recent call last): ... TypeError: Children must be inherited from the Page class, not <type 'object'> """ if not isinstance(child, Page): raise TypeError('Children must be inherited from the Page class, not %s' % str(type(child))) self.__children__.append(child.__name__) child.__parent__ = self.__name__ return self.__children__
class PlominoDocument(CatalogAware, CMFBTreeFolder, Contained): """ These represent the contents in a Plomino database. A document contains *items*. An item may or may not correspond to fields on one or more forms. They may be manipulated by Formulas. """ security = ClassSecurityInfo() implements(interfaces.IPlominoDocument, IAttributeAnnotatable) portal_type = "PlominoDocument" meta_type = "PlominoDocument" security.declarePublic('__init__') def __init__(self, id): """ Initialization """ CMFBTreeFolder.__init__(self, id) self.id = id self.items = PersistentDict() self.plomino_modification_time = DateTime().toZone(TIMEZONE) security.declarePublic('checkBeforeOpenDocument') def checkBeforeOpenDocument(self): """ Check read permission and open view. .. NOTE:: if ``READ_PERMISSION`` is set on the ``view`` action itself, it causes an error ('maximum recursion depth exceeded') if user hasn't permission. """ if self.isReader(): return self.OpenDocument() else: raise Unauthorized, "You cannot read this content" def doc_path(self): return self.getPhysicalPath() def doc_url(self): """ Return valid and nice url: - hide plomino_documents - use physicalPathToURL if REQUEST available """ path = self.doc_path() short_path = [p for p in path if p != "plomino_documents"] if hasattr(self, "REQUEST"): return self.REQUEST.physicalPathToURL(short_path) else: return "/".join(short_path) security.declarePublic('setItem') def setItem(self, name, value): """ Set item on document, converting str to unicode. """ items = self.items if isinstance(value, str): db = self.getParentDatabase() translation_service = getToolByName(db, 'translation_service') value = translation_service.asunicodetype(value) items[name] = value self.items = items self.plomino_modification_time = DateTime().toZone(TIMEZONE) security.declarePublic('getItem') def getItem(self, name, default=''): """ Get item from document. """ if self.items.has_key(name): return deepcopy(self.items[name]) else: return default security.declarePublic('hasItem') def hasItem(self, name): """ Check if doc has item 'name'. """ return self.items.has_key(name) security.declarePublic('removeItem') def removeItem(self, name): """ Delete item 'name', if it exists. """ if self.items.has_key(name): items = self.items del items[name] self.items = items security.declarePublic('getItems') def getItems(self): """ Return all item names. """ return self.items.keys() security.declarePublic('getItemClassname') def getItemClassname(self, name): """ Return class name of the item. """ return self.getItem(name).__class__.__name__ security.declarePublic('getLastModified') def getLastModified(self, asString=False): """ Return last modified date, setting it if absent. """ if not hasattr(self, 'plomino_modification_time'): self.plomino_modification_time = self.bobobase_modification_time( ).toZone(TIMEZONE) if asString: return DateToString(self.plomino_modification_time, db=self.getParentDatabase()) else: return self.plomino_modification_time security.declarePublic('getRenderedItem') def getRenderedItem(self, itemname, form=None, formid=None, convertattachments=False): """ Return the item rendered according to the corresponding field. The form used can be, in order of precedence: - passed as the `form` parameter, - specified with the `formid` parameter and looked up, - looked up from the document. If no form or field is found, return the empty string. If `convertattachments` is True, then we assume that field attachments are text and append them to the rendered value. """ db = self.getParentDatabase() result = '' if not form: if formid: form = db.getForm(formid) else: form = self.getForm() if form: field = form.getFormField(itemname) if field: result = field.getFieldRender(form, self, False) if (field.getFieldType() == 'ATTACHMENT' and convertattachments): result += ' ' + db.getIndex().convertFileToText( self, itemname).decode('utf-8') result = result.encode('utf-8') return result security.declarePublic('tojson') def tojson(self, REQUEST=None, item=None, formid=None, rendered=False, lastmodified=None): """ Return item value as JSON. Return all items if `item=None`. Values on the REQUEST overrides parameters. If the requested item corresponds to a field on the found form, the field value is returned. If not, it falls back to a plain item lookup on the document. `formid="None"` specifies plain item lookup. """ # TODO: Don't always return the entire dataset: allow batching. if not self.isReader(): raise Unauthorized, "You cannot read this content" datatables_format = False if REQUEST: REQUEST.RESPONSE.setHeader('content-type', 'application/json; charset=utf-8') item = REQUEST.get('item', item) formid = REQUEST.get('formid', formid) lastmodified = REQUEST.get('lastmodified', lastmodified) rendered_str = REQUEST.get('rendered', None) if rendered_str: rendered = True datatables_format_str = REQUEST.get('datatables', None) if datatables_format_str: datatables_format = True if item: if formid == "None": form = None elif formid: form = self.getParentDatabase().getForm(formid) else: form = self.getForm() if form: field = form.getFormField(item) if field: if field.getFieldType() == 'DATAGRID': adapt = field.getSettings() fieldvalue = adapt.getFieldValue(form, doc=self, request=REQUEST) fieldvalue = adapt.rows(fieldvalue, rendered=rendered) else: if rendered: fieldvalue = self.getRenderedItem(item, form) else: adapt = field.getSettings() fieldvalue = adapt.getFieldValue(form, doc=self, request=REQUEST) else: _logger.info("Failed to find %s on %s, " "fallback to getItem." % (item, form.id)) fieldvalue = self.getItem(item) else: fieldvalue = self.getItem(item) data = fieldvalue else: data = self.items.data if datatables_format: data = { 'iTotalRecords': len(data), 'iTotalDisplayRecords': len(data), 'aaData': data } if lastmodified: data = {'lastmodified': self.getLastModified(), 'data': data} return json.dumps(data) security.declarePublic('computeItem') def computeItem(self, itemname, form=None, formid=None, store=True, report=True): """ Return the value of named item according to the formula - of the field defined in the given form (default), - or the named `formid`, - or use the default doc form if no form found. Store the value in the doc (if `store=True`). (Pass `report` to `PlominoForm.computeFieldValue`.) """ result = None if not form: if not formid: form = self.getForm() else: db = self.getParentDatabase() form = db.getForm(formid) if form: result = form.computeFieldValue(itemname, self, report=report) if store: # So this is a way to store the value of a DISPLAY field .. self.setItem(itemname, result) return result security.declarePublic('getPlominoReaders') def getPlominoReaders(self): """ Return list of readers; if none set, everyone can read. """ if self.hasItem('Plomino_Readers'): return asList(self.getItem('Plomino_Readers')) else: return ['*'] security.declarePublic('isReader') def isReader(self): """ """ return self.getParentDatabase().isCurrentUserReader(self) security.declarePublic('isAuthor') def isAuthor(self): """ """ return self.getParentDatabase().isCurrentUserAuthor(self) security.declareProtected(REMOVE_PERMISSION, 'delete') def delete(self, REQUEST=None): """ Delete the current doc; redirect to `returnurl` if available. """ db = self.getParentDatabase() db.deleteDocument(self) if REQUEST: return_url = REQUEST.get('returnurl') if not return_url: return_url = db.absolute_url() REQUEST.RESPONSE.redirect(return_url) security.declareProtected(EDIT_PERMISSION, 'validation_errors') def validation_errors(self, REQUEST): """ Check submitted values. """ db = self.getParentDatabase() form = db.getForm(REQUEST.get('Form')) errors = form.validateInputs(REQUEST, doc=self) if errors: return self.errors_json(errors=json.dumps({ 'success': False, 'errors': errors })) else: return self.errors_json(errors=json.dumps({'success': True})) security.declareProtected(EDIT_PERMISSION, 'saveDocument') def saveDocument(self, REQUEST, creation=False): """ Save a document using the form submitted content """ db = self.getParentDatabase() form = db.getForm(REQUEST.get('Form')) errors = form.validateInputs(REQUEST, doc=self) # execute the beforeSave code of the form error = None try: error = self.runFormulaScript( SCRIPT_ID_DELIMITER.join(['form', form.id, 'beforesave']), self, form.getBeforeSaveDocument) except PlominoScriptException, e: e.reportError('Form submitted, but beforeSave formula failed') if error: errors.append(error) # if errors, stop here, and notify errors to user if errors: return form.notifyErrors(errors) self.setItem('Form', form.getFormName()) # process editable fields (we read the submitted value in the request) form.readInputs(self, REQUEST, process_attachments=True) # refresh computed values, run onSave, reindex self.save(form, creation) redirect = REQUEST.get('plominoredirecturl') if not redirect: redirect = self.getItem("plominoredirecturl") if type(redirect) is dict: # if dict, we assume it contains "callback" as an URL that will be # called asynchronously, "redirect" as the redirect url (optional, # default=doc url), and "method" (optional, default=GET) redirect = "./async_callback?" + urlencode(redirect) if not redirect: redirect = self.absolute_url() REQUEST.RESPONSE.redirect(redirect)
class RoleProtectedObject(Persistent, Contained): """Base class for object protected by roles""" inherit_parent_security = FieldProperty( IRoleProtectedObject['inherit_parent_security']) everyone_denied = FieldProperty(IRoleProtectedObject['everyone_denied']) everyone_granted = FieldProperty(IRoleProtectedObject['everyone_granted']) authenticated_denied = FieldProperty( IRoleProtectedObject['authenticated_denied']) authenticated_granted = FieldProperty( IRoleProtectedObject['authenticated_granted']) inherit_parent_roles = FieldProperty( IRoleProtectedObject['inherit_parent_roles']) def __init__(self): self._principals_by_role = PersistentDict() self._roles_by_principal = PersistentDict() def get_everyone_denied(self): """Get permissions denied to everyone""" permissions = self.everyone_denied or set() if self.inherit_parent_security: for parent in lineage(self): if parent in (self, self.__parent__): continue protection = IProtectedObject(parent, None) if protection is not None: permissions = permissions | (protection.everyone_denied or set()) return permissions def get_everyone_granted(self): """Get permissions granted to everyone""" permissions = self.everyone_granted or set() if self.inherit_parent_security: for parent in lineage(self): if parent in (self, self.__parent__): continue protection = IProtectedObject(parent, None) if protection is not None: permissions = permissions | (protection.everyone_granted or set()) return permissions def get_authenticated_denied(self): """Get permissions denied to authenticated users""" permissions = self.authenticated_denied or set() if self.inherit_parent_security: for parent in lineage(self): if parent in (self, self.__parent__): continue protection = IProtectedObject(parent, None) if protection is not None: permissions = permissions | ( protection.authenticated_denied or set()) return permissions def get_authenticated_granted(self): """Get permissions granted to authenticated users""" permissions = self.authenticated_granted or set() if self.inherit_parent_security: for parent in lineage(self): if parent in (self, self.__parent__): continue protection = IProtectedObject(parent, None) if protection is not None: permissions = permissions | ( protection.authenticated_granted or set()) return permissions def grant_role(self, role_id, principal_ids): """Grant role to selected principals""" registry = get_pyramid_registry() if IRole.providedBy(role_id): role_id = role_id.id if isinstance(principal_ids, str): principal_ids = {principal_ids} role_principals = self._principals_by_role.get(role_id) or set() for principal_id in principal_ids: if IPrincipalInfo.providedBy(principal_id): principal_id = principal_id.id if principal_id not in role_principals: principal_roles = self._roles_by_principal.get( principal_id) or set() role_principals.add(principal_id) principal_roles.add(role_id) self._roles_by_principal[principal_id] = principal_roles self._principals_by_role[role_id] = role_principals registry.notify(GrantedRoleEvent(self, role_id, principal_id)) def revoke_role(self, role_id, principal_ids): """Revoke role to selected principals""" registry = get_pyramid_registry() if IRole.providedBy(role_id): role_id = role_id.id if isinstance(principal_ids, str): principal_ids = {principal_ids} role_principals = self._principals_by_role.get(role_id) or set() for principal_id in principal_ids.copy(): if IPrincipalInfo.providedBy(principal_id): principal_id = principal_id.id if principal_id in role_principals: principal_roles = self._roles_by_principal.get( principal_id) or set() if principal_id in role_principals: role_principals.remove(principal_id) if role_id in principal_roles: principal_roles.remove(role_id) if principal_roles: self._roles_by_principal[principal_id] = principal_roles elif principal_id in self._roles_by_principal: del self._roles_by_principal[principal_id] if role_principals: self._principals_by_role[role_id] = role_principals elif role_id in self._principals_by_role: del self._principals_by_role[role_id] registry.notify(RevokedRoleEvent(self, role_id, principal_id)) def get_principals(self, role_id): """Get principals which have selected role granted""" if IRole.providedBy(role_id): role_id = role_id.id return self._principals_by_role.get(role_id) or set() def get_roles(self, principal_id): """Get roles for given principal""" if IPrincipalInfo.providedBy(principal_id): principal_id = principal_id.id return self._roles_by_principal.get(principal_id) or set() def get_permissions(self, principal_id): """Get permissions for given principal""" registry = get_pyramid_registry() result = set() for role_id in self.get_roles(principal_id): role = registry.queryUtility(IRole, role_id) result |= role.permissions or set() return result def get_granted_roles(self): """Get granted roles on current context or parents""" roles = set(self._principals_by_role.keys()) if self.inherit_parent_roles: for parent in lineage(self): if parent in (self, self.__parent__): continue protection = IProtectedObject(parent, None) if protection is not None: roles = roles | protection.get_granted_roles() return roles @request_property(key=None) def __acl__(self): """Get ACL for current context The result is stored into current request annotations, so it's not supposed to change during request lifetime. """ # always grant all permissions to system manager # and 'public' permission to everyone result = [(Allow, ADMIN_USER_ID, ALL_PERMISSIONS), (Allow, Everyone, {PUBLIC_PERMISSION})] # grant access to all roles permissions for role_id in self.get_granted_roles(): role = query_utility(IRole, role_id) if role is not None: result.append( (Allow, ROLE_ID.format(role_id), role.permissions)) # add denied permissions to everyone and authenticated permissions = self.get_everyone_denied() if permissions: result.append((Deny, Everyone, permissions)) permissions = self.get_authenticated_denied() if permissions: result.append((Deny, Authenticated, permissions)) # add allowed permissions to everyone and authenticated permissions = self.get_authenticated_granted() if permissions: result.append((Allow, Authenticated, permissions)) permissions = self.get_everyone_granted() if permissions: result.append((Allow, Everyone, permissions)) # deny all parent permissions if inheritance is disabled if not self.inherit_parent_security: result.append(DENY_ALL) LOGGER.debug('ACL({0!r}) = {1}'.format(self.__parent__, str(result))) return result
class VideoContainer(PersistentMapping): """ A simple container for Video objects >>> from mint.repoze.interfaces import IVideoContainer >>> from mint.repoze.models import VideoContainer, Video >>> ob = VideoContainer() >>> IVideoContainer.providedBy(ob) True >>> len(ob) 0 >>> ob[u'vid1'] = Video('vid1', 'Video 1', 'description', []) >>> len(ob) 1 >>> ob.keys() [u'vid1'] """ __acl__ = [ (Allow, Everyone, 'view'), (Allow, 'admin', 'add'), (Allow, 'admin', 'edit'), ] implements(IVideoContainer,ILocation) encode_dir = 'var/videos/' def __init__(self, *args, **kwargs): self.data = PersistentDict() for data in args: self.add_video(*data) for v in kwargs.values(): pass def __getitem__(self, key): return self.data.__getitem__(key) def __setitem__(self, key, value): return self.data.__setitem__(key, value) def items(self): return self.data.items() def keys(self): return self.data.keys() def values(self): return self.data.values() def __repr__(self): return u'<VideoContainer object>' def add_video(self, name, description, tags, encodes={}): uid = name.lower().replace(' ', '_') counter = 1 while uid in self: uid = '%s_%03d' % (uid, counter) counter += 1 self.data[uid] = Video(uid, name, description, tags, encodes, self.encode_dir) import transaction transaction.commit() def get_videos_by_tag(self, tag): """ Returns a list of video objects with the given tag >>> from mint.repoze.test.data import video_container >>> video_container.get_videos_by_tag('feature') # doctest: +ELLIPSIS [<Video name=...] """ return [video for video in self.data.values() if tag in video.tags]
class RegistrationApproval(PloneBaseTool, UniqueObject, SimpleItem): implements(IRegistrationApproval) id = 'wcc_minisites_registration_approval' meta_type = 'WCC Minisite Approval Tool' toolicon = 'skins/plone_images/site_icon.png' security = ClassSecurityInfo() def __init__(self): self._data = PersistentDict() def is_memberid_allowed(self, key): return not (key in self._data.keys()) def values(self): for x in self._data.values(): if not x.has_key('username'): x['username'] = x['email'] return sorted(self._data.values(), key=(lambda x: x['username'])) def add(self, key, data): if key in self._data.keys(): raise ConflictError(u'User already exist in pending') data['username'] = key self._data[key] = data notify(UserRegisteredEvent(data)) def get(self, key): return self._data[key] def approve(self, key): if key not in self._data.keys(): raise KeyError(key) portal = getSite() registration = getToolByName(self, 'portal_registration') portal_props = getToolByName(self, 'portal_properties') mt = getToolByName(self, 'portal_membership') props = portal_props.site_properties use_email_as_login = props.getProperty('use_email_as_login') data = self._data[key] if use_email_as_login: data['username'] = data['email'] user_id = data['username'] password = registration.generatePassword() request = getRequest() try: registration.addMember(user_id, password, REQUEST=request) except (AttributeError, ValueError), err: logging.exception(err) IStatusMessage(request).addStatusMessage(err, type="error") return # set additional properties using the user schema adapter schema = getUtility(IUserDataSchemaProvider).getSchema() adapter = getAdapter(portal, schema) adapter.context = mt.getMemberById(user_id) for name in getFieldNamesInOrder(schema): if name in data: setattr(adapter, name, data[name]) notify(UserApprovedEvent(data)) del self._data[key]
class Taxonomy(SimpleItem): implements(ITaxonomy) def __init__(self, name, title, default_language): super(Taxonomy, self).__init__(self) self.data = PersistentDict() self.name = name self.title = title self.default_language = default_language def __call__(self, context): request = getattr(context, "REQUEST", None) current_language = self.getCurrentLanguage(request) data = self.data[current_language] inverted_data = self.inverted_data[current_language] return Vocabulary(self.name, data, inverted_data) @property @ram.cache(lambda method, self: (self.name, self.data._p_mtime)) def inverted_data(self): inv_data = {} for (language, elements) in self.data.items(): inv_data[language] = {} for (path, identifier) in elements.items(): inv_data[language][identifier] = path return inv_data def getShortName(self): return self.name.split('.')[-1] def getGeneratedName(self): return 'collective.taxonomy.generated.' + self.getShortName() def getVocabularyName(self): return 'collective.taxonomy.' + self.getShortName() def getCurrentLanguage(self, request): try: portal_state = getMultiAdapter((self, request), name=u'plone_portal_state') language = portal_state.language().split('-', 1)[0] except ComponentLookupError: language = '' # Force to return default language. if language in self.data: return language elif self.default_language in self.data: return self.default_language else: # our best guess! return self.data.keys()[0] def registerBehavior(self, **kwargs): context = getSite() sm = context.getSiteManager() new_args = copy(kwargs) new_args['name'] = self.name new_args['title'] = self.title new_args['description'] = kwargs['field_description'] behavior = TaxonomyBehavior(**new_args) sm.registerUtility(behavior, IBehavior, name=self.getGeneratedName()) behavior.addIndex() behavior.activateSearchable() def cleanupFTI(self): """Cleanup the FTIs""" generated_name = self.getGeneratedName() context = getSite() sm = context.getSiteManager() for (name, fti) in sm.getUtilitiesFor(IDexterityFTI): if generated_name in fti.behaviors: fti.behaviors = [ behavior for behavior in fti.behaviors if behavior != generated_name ] modified(fti, DexterityFTIModificationDescription("behaviors", '')) def updateBehavior(self, **kwargs): sm = getSite().getSiteManager() behavior_name = self.getGeneratedName() short_name = self.getShortName() utility = sm.queryUtility(IBehavior, name=behavior_name) if utility: utility.deactivateSearchable() utility.activateSearchable() delattr(generated, short_name) for (name, fti) in sm.getUtilitiesFor(IDexterityFTI): if behavior_name in fti.behaviors: modified(fti, DexterityFTIModificationDescription("behaviors", '')) def unregisterBehavior(self): context = getSite() sm = context.getSiteManager() behavior_name = self.getGeneratedName() utility = sm.queryUtility(IBehavior, name=behavior_name) if utility is None: return self.cleanupFTI() utility.removeIndex() utility.deactivateSearchable() utility.unregisterInterface() sm.unregisterUtility(utility, IBehavior, name=behavior_name) def clean(self): self.data.clear() def add(self, language, identifier, path): if not language in self.data: self.data[language] = OOBTree() self.data[language][path] = identifier def translate(self, msgid, mapping=None, context=None, target_language=None, default=None): if target_language is None or \ target_language not in self.inverted_data: target_language = str( self.getCurrentLanguage(getattr(context, 'REQUEST'))) if msgid not in self.inverted_data[target_language]: return '' path = self.inverted_data[target_language][msgid] #we may have non-ascii now if not isinstance(path, unicode): path = path.decode('utf-8') pretty_path = path[1:].replace('/', u' ยป ') return pretty_path