def process_value(self, value): """Process publication value """ # UID -> SuperModel if api.is_uid(value): # Do not process "0" as the portal object # -> Side effect in specifications when the value is "0" if value == "0": return "0" return self.to_super_model(value) # Content -> SuperModel elif api.is_object(value): return self.to_super_model(value) # String -> Unicode elif isinstance(value, basestring): return safe_unicode(value).encode("utf-8") # DateTime -> DateTime elif isinstance(value, DateTime): return value # Process list values elif isinstance(value, (LazyMap, list, tuple)): return map(self.process_value, value) # Process dict values elif isinstance(value, (dict)): return {k: self.process_value(v) for k, v in value.iteritems()} # Process function elif safe_callable(value): return self.process_value(value()) # Always return the unprocessed value last return value
def __init__(self, context, request): super(WorkflowActionHandler, self).__init__(context, request) # TODO This "context_uid" dance is probably no longer necessary self.request["context_uid"] = "" if api.is_object(self.context): self.request["context_uid"] = api.get_uid(self.context)
def to_service_uid(uid_brain_obj_str): """Resolves the passed in element to a valid uid. Returns None if the value cannot be resolved to a valid uid """ if api.is_uid(uid_brain_obj_str) and uid_brain_obj_str != "0": return uid_brain_obj_str if api.is_object(uid_brain_obj_str): obj = api.get_object(uid_brain_obj_str) if IAnalysisService.providedBy(obj): return api.get_uid(obj) elif IRoutineAnalysis.providedBy(obj): return obj.getServiceUID() else: logger.error("Type not supported: {}".format(obj.portal_type)) return None if isinstance(uid_brain_obj_str, six.string_types): # Maybe is a keyword? query = dict(portal_type="AnalysisService", getKeyword=uid_brain_obj_str) brains = api.search(query, SETUP_CATALOG) if len(brains) == 1: return api.get_uid(brains[0]) # Or maybe a title query = dict(portal_type="AnalysisService", title=uid_brain_obj_str) brains = api.search(query, SETUP_CATALOG) if len(brains) == 1: return api.get_uid(brains[0]) return None
def _get_object(context, value): """Resolve a UID to an object. :param context: context is the object containing the field's schema. :type context: BaseContent :param value: A UID. :type value: string :return: Returns a Content object or None. :rtype: BaseContent """ if not value: return None if api.is_brain(value): return api.get_object(value) if api.is_object(value): return value if api.is_uid(value): uc = api.get_tool('uid_catalog', context=context) brains = uc(UID=value) if len(brains) == 0: # Broken Reference! logger.warn("Reference on {} with UID {} is broken!" .format(repr(context), value)) return None return brains[0].getObject() return None
def _to_service(self, thing): """Convert to Analysis Service :param thing: UID/Catalog Brain/Object/Something :returns: Analysis Service object or None """ # Convert UIDs to objects if api.is_uid(thing): thing = api.get_object_by_uid(thing, None) # Bail out if the thing is not a valid object if not api.is_object(thing): logger.warn("'{}' is not a valid object!".format(repr(thing))) return None # Ensure we have an object here and not a brain obj = api.get_object(thing) if IAnalysisService.providedBy(obj): return obj if IAnalysis.providedBy(obj): return obj.getAnalysisService() # An object, but neither an Analysis nor AnalysisService? # This should never happen. msg = "ARAnalysesField doesn't accept objects from {} type. " \ "The object will be dismissed.".format(api.get_portal_type(obj)) logger.warn(msg) return None
def _to_service(self, thing): """Convert to Analysis Service :param thing: UID/Catalog Brain/Object/Something :returns: Analysis Service object or None """ # Convert UIDs to objects if api.is_uid(thing): thing = api.get_object_by_uid(thing, None) # Bail out if the thing is not a valid object if not api.is_object(thing): logger.warn("'{}' is not a valid object!".format(repr(thing))) return None # Ensure we have an object here and not a brain obj = api.get_object(thing) if IAnalysisService.providedBy(obj): return obj if IAnalysis.providedBy(obj): return obj.getAnalysisService() # An object, but neither an Analysis nor AnalysisService? # This should never happen. portal_type = api.get_portal_type(obj) logger.error("ARAnalysesField doesn't accept objects from {} type. " "The object will be dismissed.".format(portal_type)) return None
def can_export(obj): """Decides if the object can be exported or not """ if not api.is_object(obj): return False if api.get_portal_type(obj) in SKIP_TYPES: return False return True
def get_catalog_for(self, brain_or_object): """Return the primary catalog for the given brain or object """ if not api.is_object(brain_or_object): raise TypeError("Invalid object type %r" % brain_or_object) catalogs = api.get_catalogs_for(brain_or_object, default="uid_catalog") return catalogs[0]
def get_obj_url(self, obj): """Returns the absolute url of the object passed-in """ if not api.is_object(obj): # Some objects (e.g. portal_registry) are not supported return obj.absolute_url() return api.get_url(obj)
def to_super_model(self, thing): """Wraps an object into a Super Model """ if api.is_uid(thing): return SuperModel(thing) if not api.is_object(thing): raise TypeError("Expected a portal object, got '{}'".format( type(thing))) return thing
def get_uids(self): """Returns a uids list of the objects this action must be performed against to. If no values for uids param found in the request, returns the uid of the current context """ uids = self.get_uids_from_request() if not uids and api.is_object(self.context): uids = [api.get_uid(self.context)] return uids
def get_json_value(self): """Returns the date as ISO string """ value = self.field.get(self.context) if api.is_object(value): value = api.get_uid(value) elif isinstance(value, list): value = map(api.get_uid, value) else: value = "" return json.dumps(value)
def get_object(self, brain_or_object_or_uid): """Get the full content object. Returns None if the param passed in is not a valid, not a valid object or not found :param brain_or_object_or_uid: UID/Catalog brain/content object :returns: content object """ if api.is_uid(brain_or_object_or_uid): return api.get_object_by_uid(brain_or_object_or_uid, default=None) if api.is_object(brain_or_object_or_uid): return api.get_object(brain_or_object_or_uid) return None
def default(obj): """This function handles unhashable objects """ # Convert `DateTime` objects to ISO8601 format if isinstance(obj, DateTime): obj = obj.ISO8601() # Convert objects and brains to UIDs if api.is_object(obj): obj = api.get_uid(obj) if isinstance(obj, basestring): return obj return str(obj)
def __init__(self, thing): # Type based initializers if isinstance(thing, basestring) and thing == "0": self.init_with_instance(api.get_portal()) elif api.is_uid(thing): self.init_with_uid(thing) elif api.is_brain(thing): self.init_with_brain(thing) elif api.is_object(thing): self.init_with_instance(thing) else: raise TypeError("Can not initialize a SuperModel with '{}'".format( repr(thing)))
def get_breadcrumbs(self): """Generates the breadcrumbs. Items for which current user does not have the View permission granted are omitted """ hierarchy = [] current = self.context while not api.is_portal(current): if api.is_object(current): if check_permission(View, current): hierarchy.append(current) else: # Some objects (e.g. portal_registry) are not supported hierarchy.append(current) current = current.aq_parent hierarchy = reversed(hierarchy) return map(self.to_breadcrumb, hierarchy)
def getResultRange(self, values, uid_keyword_service): if not uid_keyword_service: return None if api.is_object(uid_keyword_service): uid_keyword_service = api.get_uid(uid_keyword_service) key = "keyword" if api.is_uid(uid_keyword_service) and uid_keyword_service != "0": # We always assume a uid of "0" refers to portal key = "uid" # Find out the item for the given uid/keyword from bika.lims.content.analysisspec import ResultsRangeDict value = filter(lambda v: v.get(key) == uid_keyword_service, values) return value and ResultsRangeDict(dict(value[0].items())) or None
def __init__(self, name, request, context, *arg, **kw): super(QueueTask, self).__init__(*arg, **kw) if api.is_uid(context): context_uid = context context_path = kw.get("context_path") if not context_path: raise ValueError("context_path is missing") elif api.is_object(context): context_uid = api.get_uid(context) context_path = api.get_path(context) else: raise TypeError("No valid context object") # Set defaults kw = kw or {} task_uid = str(kw.get("task_uid", tmpID())) uids = map(str, kw.get("uids", [])) created = api.to_float(kw.get("created"), default=time.time()) status = kw.get("status", None) min_sec = api.to_int(kw.get("min_seconds"), default=get_min_seconds()) max_sec = api.to_int(kw.get("max_seconds"), default=get_max_seconds()) priority = api.to_int(kw.get("priority"), default=10) retries = api.to_int(kw.get("retries"), default=get_max_retries()) unique = self._is_true(kw.get("unique", False)) chunks = api.to_int(kw.get("chunk_size"), default=get_chunk_size(name)) username = kw.get("username", self._get_authenticated_user(request)) err_message = kw.get("error_message", None) self.update({ "task_uid": task_uid, "name": name, "context_uid": context_uid, "context_path": context_path, "uids": uids, "created": created, "status": status and str(status) or None, "error_message": err_message and str(err_message) or None, "min_seconds": min_sec, "max_seconds": max_sec, "priority": priority, "retries": retries, "unique": unique, "chunk_size": chunks, "username": str(username), })
def get_obj_title(self, obj): """Returns the title of the object to be displayed as breadcrumb """ if not api.is_object(obj): # Some objects (e.g. portal_registry) are not supported return obj.Title() title = api.get_title(obj) if IClient.providedBy(obj.aq_parent): # Objects from inside Client folder are always stored directly, w/o # subfolders, making it difficult for user to know if what is # looking at is a Sample, a Batch or a Contact. Append the name of # the portal type pt_title = self.get_portal_type_title(obj) if pt_title: title = "{} ({})".format(title, _(pt_title)) return title
def get_contents(brain_or_object): """Lookup folder contents for this object. :param brain_or_object: A single catalog brain or content object :type brain_or_object: ATContentType/DexterityContentType/CatalogBrain :returns: List of contained contents :rtype: list/Products.ZCatalog.Lazy.LazyMap """ # Nothing to do if the object is contentish if not is_folderish(brain_or_object): return [] # Returning objects (not brains) to make sure we do not miss any child. # It may happen when children belong to different catalogs and not # found on 'portal_catalog'. ret = filter(lambda obj: api.is_object(obj), api.get_object(brain_or_object).objectValues()) return ret
def to_super_model(obj): # avoid circular imports from senaite.core.supermodel import SuperModel # Object is already a SuperModel, return immediately if isinstance(obj, SuperModel): return obj # Only portal objects are supported if not api.is_object(obj): return None # Wrap the object into a specific Publication Object Adapter uid = api.get_uid(obj) portal_type = api.get_portal_type(obj) adapter = queryAdapter(uid, ISuperModel, name=portal_type) if adapter is None: return SuperModel(uid) return adapter
def _get_service_uid(self, item): if api.is_uid(item): return item if not api.is_object(item): logger.warn("Not an UID: {}".format(item)) return None obj = api.get_object(item) if IAnalysisService.providedBy(obj): return api.get_uid(obj) if IAnalysis.providedBy(obj) and IRequestAnalysis.providedBy(obj): return obj.getServiceUID() # An object, but neither an Analysis nor AnalysisService? # This should never happen. msg = "ARAnalysesField doesn't accept objects from {} type. " \ "The object will be dismissed." logger.warn(msg.format(api.get_portal_type(obj))) return None
def reindex_content_structure(portal): """Reindex contents generated by Generic Setup """ logger.info("*** Reindex content structure ***") def reindex(obj, recurse=False): # skip catalog tools etc. if api.is_object(obj): obj.reindexObject() if recurse and hasattr(aq_base(obj), "objectValues"): map(reindex, obj.objectValues()) setup = api.get_setup() setupitems = setup.objectValues() rootitems = portal.objectValues() for obj in itertools.chain(setupitems, rootitems): if not api.is_object(obj): continue logger.info("Reindexing {}".format(repr(obj))) reindex(obj)
def _get_object(context, value): """Resolve a UID to an object. :param context: context is the object containing the field's schema. :type context: BaseContent :param value: A UID. :type value: string :return: Returns a Content object or None. :rtype: BaseContent """ if not value: return None if api.is_brain(value): return api.get_object(value) if api.is_object(value): return value if api.is_uid(value): uc = api.get_tool('uid_catalog', context=context) brains = uc(UID=value) assert len(brains) == 1 return brains[0].getObject() return None
def set(self, instance, value, **kwargs): """Set (multi-)references """ value = self.preprocess_value(value) existing_uids = self.get_backreferences_for(instance) if not value and not existing_uids: logger.warning("Field and value is empty!") return if not self.multiValued and len(value) > 1: raise ValueError( "Multiple values given for single valued field {}".format( repr(self))) set_uids = [] for val in value: if api.is_uid(val): set_uids.append(val) elif api.is_object(val): set_uids.append(api.get_uid(val)) else: logger.error("Target has no UID: %s/%s" % (val, value)) sub = filter(lambda uid: uid not in set_uids, existing_uids) add = filter(lambda uid: uid not in existing_uids, set_uids) for uid in set(existing_uids + set_uids): # The object to link target = api.get_object(uid) # Add reference to object if uid in add: __traceback_info__ = (instance, uid, value, existing_uids) self.add_reference(instance, target, **kwargs) # Delete reference to object elif uid in sub: self.del_reference(instance, target, **kwargs)
def reindex(obj, recurse=False): # skip catalog tools etc. if api.is_object(obj): obj.reindexObject() if recurse and hasattr(aq_base(obj), "objectValues"): map(reindex, obj.objectValues())
def can_import(obj): """Decides if the object can be imported or not """ if not api.is_object(obj): return False return True
def get_portal_type(self, obj): """Returns the portal type of the object """ if not api.is_object(obj): return None return api.get_portal_type(obj)