def _set(self, instance, value, **kw): """Set the value of the field """ logger.debug("ATFieldManager::set: value=%r" % value) # check field permission if not self.field.checkPermission("write", instance): raise Unauthorized( "You are not allowed to write the field {}".format(self.name)) # check if field is writable if not self.field.writeable(instance): raise Unauthorized("Field {} is read only.".format(self.name)) # id fields take only strings if self.name == "id": value = str(value) # get the field mutator mutator = self.field.getMutator(instance) # Inspect function and apply *args and **kwargs if possible. mapply(mutator, value, **kw) return True
def extract_fields(self): """Extract the given fieldnames from the object :returns: Schema name/value mapping :rtype: dict """ # get the proper data manager for the object dm = IDataManager(self.context) # filter out ignored fields fieldnames = filter(lambda name: name not in self.ignore, self.keys) # schema mapping out = dict() for fieldname in fieldnames: try: # get the field value with the data manager fieldvalue = dm.json_data(fieldname) # https://github.com/collective/plone.jsonapi.routes/issues/52 # -> skip restricted fields except Unauthorized: logger.debug("Skipping restricted field '%s'" % fieldname) continue except ValueError: logger.debug("Skipping invalid field '%s'" % fieldname) continue out[fieldname] = api.to_json_value(self.context, fieldname, fieldvalue) return out
def get_keyword_query(self, **kw): """Generates a query from the given keywords. Only known indexes make it into the generated query. :returns: Catalog query :rtype: dict """ query = dict() # Only known indexes get observed indexes = self.catalog.get_indexes() # Handle additional keyword parameters for k, v in kw.iteritems(): # handle uid in keywords if k.lower() == "uid": k = "UID" # handle portal_type in keywords if k.lower() == "portal_type": if v: v = _.to_list(v) if k not in indexes: logger.warn("Skipping unknown keyword parameter '%s=%s'" % (k, v)) continue if v is None: logger.warn("Skip None value in kw parameter '%s=%s'" % (k, v)) continue logger.debug("Adding '%s=%s' to query" % (k, v)) query[k] = v return query
def _get(self, instance, **kw): """Get the value of the field """ logger.debug("DexterityFieldManager::get: instance={} field={}".format( instance, self.field)) # TODO: Check security on the field level return self.field.get(instance)
def get_index(self, name): """get an index by name TODO: Combine indexes of relevant catalogs depending on the portal_type which is searched for. """ catalog = self.get_catalog() index = catalog._catalog.getIndex(name) logger.debug("get_index={} of catalog '{}' --> {}".format( name, catalog.__name__, index)) return index
def icon_cache_key(method, self, brain_or_object): """Generates a cache key for the icon lookup Includes the virtual URL to handle multiple HTTP/HTTPS domains Example: http://senaite.local/clients?modified=1512033263370 """ url = api.get_url(brain_or_object) modified = api.get_modification_date(brain_or_object).millis() key = "{}?modified={}".format(url, modified) logger.debug("Generated Cache Key: {}".format(key)) return key
def set(self, instance, value, **kw): """Decodes base64 value and set the file object """ value = str(value).decode("base64") # handle the filename if "filename" not in kw: logger.debug("FielFieldManager::set: No Filename detected " "-> using title or id") kw["filename"] = kw.get("id") or kw.get("title") self._set(instance, value, **kw)
def _get(self, instance, **kw): """Get the value of the field """ logger.debug("ATFieldManager::get: instance={} field={}".format( instance, self.field)) # check the field permission if not self.field.checkPermission("read", instance): raise Unauthorized( "You are not allowed to read the field {}".format(self.name)) # return the field value return self.field.get(instance)
def _set(self, instance, value, **kw): """Set the value of the field """ logger.debug("DexterityFieldManager::set: value=%r" % value) # Check if the field is read only if self.field.readonly: raise Unauthorized("Field is read only") # Validate self.field.validate(value) # TODO: Check security on the field level return self.field.set(instance, value)
def url_for(endpoint, default="senaite.lims.jsonapi.get", **values): """Looks up the API URL for the given endpoint :param endpoint: The name of the registered route (aka endpoint) :type endpoint: string :returns: External URL for this endpoint :rtype: string/None """ try: return router.url_for(endpoint, force_external=True, values=values) except Exception: # XXX plone.jsonapi.core should catch the BuildError of Werkzeug and # throw another error which can be handled here. logger.debug("Could not build API URL for endpoint '%s'. " "No route provider registered?" % endpoint) # build generic API URL return router.url_for(default, force_external=True, values=values)
def set(self, instance, value, **kw): logger.debug( "NamedFileFieldManager::set:File field" "detected ('%r'), base64 decoding value", self.field) data = str(value).decode("base64") filename = kw.get("filename") or kw.get("id") or kw.get("title") contentType = kw.get("mimetype") or kw.get("content_type") if contentType: # create NamedFile with content type information value = self.field._type(data=data, contentType=contentType, filename=filename) else: # create NamedFile w/o content type information # -> will be guessed by the extension of the filename value = self.field._type(data=data, filename=filename) return self.field.set(instance, value)
def get_icon_for(self, brain_or_object): """Get the navigation portlet icon for the brain or object The cache key ensures that the lookup is done only once per domain name """ portal_types = api.get_tool("portal_types") fti = portal_types.getTypeInfo(api.get_portal_type(brain_or_object)) icon = fti.getIcon() if not icon: return "" # Always try to get the big icon for high-res displays icon_big = icon.replace(".png", "_big.png") # fall back to a default icon if the looked up icon does not exist if self.context.restrictedTraverse(icon_big, None) is None: icon_big = None portal_url = api.get_url(api.get_portal()) title = api.get_title(brain_or_object) html_tag = "<img title='{}' src='{}/{}' width='16' />".format( title, portal_url, icon_big or icon) logger.debug("Generated Icon Tag for {}: {}".format( api.get_path(brain_or_object), html_tag)) return html_tag
def update_object_with_data(content, record): """Update the content with the record data :param content: A single folderish catalog brain or content object :type content: ATContentType/DexterityContentType/CatalogBrain :param record: The data to update :type record: dict :returns: The updated content object :rtype: object :raises: APIError, :class:`~plone.jsonapi.routes.exceptions.APIError` """ # ensure we have a full content object content = get_object(content) # get the proper data manager dm = IDataManager(content) if dm is None: fail(400, "Update for this object is not allowed") # Iterate through record items for k, v in record.items(): try: success = dm.set(k, v, **record) except Unauthorized: fail(401, "Not allowed to set the field '%s'" % k) except ValueError, exc: fail(400, str(exc)) if not success: logger.warn("update_object_with_data::skipping key=%r", k) continue logger.debug("update_object_with_data::field %r updated", k)
if not success: logger.warn("update_object_with_data::skipping key=%r", k) continue logger.debug("update_object_with_data::field %r updated", k) # Validate the entire content object invalid = validate_object(content, record) if invalid: fail(400, u.to_json(invalid)) # do a wf transition if record.get("transition", None): t = record.get("transition") logger.debug(">>> Do Transition '%s' for Object %s", t, content.getId()) do_transition_for(content, t) # reindex the object content.reindexObject() return content def validate_object(brain_or_object, data): """Validate the entire object :param brain_or_object: A single catalog brain or content object :type brain_or_object: ATContentType/DexterityContentType/CatalogBrain :param data: The sharing dictionary as returned from the API :type data: dict :returns: invalidity status