def catalog(self): """Primary registered catalog for the wrapped portal type """ if self._catalog is None: logger.debug("ReportModel::catalog: *Fetch catalog*") archetype_tool = api.get_tool("archetype_tool") portal_type = self.brain.portal_type catalogs = archetype_tool.getCatalogsByType(portal_type) if catalogs is None: logger.warn( "No registered catalog found for portal_type={}".format( portal_type)) return api.get_tool("uid_catalog") self._catalog = catalogs[0] return self._catalog
def import_review_history(self, content, wf_id, review_history, **kw): """Change the workflow state of an object @param content: Content obj which state will be changed @param review_history: Review history of the object @param wf_id: workflow name @param kw: change the values of same name of the state mapping @return: None """ portal_workflow = api.get_tool('portal_workflow') # Might raise IndexError if no workflow is associated to this type for wf_def in portal_workflow.getWorkflowsFor(content): if wf_id == wf_def.getId(): break else: logger.error("%s: Cannot find workflow id %s" % (content, wf_id)) for rh in sorted(review_history, key=lambda k: k['time']): if not self.review_history_imported(content, rh, wf_def): portal_workflow.setStatusOf(wf_id, content, self.to_review_history_format(rh)) wf_def.updateRoleMappingsFor(content) return
def create_object_slug(self, container, data, *args, **kwargs): """Create an content object slug for the given data """ id = data.get("id") portal_type = data.get("portal_type") types_tool = api.get_tool("portal_types") fti = types_tool.getTypeInfo(portal_type) logger.info("Creating {} with ID {} in parent path {}".format( portal_type, id, api.get_path(container))) if fti.product: obj = _createObjectByType(portal_type, container, id) else: # newstyle factory factory = getUtility(IFactory, fti.factory) obj = factory(id, *args, **kwargs) if hasattr(obj, '_setPortalTypeName'): obj._setPortalTypeName(fti.getId()) # notifies ObjectWillBeAddedEvent, ObjectAddedEvent and ContainerModifiedEvent container._setObject(id, obj) # we get the object here with the current object id, as it might be renamed # already by an event handler obj = container._getOb(obj.getId()) return obj
def get_workflow_by_id(self, wfid): """Returns a workflow by ID :returns: DCWorkflowDefinition instance """ wf_tool = api.get_tool("portal_workflow") return wf_tool.getWorkflowById(wfid)
def get_addable_types(): """returns a list portal types (name, title) pairs """ portal_types = api.get_tool("portal_types") types_dict = portal_types.listTypeTitles() addable_types = filter(lambda t: t in types_dict, ADDABLE_TYPES) return map(lambda t: (t, types_dict[t]), sorted(addable_types))
def get_workflow_info_for(self, wf_id): """Return a workflow info object """ wf_tool = api.get_tool("portal_workflow") # `DCWorkflowDefinition` instance workflow = wf_tool.getWorkflowById(wf_id) # the state variable, e.g. review_state state_var = workflow.state_var # tuple of possible transitions transitions = wf_tool.getTransitionsFor(self.instance) # review history tuple, e.g. ({'action': 'publish', ...}, ) history = wf_tool.getHistoryOf(wf_id, self.instance) # reverse the history review_history = history[::-1] # the most current history info current_state = review_history[0] # extracted status id status = current_state[state_var] # `StateDefinition` instance state_definition = workflow.states[status] # status title, e.g. "Published" status_title = state_definition.title # return selected workflow information for the wrapped instance return { "id": wf_id, "status": status, "status_title": status_title, "state_var": state_var, "transitions": transitions, "review_history": review_history, }
def _recover_failed_objects(self): """ Checks for non-updated objects (by filtering null Title) and re-updates them. :return: """ uc = api.get_tool('uid_catalog', self.portal) # Reference objects must be skipped query = Eq('Title', '') & ~ Eq('portal_type', 'Reference') & ~ \ Eq('portal_type', 'ARReport') brains = uc.evalAdvancedQuery(query) total = len(brains) logger.info('*** Recovering {} objects ***'.format(total)) for idx, brain in enumerate(brains): # Check if object has been created during migration uid = brain.UID existing = self.sh.find_unique(LOCAL_UID, uid) if existing is None: continue logger.info('Recovering {0}/{1} : {2} '.format( idx + 1, total, existing[REMOTE_PATH])) # Mark that update failed previously existing['updated'] = '0' self._handle_obj(existing, handle_dependencies=False) obj = brain.getObject() obj.reindexObject() return
def get_workflow_history(self, wfid, reverse=True): """Return the (reversed) review history """ wf_tool = api.get_tool("portal_workflow") history = wf_tool.getHistoryOf(wfid, self.instance) if reverse: return history[::-1] return history
def get_addable_types(): """returns a list portal types (name, title) pairs """ portal_types = api.get_tool("portal_types") portal_properties = api.get_tool("portal_properties") site_properties = portal_properties.site_properties not_searched = site_properties.getProperty("types_not_searched", []) types_dict = portal_types.listTypeTitles() searchable_types = filter(lambda t: t not in not_searched, types_dict) addable_types = filter(lambda t: t not in NOT_ADDABLE_TYPES, searchable_types) return map(lambda t: (t, types_dict[t]), sorted(addable_types))
def get_brain_by_uid(self, uid): """Lookup brain in the UID catalog """ if uid == "0": return api.get_portal() uid_catalog = api.get_tool("uid_catalog") results = uid_catalog({"UID": uid}) if len(results) != 1: raise ValueError("Failed to get brain by UID") return results[0]
def get_search_index_for(catalog): """Returns the search index to query """ searchable_text_index = "SearchableText" listing_searchable_text_index = "listing_searchable_text" if catalog == CATALOG_ANALYSIS_REQUEST_LISTING: tool = api.get_tool(catalog) indexes = tool.indexes() if listing_searchable_text_index in indexes: return listing_searchable_text_index return searchable_text_index
def has_valid_portal_type(item): """ Check if an item can be handled based on its portal type. :return: True if the item can be handled """ if not isinstance(item, dict): return False portal_types = api.get_tool("portal_types").listContentTypes() pt = item.get("portal_type", None) if pt not in portal_types: return False return True
def filter_content_types(content_types): """ :param content_types: :return: """ ret = list() if not content_types: return ret # Get available portal types and make it all lowercase portal_types = api.get_tool("portal_types").listContentTypes() portal_types = [t.lower() for t in portal_types] ret = [t.strip() for t in content_types.split(",") if t] ret = filter(lambda ct, types=portal_types: ct.lower() in types, ret) ret = list(set(ret)) return ret
def review_history_imported(self, obj, review_history, wf_tool=None): """ Check if review History info is already imported for given workflow. :param obj: the object to be checked :param review_history: Review State Dictionary :param wf_tool: Objects Workflow tool. Will be set to 'portal_worklow' if is None. :return: formatted dictionary """ if wf_tool is None: wf_tool = api.get_tool('portal_workflow') state = review_history.get('review_state') current_rh = wf_tool.getInfoFor(obj, 'review_history', '') for rh in current_rh: if rh.get('review_state') == state: return True return False
def is_review_history_imported(obj, review_history, wf_tool=None): """ Check if review History info is already imported for given workflow. :param obj: the object to be checked :param review_history: Review State Dictionary :param wf_tool: Objects Workflow tool. Will be set to 'portal_worklow' if is None. :return: True if the state was found in the current review history """ if wf_tool is None: wf_tool = api.get_tool('portal_workflow') state_variable = wf_tool.variables.getStateVar() state = review_history.get(state_variable) time = DateTime(review_history.get('time')) current_rh = wf_tool.getInfoFor(obj, 'review_history', '') for rh in current_rh: if rh.get(state_variable) == state and time < rh.get('time'): return True return False
def get_brain_by_uid(self, uid): """Lookup brain from the right catalog """ if uid == "0": return api.get_portal() # ensure we have the primary catalog if self._catalog is None: uid_catalog = api.get_tool("uid_catalog") results = uid_catalog({"UID": uid}) if len(results) != 1: raise ValueError("No object found for UID '{}'".format(uid)) brain = results[0] self._catalog = self.get_catalog_for(brain) # Fetch the brain with the primary catalog results = self.catalog({"UID": self.uid}) if not results: raise ValueError("No results found for UID '{}'".format(uid)) if len(results) != 1: raise ValueError( "Found more than one object for UID '{}'".format(uid)) return results[0]
def _create_object_slug(self, container, data, *args, **kwargs): """Create an content object slug for the given data """ id = data.get("id") remote_path = data.get("remote_path") portal_type = data.get("portal_type") types_tool = api.get_tool("portal_types") fti = types_tool.getTypeInfo(portal_type) if not fti: self.skipped.append(remote_path) logger.error("Type Info not found for {}".format(portal_type)) return None logger.debug("Creating {} with ID {} in parent path {}".format( portal_type, id, api.get_path(container))) if fti.product: obj = _createObjectByType(portal_type, container, id) else: # new style factory factory = getUtility(IFactory, fti.factory) obj = factory(id, *args, **kwargs) if hasattr(obj, '_setPortalTypeName'): obj._setPortalTypeName(fti.getId()) # notifies ObjectWillBeAddedEvent, ObjectAddedEvent and # ContainerModifiedEvent container._setObject(id, obj) # we get the object here with the current object id, as it # might be renamed # already by an event handler obj = container._getOb(obj.getId()) # Be sure that Creation Flag is Cleared. if obj.checkCreationFlag(): obj.unmarkCreationFlag() return obj
def get_tool(name, default=_marker): """Proxy to senaite.api.get_tool """ return api.get_tool(name, default)
def get_content_types(self): return api.get_tool("portal_types").listContentTypes()
def get_transitions(self): """Return possible transitions """ wf_tool = api.get_tool("portal_workflow") return wf_tool.getTransitionsFor(self.instance)
def wf_tool(self): return api.get_tool("portal_workflow")