예제 #1
0
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)
예제 #2
0
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}
예제 #3
0
    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"
                }
            }
예제 #4
0
    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"}
            }
예제 #5
0
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
예제 #6
0
    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')
예제 #7
0
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)
예제 #8
0
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
예제 #9
0
    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, {}
예제 #10
0
    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()
예제 #11
0
    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')
예제 #12
0
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
    ])
예제 #13
0
파일: contact.py 프로젝트: nassimcha/sencua
    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
예제 #14
0
    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)
예제 #15
0
 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
예제 #16
0
    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)
예제 #17
0
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]")
예제 #18
0
    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)
예제 #19
0
    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)
예제 #20
0
 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
예제 #21
0
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')
예제 #22
0
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"
예제 #23
0
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"
예제 #24
0
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)
예제 #25
0
    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)
예제 #26
0
    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)
예제 #27
0
 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
예제 #28
0
    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()
예제 #30
0
 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)
예제 #31
0
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()
예제 #32
0
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
예제 #33
0
파일: view.py 프로젝트: bikalabs/bika.lims
    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()
예제 #34
0
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)
예제 #35
0
def get_portal():
    """Proxy to bika.lims.api.get_portal
    """
    return api.get_portal()