def steps(self): # Default: 3 steps. But if more than one dossier type is addable on # the selected repository folder, display 3 steps and also show the # the dossier step selection step. if IRepositoryFolder.providedBy(self.context) and \ len(allowed_dossier_types_vocabulary(self.context)) > 1: return ( ('accept_choose_method', _(u'step_1', default=u'Step 1')), ('accept_select_repositoryfolder', _(u'step_2', default=u'Step 2')), ('accept_select_dossier_type', _(u'step_3', default=u'Step 3')), ('accept_dossier_add_form', _(u'step_4', default=u'Step 4'))) return ( ('accept_choose_method', _(u'step_1', default=u'Step 1')), ('accept_select_repositoryfolder', _(u'step_2', default=u'Step 2')), ('accept_dossier_add_form', _(u'step_3', default=u'Step 3')))
def available(self): if not self.enabled(): return False if not IRepositoryFolder.providedBy(self.context): return False if self.context.is_leaf_node(): return True return False
def available(self): if not self.enabled(): return False if IDossierMarker.providedBy(self.context): return True if not IRepositoryFolder.providedBy(self.context): return False if self.context.is_leaf_node(): return True return False
def handleSave(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return with ZipFile(data['message'].open(), 'r') as zipfile: try: zipinfo = zipfile.getinfo('message.xml') except KeyError: self.set_form_error( _(u'Invalid message. Missing message.xml'), self.widgets['message']) return xml = zipfile.read(zipinfo) try: message = ech0147t1.CreateFromDocument(xml) except UnrecognizedContentError as e: self.set_form_error( _(u'msg_ech0147_invalid_content', default=u'Invalid content. ${details}', mapping={'details': e.details()}), self.widgets['message']) return if (IRepositoryFolder.providedBy(self.context) and message.content_.documents): self.set_form_error( _(u'This message contains toplevel documents. ' 'It can only be imported within a dossier.'), self.widgets['message']) return if message.content_.documents: for document in message.content_.documents.document: try: create_document(self.context, document, zipfile) except BadRequest as exc: return self._import_error(exc) if message.content_.dossiers: for dossier in message.content_.dossiers.dossier: try: create_dossier( self.context, dossier, zipfile, data['responsible']) except BadRequest as exc: return self._import_error(exc) self.import_successful = True
def handleSave(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return with ZipFile(data['message'].open(), 'r') as zipfile: try: zipinfo = zipfile.getinfo('message.xml') except KeyError: self.set_form_error(_(u'Invalid message. Missing message.xml'), self.widgets['message']) return xml = zipfile.read(zipinfo) try: message = ech0147t1.CreateFromDocument(xml) except UnrecognizedContentError as e: self.set_form_error( _(u'msg_ech0147_invalid_content', default=u'Invalid content. ${details}', mapping={'details': e.details()}), self.widgets['message']) return if (IRepositoryFolder.providedBy(self.context) and message.content_.documents): self.set_form_error( _(u'This message contains toplevel documents. ' 'It can only be imported within a dossier.'), self.widgets['message']) return if message.content_.documents: for document in message.content_.documents.document: try: create_document(self.context, document, zipfile) except BadRequest as exc: return self._import_error(exc) if message.content_.dossiers: for dossier in message.content_.dossiers.dossier: try: create_dossier(self.context, dossier, zipfile, data['responsible']) except BadRequest as exc: return self._import_error(exc) self.import_successful = True
def get_repository_title(self, brain): """Returns the title of the first parental repository folder. """ # The breadcrumb_titles index was removed in favor of 30% performance # improvement while reindexing, thus we now walk up to the # repository folder. obj = brain.getObject() while obj != api.portal.get(): if IRepositoryFolder.providedBy(obj): break else: obj = obj.aq_parent return obj.Title()
def get_new_mapping(self, key, obj): parent = aq_parent(aq_inner(obj)) ann = IAnnotations(parent) if IDossierMarker.providedBy(obj): mapping_base = ann.get(DOSSIER_KEY) elif IRepositoryFolder.providedBy(obj) or IRepositoryRoot.providedBy(obj): mapping_base = ann.get(REPOSITORY_FOLDER_KEY) else: raise Exception("Unknown object type!") if not mapping_base: return None mapping = mapping_base.get(key) return mapping
def get_repository_path(self): """Returns a reverted, path-like list of parental repository folder titles, not including the dossier itself nor the repository root, seperated by slashes. """ titles = [] obj = self.context while not IPloneSiteRoot.providedBy(obj): if IRepositoryFolder.providedBy(obj): titles.append(obj.Title()) obj = aq_parent(aq_inner(obj)) return ' / '.join(titles)
def get_repository_path(self): """Returns a reverted, path-like list of parental repository folder titles, not including the dossier itself nor the repository root, seperated by slashes. """ titles = [] obj = self.context while not IPloneSiteRoot.providedBy(obj): if IRepositoryFolder.providedBy(obj): titles.append(obj.Title()) obj = aq_parent(aq_inner(obj)) return ' / '.join(self.convert_list(titles))
def save_new_prefix(self, action): data, errors = self.extractData() if len(errors) > 0: return obj = self.context parent = aq_parent(aq_inner(obj)) new_prefix = unicode(data['prefix']) old_prefix = IReferenceNumberPrefix(parent).get_number(obj) intids = getUtility(IIntIds) intid = intids.getId(aq_base(obj)) prefix_adapter = IReferenceNumberPrefix(parent) # Check if prefix already allocated prefix_mapping = prefix_adapter.get_prefix_mapping(obj) child_mapping = prefix_adapter.get_child_mapping(obj) if new_prefix in prefix_mapping.values() or \ new_prefix in child_mapping.keys(): raise Exception("This prefix is already allocated!") # Save new prefix in both mappings prefix_mapping[intid] = new_prefix child_mapping[new_prefix] = intid # Drop entry for old prefix from child_mapping if old_prefix in child_mapping: child_mapping.pop(old_prefix) if IRepositoryFolder.providedBy(obj): # Also change the prefix on the repo folder behavior rnp_behavior = IReferenceNumberPrefixBehavior(obj) rnp_behavior.reference_number_prefix = new_prefix obj.reindexObject() IStatusMessage(self.request).addStatusMessage( _(u"Reference Number prefix for '%s' " "changed to '%s'" % (obj.id, new_prefix)), 'info') return self.request.RESPONSE.redirect(self.context.absolute_url())
def _add_descendants(self, descendants): if not descendants: return obj = descendants[0] if IRepositoryFolder.providedBy(obj): uid = obj.UID() if uid in self.positions: pos = self.positions[uid] else: pos = Position(obj) self.positions[uid] = pos pos._add_descendants(descendants[1:]) elif isinstance(obj, Dossier): uid = obj.obj.UID() if uid in self.dossiers: dossier = self.dossiers[uid] else: dossier = obj self.dossiers[uid] = dossier
def is_part_of_repo(self, obj): return IRepositoryRoot.providedBy(obj) or \ IRepositoryFolder.providedBy(obj)
def allowedContentTypes(self): """Return the list of currently permitted FTIs.""" # We have to follow some rules: # 1. If this RepositoryFolder contains another RF, we should not be # able to add other types than RFs. # 2. If we are reaching the maximum depth of repository folders # (Configured in plone.registry), we should not be able to add # any more RFs, but then we should be able to add the other configured # types in any case. If the maximum_repository_depth is set to 0, # we do not have a depth limit. types = self.getDefaultAddableTypes() fti = self.context.getTypeInfo() # Get maximum depth of repository folders registry = queryUtility(IRegistry) proxy = registry.forInterface(IRepositoryFolderRecords) # 0 -> no restriction maximum_depth = getattr(proxy, 'maximum_repository_depth', 0) current_depth = 0 # If we have a maximum depth, we need to know the current depth if maximum_depth > 0: obj = self.context while IRepositoryFolder.providedBy(obj): current_depth += 1 obj = aq_parent(aq_inner(obj)) if IPloneSiteRoot.providedBy(obj): break if maximum_depth <= current_depth: # Depth exceeded # RepositoryFolder not allowed, but any other type types = filter(lambda a: a != fti, types) # Filter content types, if required if not self.context.is_leaf_node(): # only allow same types types = filter(lambda a: a == fti, types) # Finally: remove not enabled resticted content types marker_behavior = 'opengever.dossier.behaviors.restricteddossier.' + \ 'IRestrictedDossier' allowed = self.context.addable_dossier_types \ and self.context.addable_dossier_types or [] def _filterer(fti): if fti.id in allowed: # FTI is enabled in repository folder return True elif getattr(fti, 'behaviors', None) \ and marker_behavior in fti.behaviors: # FTI has marker interface and is not enabled return False else: # Normal type - we don't care return True types = filter(_filterer, types) return types
def allowedContentTypes(self, *args, **kwargs): """ We have to follow some rules: 1. If this RepositoryFolder contains another RF, we should not be able to add other types than RFs. 2. If we are reaching the maximum depth of repository folders (Configured in plone.registry), we should not be able to add any more RFs, but then we should be able to add the other configured types in any case. If the maximum_repository_depth is set to 0, we do not have a depth limit. """ # get the default types types = super( RepositoryFolder, self).allowedContentTypes(*args, **kwargs) # get fti of myself fti = self.portal_types.get(self.portal_type) # get maximum depth of repository folders registry = queryUtility(IRegistry) proxy = registry.forInterface(IRepositoryFolderRecords) # 0 -> no restriction maximum_depth = getattr(proxy, 'maximum_repository_depth', 0) current_depth = 0 # if we have a maximum depth, we need to know the current depth if maximum_depth > 0: obj = self while IRepositoryFolder.providedBy(obj): current_depth += 1 obj = aq_parent(aq_inner(obj)) if IPloneSiteRoot.providedBy(obj): break if maximum_depth <= current_depth: # depth exceeded # RepositoryFolder not allowed, but any other type types = filter(lambda a: a != fti, types) # check if self contains any similar objects contains_similar_objects = False for id, obj in self.contentItems(): if obj.portal_type == self.portal_type: contains_similar_objects = True break # filter content types, if required if contains_similar_objects: # only allow same types types = filter(lambda a: a == fti, types) # finally: remove not enabled resticted content types marker_behavior = 'opengever.dossier.behaviors.restricteddossier.' + \ 'IRestrictedDossier' allowed = self.addable_dossier_types \ and self.addable_dossier_types or [] def _filterer(fti): if fti.id in allowed: # fti is enabled in repository folder return True elif getattr(fti, 'behaviors', None) \ and marker_behavior in fti.behaviors: # fti has marker interface and is not enabled return False else: # normal type - we don't care return True types = filter(_filterer, types) return types