def _process_value(value): """Convert the value into a human readable diff string """ if not value: value = _("Not set") # handle strings elif isinstance(value, basestring): # XXX: bad data, e.g. in AS Method field if value == "None": value = _("Not set") # 0 is detected as the portal UID elif value == "0": value = "0" # handle physical paths elif value.startswith("/"): # remove the portal path to reduce noise in virtual hostings portal_path = api.get_path(api.get_portal()) value = value.replace(portal_path, "", 1) elif api.is_uid(value): value = _get_title_or_id_from_uid(value) # handle dictionaries elif isinstance(value, (dict)): value = json.dumps(sorted(value.items()), indent=1) # handle lists and tuples elif isinstance(value, (list, tuple)): value = sorted(map(_process_value, value)) value = "; ".join(value) # handle unicodes if isinstance(value, unicode): value = api.safe_unicode(value).encode("utf8") return str(value)
def resolve_query_for_shareable(portal_type, context=None): """Resolves a query filter for the portal_type passed in and the context for which the query has to be filtered by """ # Resolve the client from the object, if possible client = context and get_client_from_chain(context) or None if client and is_internal_client(client): # Client is internal and the portal type is "shareable", the query # must display all items of this portal_type that are located # inside any of the clients from "internal_clients" folder folder = api.get_portal().internal_clients return { "path": { "query": api.get_path(folder), "depth": 2 }, "portal_type": portal_type, } elif client: # Client is external. Only the items that belong to this client return { "path": { "query": api.get_path(client), "depth": 1 }, "portal_type": portal_type, } # We don't know neither the client nor the type of client return {"portal_type": portal_type}
def before_render(self): # Additional columns self.add_columns() # Remove unnecessary columns self.hide_columns() # Apply client filter, if necessary client = api.get_current_client() if client: query = dict(getClientUID=api.get_uid(client)) self.listing.contentFilter.update(query) for rv in self.listing.review_states: if "contentFilter" not in rv: rv["contentFilter"] = {} rv["contentFilter"].update(query) # Render the Add button self.listing.context_actions = {} batches = api.get_portal().batches if security.check_permission(AddBatch, batches): url = api.get_url(batches) self.listing.context_actions = { _("Add"): { "url": "{}/createObject?type_name=Batch".format(url), "icon": "++resource++bika.lims.images/add.png" } }
def before_render(self): # Additional columns self.add_columns() # Remove unnecessary columns self.hide_columns() # Apply client filter, if necessary client = api.get_current_client() if client: query = dict(getClientUID=api.get_uid(client)) self.listing.contentFilter.update(query) for rv in self.listing.review_states: if "contentFilter" not in rv: rv["contentFilter"] = {} rv["contentFilter"].update(query) # Render the Add button self.listing.context_actions = {} batches = api.get_portal().batches if security.check_permission(AddBatch, batches): url = api.get_url(batches) self.listing.context_actions = { _("Add"): { "url": "{}/createObject?type_name=Batch".format(url), "icon": "++resource++bika.lims.images/add.png"} }
def is_external_client(client): """Returns whether the client passed is an external client """ if not IClient.providedBy(client): raise TypeError("Type not supported") return api.get_parent(client) == api.get_portal().clients
def update(self): """Called before the listings renders """ super(PatientsView, self).update() # Render the Add button. We need to do this here because patients live # inside site.patients folder self.context_actions = {} patients = api.get_portal().patients if security.check_permission(AddPatient, patients): self.context_actions = { _("Add"): { "url": "createObject?type_name=Patient", "icon": "++resource++bika.lims.images/add.png" } } # If the current user is a client contact, display those patients that # belong to same client or that do not belong to any client client = api.get_current_client() if client: query = dict(client_uid=[api.get_uid(client), "-1"]) # We add UID "-1" to also include Patients w/o Client assigned self.contentFilter.update(query) for rv in self.review_states: rv["contentFilter"].update(query) # If the current context is a Client, remove the title column if IClient.providedBy(self.context): self.remove_column('getPrimaryReferrerTitle')
def add_action_task(brain_object_uid, action, context=None, **kwargs): """Adds an action-type task to the queue for async processing. :param brain_object_uid: object(s) to perform the action against :param action: action to be performed :param context: context where the action takes place :param kwargs: optional arguments that ``add_task`` takes. :return: the task added to the queue :rtype: senaite.queue.queue.QueueTask """ if not isinstance(brain_object_uid, (list, tuple)): brain_object_uid = [brain_object_uid] # Remove empties and duplicates while keeping the order uids = filter(None, map(_api.get_uid, brain_object_uid)) uids = list(OrderedDict.fromkeys(uids)) if not uids: return None context = context or _api.get_portal() # Special case for "assign" action if action == "assign" and IWorksheet.providedBy(context): return add_assign_task(context, analyses=uids) name = "task_action_{}".format(action) kwargs.update({ "action": action, "uids": uids, }) return add_task(name, context, **kwargs)
def is_creation_allowed(portal_type, container): """Checks if it is allowed to create the portal type :param portal_type: The portal type requested :type portal_type: string :container container: The parent of the object to be created :returns: True if it is allowed to create this object :rtype: bool """ # Do not allow the creation of objects directly inside portal root if container == api.get_portal(): return False # Do not allow the creation of objects directly inside setup folder if container == api.get_setup(): return False # Check if the portal_type is allowed in the container container_info = container.getTypeInfo() if container_info.filter_content_types: if portal_type not in container_info.allowed_content_types: return False # Look for a create-specific adapter for this portal type and container adapter = queryAdapter(container, ICreate, name=portal_type) if adapter: return adapter.is_creation_allowed() return True
def process_form(self, instance, field, form, empty_marker=None, emptyReturnsMarker=False, validating=True): value = form.get(field.getName()) # Allow non-required fields if not value: return None, {} # Is this Identifier temporary? true_values = ("true", "1", "on", "True", True, 1) temporary = value.get("temporary", False) in true_values # The ID might need to be auto-generated if temporary? autogenerated = value.get("autogenerated", "") identifier = value.get("value") or None if temporary and identifier in [None, AUTO_ID_MARKER]: kwargs = {"portal_type": field.getName()} identifier = generateUniqueId(api.get_portal(), **kwargs) autogenerated = identifier value = { "temporary": temporary, "value": identifier, "value_auto": autogenerated, } return value, {}
def __call__(self): protect.CheckAuthenticator(self.request.form) self.portal = api.get_portal() self.request.set('disable_plone.rightcolumn', 1) self.request.set('disable_border', 1) # Handle form submit form = self.request.form submitted = form.get("submitted", False) # nothing to do here if not submitted: return self.template() # Handle "Seed" action if form.get("seed", False): seeds = form.get("seeds", {}) for key, value in seeds.items(): value = api.to_int(value, None) message = "" if value is None: message = _( "Could not convert '{}' to an integer".format(value)) elif value == 0: del self.storage[key] message = _("Removed key {} from storage".format(key)) else: self.set_seed(key, value) message = _("Seeding key {} to {}".format(key, value)) self.add_status_message(message, "info") return self.template()
def update(self): """Called before the listings renders """ super(PatientsView, self).update() # Render the Add button. We need to do this here because patients live # inside site.patients folder self.context_actions = {} patients = api.get_portal().patients if security.check_permission(AddPatient, patients): self.context_actions = { _("Add"): { "url": "createObject?type_name=Patient", "icon": "++resource++bika.lims.images/add.png"} } # If the current user is a client contact, display those patients that # belong to same client or that do not belong to any client client = api.get_current_client() if client: query = dict(client_uid=[api.get_uid(client), "-1"]) # We add UID "-1" to also include Patients w/o Client assigned self.contentFilter.update(query) for rv in self.review_states: rv["contentFilter"].update(query) # If the current context is a Client, remove the title column if IClient.providedBy(self.context): self.remove_column('getPrimaryReferrerTitle')
def get_task_url(task): """Returns the canonical url of the task """ return "/".join([ capi.get_url(capi.get_portal()), "@@API/senaite/v1/queue_server", task.task_uid ])
def get_user_properties(self): """Return the properties of the User """ user = self.context.getUser() # No User linked, nothing to do if user is None: return {} out = {} plone_user = user.getUser() userid = plone_user.getId() for sheet in plone_user.listPropertysheets(): ps = plone_user.getPropertysheet(sheet) out.update(dict(ps.propertyItems())) portal = api.get_portal() mtool = getToolByName(self.context, 'portal_membership') out["id"] = userid out["portrait"] = mtool.getPersonalPortrait(id=userid) out["edit_url"] = "{}/@@user-information?userid={}".format( portal.absolute_url(), userid) return out
def __call__(self): client = self.context.getClient() if not client: # Patient from the laboratory (no client assigned) base_folder = api.get_portal().analysisrequests elif is_internal_client(client): # Patient from an internal client, shared base_folder = api.get_portal().analysisrequests else: # Patient from an external client, private base_folder = client url = "{}/{}".format(api.get_url(base_folder), "ar_add") url = "{}?Patient={}".format(url, api.get_uid(self.context)) qs = self.request.getHeader("query_string") if qs: url = "{}&{}".format(url, qs) return self.request.response.redirect(url)
def get_portal_type_title(self, obj): """Returns the title of the portal type of the obj passed-in """ portal = api.get_portal() portal_type = api.get_portal_type(obj) portal_type = portal.portal_types.getTypeInfo(portal_type) if portal_type: return portal_type.title return None
def __call__(self): url = api.get_url(api.get_portal()) current_user = api.get_current_user() contact = api.get_user_contact(current_user) if contact: parent = api.get_parent(contact) url = api.get_url(parent) return self.request.response.redirect(url)
def afterUpgradeStepHandler(event): """Event handler that is executed after running an upgrade step of senaite.core """ if not is_installed(): return logger.info("Run senaite.databox.afterUpgradeStepHandler ...") portal = get_portal() setup_navigation_types(portal) logger.info("Run senaite.databox.afterUpgradeStepHandler [DONE]")
def get_resource_url(self, name, prefix=""): """Return the full resouce URL """ portal = api.get_portal() portal_url = portal.absolute_url() if not prefix: return "{}/{}".format(portal_url, name) return "{}/++resource++{}/{}".format(portal_url, prefix, name)
def __call__(self, action, uids): """Removes the selected tasks and redirects to the previous URL """ queue = qapi.get_queue() map(queue.delete, uids) url = api.get_url(api.get_portal()) url = "{}/queue_tasks".format(url) return self.redirect(url)
def __init__(self, context, request): self.destination_url = "" self.context = context self.request = request self.back_url = self.context.absolute_url() # Save context UID for benefit of event subscribers. self.request['context_uid'] = hasattr(self.context, 'UID') and \ self.context.UID() or '' self.portal = api.get_portal() self.addPortalMessage = self.context.plone_utils.addPortalMessage
def rename_bika_setup(): """ Rename Bika Setup to just Setup to avoid naming confusions for new users """ logger.info("Renaming Bika Setup...") bika_setup = api.get_bika_setup() bika_setup.setTitle("Setup") bika_setup.reindexObject() setup = api.get_portal().portal_setup setup.runImportStepFromProfile('profile-bika.lims:default', 'controlpanel')
def post_install(context): """Post install script""" # Do something at the end of the installation of this package. nallims = api.get_portal() #Change 'Batches' folder title to 'SDGs' nallims.batches.title = "SDGs" #Change 'Batch Labels' folder to 'SDG Labels' nallims.bika_setup.bika_batchlabels.title = "SDG Labels" #Change 'Sample Points' folder to 'Sample Locations' nallims.bika_setup.bika_samplepoints.title = "Sample Locations"
def uninstall(context): """Uninstall script""" #Do something at the end of the uninstallation of this package. nallims = api.get_portal() #Revert 'Batches' folder to default senaite title nallims.batches.title = "Batches" #Revert 'Batch Labels' folder to default senaite title nallims.bika_setup.bika_batchlabels.title = "Batch Labels" #Revert 'Sample Locations' folder to 'Sample Points' nallims.bika_setup.bika_samplepoints.title = "Sample Points"
def get_image(name, **kwargs): """Returns a well-formed image :param name: file name of the image :param kwargs: additional attributes and values :return: a well-formed html img """ if not name: return "" portal_url = api.get_url(api.get_portal()) attr = render_html_attributes(**kwargs) html = '<img src="{}/++resource++senaite.panic.static/img/{}" {}/>' return html.format(portal_url, name, attr)
def __call__(self): base_folder = self.context.getPrimaryReferrer() if not base_folder: # Doctor w/o client assigned, just use analysisrequests folder base_folder = api.get_portal().analysisrequests url = "{}/{}".format(api.get_url(base_folder), "ar_add") url = "{}?Doctor={}".format(url, api.get_uid(self.context)) qs = self.request.getHeader("query_string") if qs: url = "{}&{}".format(url, qs) return self.request.response.redirect(url)
def __call__(self, action, uids): """Re-queues the selected tasks and redirects to the previous URL """ queue = qapi.get_queue() for uid in uids: task = queue.get_task(uid) task.retries = get_max_retries() queue.delete(uid) queue.add(task) url = api.get_url(api.get_portal()) url = "{}/queue_tasks".format(url) return self.redirect(url)
def available(self): """Control availability of the viewlet """ url = api.get_url(self.context) # render on the portal root if self.context == api.get_portal(): return True # render on the front-page if url.endswith("/front-page"): return True # render for manage_results if url.endswith("/manage_results"): return True return False
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 setUp(self): super(test_FormattedResult, self).setUp() portal = get_portal() bika_setup = get_bika_setup() login(self.portal, TEST_USER_NAME) self.client = self.addthing( portal.clients, 'Client', title='Happy Hills', ClientID='HH') self.contact = self.addthing( self.client, 'Contact', Firstname='Rita', Lastname='Mohale') self.sampletype = self.addthing( bika_setup.bika_sampletypes, 'SampleType', Prefix='H2O') self.service = self.addthing( bika_setup.bika_analysisservices, 'AnalysisService', title='Calcium', Keyword='Ca') transaction.commit()
def to_localized_time(self, date, **kw): """Converts the given date to a localized time string """ if date is None: return "" # default options options = { "long_format": True, "time_only": False, "context": api.get_portal(), "request": api.get_request(), "domain": "senaite.core", } options.update(kw) return ulocalized_time(date, **options)
def update_worksheet_manage_permissions(senaite_setup): """Updates the permissions 'Manage Worksheets' and 'Edit Worksheet' based on the setting 'RestrictWorksheetManagement' from Setup """ roles = ["LabManager", "Manager"] if not senaite_setup.getRestrictWorksheetManagement(): # LabManagers, Analysts and LabClerks can create and manage worksheets roles.extend(["Analyst", "LabClerk"]) worksheets = api.get_portal().worksheets worksheets.manage_permission(permissions.ManageWorksheets, roles, acquire=1) worksheets.manage_permission(permissions.EditWorksheet, roles, acquire=1) worksheets.reindexObject()
def create_empty_patient(): """Create a new empty patient in the patients folder """ tid = tmpID() portal = api.get_portal() container = portal.patients portal_type = "Patient" portal_types = api.get_tool("portal_types") fti = portal_types.getTypeInfo(portal_type) factory = getUtility(IFactory, fti.factory) obj = factory(tid) obj._setPortalTypeName(fti.getId()) notify(ObjectCreatedEvent(obj)) container._setObject(tid, obj) patient = container.get(obj.getId()) return patient
def __call__(self): protect.CheckAuthenticator(self.request.form) self.portal = api.get_portal() self.request.set('disable_plone.rightcolumn', 1) self.request.set('disable_border', 1) # Handle form submit form = self.request.form submitted = form.get("submitted", False) # nothing to do here if not submitted: return self.template() # Handle "Seed" action if form.get("seed", False): seeds = form.get("seeds", {}) for key, value in seeds.items(): value = self.to_int(value) message = "" if value == 0: del self.storage[key] message = _("Removed key {} from storage".format(key)) else: self.set_seed(key, value) message = _("Seeding key {} to {}".format(key, value)) self.add_status_message(message, "info") # Handle "Flush" action if form.get("flush", False): message = _("Flushed Number Storage") self.add_status_message(message, "warning") self.flush() return self.template() return self.template()
def get_resource_url(resource, route="++resource++bika.health.images"): """Returns the url for the given resource name """ portal_url = api.get_url(api.get_portal()) return "{}/{}/{}".format(portal_url, route, resource)
def get_portal(): """Proxy to bika.lims.api.get_portal """ return api.get_portal()