예제 #1
0
def get_tasks_summary(tasks, endpoint, complete=False, **kwargs):
    """Returns a dict that represents a summary of a tasks response
    :param tasks: items to be included in the response
    :param endpoint: endpoint from the request
    :param complete: whether to include the full representation of the tasks
    :param kwargs: additional (hashable) params to be included in the message
    :return: dict with the summary and the list of task representations
    """
    tasks = tasks or []
    if not isinstance(tasks, (list, tuple)):
        tasks = [tasks]

    # Get the information dict of each task
    tasks = filter(None, tasks)
    tasks = map(lambda t: get_task_info(t, complete=complete), tasks)

    zeo = get_post_zeo()
    complete_info = complete and " (complete)" or ""
    logger.info("::{}: {} tasks{} [{}]".format(endpoint, len(tasks),
                                               complete_info, zeo))
    info = kwargs or {}
    info.update({
        "count": len(tasks),
        "items": tasks,
        "url": japi.url_for("senaite.queue.{}".format(endpoint)),
        "zeo": zeo,
    })
    return info
예제 #2
0
def get(context, request, catalog_id=None):
    """Returns all registered catalogs if key is None, otherwise try to fetch
    the information about the catalog name passed in
    """
    archetype_tool = api.get_tool("archetype_tool")

    def get_data(catalog):
        portal_types = catalog.getPortalTypes()

        # Bail out portal types not present in this catalog
        pt_catalogs = map(archetype_tool.getCatalogsByType, portal_types)
        pt_catalogs = map(lambda pts: catalog in pts, pt_catalogs)
        pt_catalogs = zip(pt_catalogs, portal_types)
        portal_types = filter(lambda it: it[0], pt_catalogs)

        return {
            "id": catalog.id,
            "indexes": sorted(catalog.indexes()),
            "schema": sorted(catalog.schema()),
            "portal_types": sorted(map(lambda it: it[1], portal_types)),
        }

    if catalog_id:
        # Return the catalog directly
        catalog = api.get_tool(catalog_id)

        # If a catalog name was passed in, return the catalog info directly
        return get_data(catalog)

    # Look for all catalogs
    if not archetype_tool:
        # Default catalog
        catalogs = [api.get_tool("portal_catalog")],
    else:
        catalogs = archetype_tool.getCatalogsInSite()
        catalogs = map(api.get_tool, catalogs)

    # Exclude some catalogs
    skip = ["reference_catalog", "uid_catalog"]
    catalogs = filter(lambda cat: cat.id not in skip, catalogs)

    # Generate the metadata info for catalogs
    records = map(get_data, catalogs)

    # Prepare batch
    size = req.get_batch_size()
    start = req.get_batch_start()
    batch = api.make_batch(records, size, start)

    return {
        "pagesize": batch.get_pagesize(),
        "next": batch.make_next_url(),
        "previous": batch.make_prev_url(),
        "page": batch.get_pagenumber(),
        "pages": batch.get_numpages(),
        "count": batch.get_sequence_length(),
        "items": records,
        "url": api.url_for("senaite.jsonapi.v1.catalogs", key=catalog_id),
    }
예제 #3
0
def logout(context, request):
    """ Logout Route
    """
    logger.info("*** LOGOUT ***")

    acl_users = api.get_tool("acl_users")
    acl_users.logout(request)

    return {"url": api.url_for("senaite.jsonapi.v1.users"), "success": True}
예제 #4
0
def get_user_info(user):
    """Get the user information
    """
    user = api.get_user(user)
    current = api.get_current_user()

    if api.is_anonymous():
        return {
            "username": current.getUserName(),
            "authenticated": False,
            "roles": current.getRoles(),
            "api_url": api.url_for("senaite.jsonapi.v1.users",
                                   username="******"),
        }

    # nothing to do
    if user is None:
        logger.warn("No user found for {}".format(user))
        return None

    # plone user
    pu = user.getUser()

    info = {
        "username": user.getUserName(),
        "roles": user.getRoles(),
        "groups": pu.getGroups(),
        "authenticated": current == user,
        "api_url": api.url_for("senaite.jsonapi.v1.users",
                               username=user.getId()),
    }

    for k, v in api.get_user_properties(user).items():
        if api.is_date(v):
            v = api.to_iso_date(v)
        if not api.is_json_serializable(v):
            logger.warn(
                "User property '{}' is not JSON serializable".format(k))
            continue
        info[k] = v

    return info
예제 #5
0
def get_message_summary(message, endpoint, **kwargs):
    """Returns a dict that represents a summary of a message response
    :param message: message to be included in the response
    :param endpoint: endpoint from the request
    :param kwargs: additional (hashable) params to be included in the message
    :return: dict with the summary of the response
    """
    zeo = get_post_zeo()
    logger.info("::{}: {} [{}]".format(endpoint, message, zeo))
    info = kwargs or {}
    info.update({
        "message": message,
        "url": japi.url_for("senaite.queue.{}".format(endpoint)),
        "zeo": zeo,
    })
    return info
예제 #6
0
def get(context, request, key=None):
    """Return settings by keyword. If key is None, return all settings.
    """
    settings = api.get_settings_by_keyword(key)

    # Prepare batch
    size = req.get_batch_size()
    start = req.get_batch_start()
    batch = api.make_batch(settings, size, start)

    return {
        "pagesize": batch.get_pagesize(),
        "next": batch.make_next_url(),
        "previous": batch.make_prev_url(),
        "page": batch.get_pagenumber(),
        "pages": batch.get_numpages(),
        "count": batch.get_sequence_length(),
        "items": settings,
        "url": api.url_for("senaite.jsonapi.v1.settings", key=key),
    }
예제 #7
0
def get(context, request, key=None):
    """Return all registry items if key is None, otherwise try to fetch the registry key
    """
    registry_records = api.get_registry_records_by_keyword(key)

    # Prepare batch
    size = req.get_batch_size()
    start = req.get_batch_start()
    batch = api.make_batch(registry_records, size, start)

    return {
        "pagesize": batch.get_pagesize(),
        "next": batch.make_next_url(),
        "previous": batch.make_prev_url(),
        "page": batch.get_pagenumber(),
        "pages": batch.get_numpages(),
        "count": batch.get_sequence_length(),
        "items": [registry_records],
        "url": api.url_for("senaite.jsonapi.v1.registry", key=key),
    }
예제 #8
0
def action(context, request, action=None, resource=None, uid=None):
    """Various HTTP POST actions

    Case 1: /<uid>
    -> Return the full object immediately in the root of the JSON API response
    <Senaite-Site>/@@API/senaite/v1/<uid>

    Case 2: /<action>/<uid>
    -> The actions (update, delete) will performed on the object identified by <uid>
    -> The actions (create) will use the <uid> as the parent folder
    <Senaite-Site>/@@API/senaite/v1/<action>/<uid>

    Case 3: <resource>/<action>
    -> The "target" object will be located by a location given in the request body (uid, path, parent_path + id)
    -> The actions (cut, copy, update, delete) will performed on the target object
    -> The actions (create) will use the target object as the container
    <Senaite-Site>/@@API/senaite/v1/<resource>/<action>

    Case 4: <resource>/<action>/<uid>
    -> The actions (cut, copy, update, delete) will performed on the object identified by <uid>
    -> The actions (create) will use the <uid> as the parent folder
    <Senaite-Site>/@@API/senaite/v1/<resource>/<action>
    """

    # Fetch and call the action function of the API
    func_name = "{}_items".format(action)
    action_func = getattr(api, func_name, None)
    if action_func is None:
        api.fail(500, "API has no member named '{}'".format(func_name))

    portal_type = api.resource_to_portal_type(resource)
    items = action_func(portal_type=portal_type, uid=uid)

    return {
        "count": len(items),
        "items": items,
        "url": api.url_for("senaite.jsonapi.v1.action", action=action),
    }
예제 #9
0
def action(context, request, action=None, resource=None, uid=None):
    """Various HTTP POST actions
    """

    # allow to set the method via the header
    if action is None:
        action = request.get_header("HTTP_X_HTTP_METHOD_OVERRIDE",
                                    "CREATE").lower()

    # Fetch and call the action function of the API
    func_name = "{}_items".format(action)
    action_func = getattr(api, func_name, None)
    if action_func is None:
        api.fail(500, "API has no member named '{}'".format(func_name))

    portal_type = api.resource_to_portal_type(resource)
    items = action_func(portal_type=portal_type, uid=uid)

    return {
        "count": len(items),
        "items": items,
        "url": api.url_for("senaite.jsonapi.v1.action", action=action),
    }
예제 #10
0
def get_list_summary(items, endpoint, **kwargs):
    """Returns a dict that represents a summary of a list response
    :param items: items to be included in the response
    :param endpoint: endpoint from the request
    :param kwargs: additional (hashable) params to be included in the message
    :return: dict with the summary and the list of items
    """
    items = items or []
    if not isinstance(items, (list, tuple)):
        items = [items]

    # Remove empties
    items = filter(None, items)

    zeo = get_post_zeo()
    logger.info("::{}: {} items [{}]".format(endpoint, len(items), zeo))
    info = kwargs or {}
    info.update({
        "count": len(items),
        "items": items,
        "url": japi.url_for("senaite.queue.{}".format(endpoint)),
        "zeo": zeo,
    })
    return info