Beispiel #1
0
def _fetch_bundles():
    """
    Fetch bundles by bundle specs OR search keywords.
    """
    keywords = query_get_list('keywords')
    specs = query_get_list('specs')
    worksheet_uuid = request.query.get('worksheet')
    descendant_depth = query_get_type(int, 'depth', None)

    if keywords:
        # Handle search keywords
        keywords = resolve_owner_in_keywords(keywords)
        bundle_uuids = local.model.search_bundle_uuids(request.user.user_id,
                                                       worksheet_uuid,
                                                       keywords)
    elif specs:
        # Resolve bundle specs
        bundle_uuids = canonicalize.get_bundle_uuids(local.model, request.user,
                                                     worksheet_uuid, specs)
    else:
        abort(
            httplib.BAD_REQUEST, "Request must include either 'keywords' "
            "or 'specs' query parameter")

    # Find all descendants down to the provided depth
    if descendant_depth is not None:
        bundle_uuids = local.model.get_self_and_descendants(
            bundle_uuids, depth=descendant_depth)

    # Return simple dict if scalar result (e.g. .sum or .count queries)
    if not isinstance(bundle_uuids, list):
        return json_api_meta({}, {'result': bundle_uuids})

    return build_bundles_document(bundle_uuids)
Beispiel #2
0
def interpret_search(query):
    """
    Input: specification of a bundle search query.
    Output: worksheet items based on the result of issuing the search query.
    """
    # Perform search
    keywords = rest_util.resolve_owner_in_keywords(query['keywords'])
    bundle_uuids = local.model.search_bundle_uuids(request.user.user_id,
                                                   keywords)

    # Single number, just print it out...
    if not isinstance(bundle_uuids, list):
        return interpret_items(query['schemas'],
                               [markup_item(str(bundle_uuids))])

    # Set display
    items = [directive_item(('display', ) + tuple(query['display']))]

    # Show bundles
    bundle_infos = rest_util.get_bundle_infos(bundle_uuids)
    for bundle_uuid in bundle_uuids:
        items.append(bundle_item(bundle_infos[bundle_uuid]))

    # Finally, interpret the items
    return interpret_items(query['schemas'], items)
def expand_raw_item(raw_item):
    """
    Raw items that include searches must be expanded into more raw items.
    Input: Raw item.
    Output: Array of raw items. If raw item does not need expanding,
    this returns an 1-length array that contains original raw item,
    otherwise it contains the search result. You do not need to call
    resolve_items_into_infos on the returned raw_items.
    """

    (bundle_info, subworksheet_info, value_obj, item_type, id,
     sort_key) = raw_item

    is_search = item_type == TYPE_DIRECTIVE and get_command(
        value_obj) == 'search'
    is_wsearch = item_type == TYPE_DIRECTIVE and get_command(
        value_obj) == 'wsearch'

    if is_search or is_wsearch:
        command = get_command(value_obj)
        keywords = value_obj[1:]
        raw_items = []

        if is_search:
            keywords = rest_util.resolve_owner_in_keywords(keywords)
            search_result = local.model.search_bundles(request.user.user_id,
                                                       keywords)
            if search_result['is_aggregate']:
                # Add None's for the 'id' and 'sort_key' of the tuple, since these
                # items are not really worksheet items.
                raw_items.append(
                    markup_item(str(search_result['result'])) + (None, None))
            else:
                bundle_uuids = search_result['result']
                bundle_infos = rest_util.get_bundle_infos(bundle_uuids)
                for bundle_uuid in bundle_uuids:
                    # Since bundle UUID's are queried first, we can't assume a UUID exists in
                    # the subsequent bundle info query.
                    if bundle_uuid in bundle_infos:
                        raw_items.append(
                            bundle_item(bundle_infos[bundle_uuid]) +
                            (None, None))
        elif is_wsearch:
            worksheet_infos = search_worksheets(keywords)
            for worksheet_info in worksheet_infos:
                raw_items.append(
                    subworksheet_item(worksheet_info) + (None, None))

        return raw_items
    else:
        return [raw_item]
def fetch_worksheets():
    """
    Fetch worksheets by worksheet specs (names) OR search keywords.

    Query parameters:

     - `include`: comma-separated list of related resources to include, such as "owner"
    """
    keywords = query_get_list('keywords')
    specs = query_get_list('specs')
    base_worksheet_uuid = request.query.get('base')
    include_set = query_get_json_api_include_set(
        supported={'owner', 'group_permissions'})

    if specs:
        uuids = [
            get_worksheet_uuid_or_create(base_worksheet_uuid, spec)
            for spec in specs
        ]
        worksheets = [
            w.to_dict()
            for w in local.model.batch_get_worksheets(fetch_items=False,
                                                      uuid=uuids)
        ]
    else:
        keywords = resolve_owner_in_keywords(keywords)
        worksheets = local.model.search_worksheets(request.user.user_id,
                                                   keywords)

    # Build response document
    document = WorksheetSchema(many=True).dump(worksheets).data

    # Include users
    if 'owner' in include_set:
        owner_ids = {w['owner_id'] for w in worksheets}
        if owner_ids:
            json_api_include(
                document, UserSchema(),
                local.model.get_users(user_ids=owner_ids)['results'])

    # Include permissions
    if 'group_permissions' in include_set:
        for w in worksheets:
            if 'group_permissions' in w:
                json_api_include(document, WorksheetPermissionSchema(),
                                 w['group_permissions'])

    return document
Beispiel #5
0
def expand_raw_item(raw_item):
    """
    Raw items that include searches must be expanded into more raw items.
    Input: Raw item.
    Output: Array of raw items. If raw item does not need expanding,
    this returns an 1-length array that contains original raw item,
    otherwise it contains the search result. You do not need to call
    resolve_items_into_infos on the returned raw_items.
    """

    (bundle_info, subworksheet_info, value_obj, item_type) = raw_item

    is_search = item_type == TYPE_DIRECTIVE and get_command(
        value_obj) == 'search'
    is_wsearch = item_type == TYPE_DIRECTIVE and get_command(
        value_obj) == 'wsearch'

    if is_search or is_wsearch:
        command = get_command(value_obj)
        keywords = value_obj[1:]
        raw_items = []

        if is_search:
            keywords = rest_util.resolve_owner_in_keywords(keywords)
            search_result = local.model.search_bundle_uuids(
                request.user.user_id, keywords)
            if not isinstance(search_result, list):
                raw_items.append(markup_item(str(search_result)))
            else:
                bundle_uuids = search_result
                bundle_infos = rest_util.get_bundle_infos(bundle_uuids)
                for bundle_uuid in bundle_uuids:
                    raw_items.append(bundle_item(bundle_infos[bundle_uuid]))
        elif is_wsearch:
            worksheet_infos = search_worksheets(keywords)
            for worksheet_info in worksheet_infos:
                raw_items.append(subworksheet_item(worksheet_info))

        return raw_items
    else:
        return [raw_item]
Beispiel #6
0
def perform_search_query(value_obj):
    """
    Perform a search query and return the resulting raw items.
    Input: directive that is tokenized by formatting.string_to_tokens(),
        such as formatting.string_to_tokens("search 0x .limit=100")
    """
    command = get_command(value_obj)
    is_search = command == 'search'
    is_wsearch = command == 'wsearch'
    if is_search or is_wsearch:
        keywords = value_obj[1:]
        raw_items = []

        if is_search:
            keywords = rest_util.resolve_owner_in_keywords(keywords)
            search_result = local.model.search_bundles(request.user.user_id,
                                                       keywords)
            if search_result['is_aggregate']:
                # Add None's for the 'id' and 'sort_key' of the tuple, since these
                # items are not really worksheet items.
                raw_items.append(
                    markup_item(str(search_result['result'])) + (None, None))
            else:
                bundle_uuids = search_result['result']
                bundle_infos = rest_util.get_bundle_infos(bundle_uuids)
                for bundle_uuid in bundle_uuids:
                    # Since bundle UUID's are queried first, we can't assume a UUID exists in
                    # the subsequent bundle info query.
                    if bundle_uuid in bundle_infos:
                        raw_items.append(
                            bundle_item(bundle_infos[bundle_uuid]) +
                            (None, None))
        elif is_wsearch:
            worksheet_infos = search_worksheets(keywords)
            for worksheet_info in worksheet_infos:
                raw_items.append(
                    subworksheet_item(worksheet_info) + (None, None))
        return raw_items
    else:
        # Not a search query
        return []
Beispiel #7
0
def fetch_worksheets():
    """
    Fetch bundles by bundle specs OR search keywords.
    """
    keywords = query_get_list('keywords')
    specs = query_get_list('specs')
    base_worksheet_uuid = request.query.get('base')

    if specs:
        uuids = [
            get_worksheet_uuid_or_create(base_worksheet_uuid, spec)
            for spec in specs
        ]
        worksheets = [
            w.to_dict()
            for w in local.model.batch_get_worksheets(fetch_items=False,
                                                      uuid=uuids)
        ]
    else:
        keywords = resolve_owner_in_keywords(keywords)
        worksheets = local.model.search_worksheets(request.user.user_id,
                                                   keywords)

    # Build response document
    document = WorksheetSchema(many=True).dump(worksheets).data

    # Include users
    owner_ids = {w['owner_id'] for w in worksheets}
    if owner_ids:
        json_api_include(document, UserSchema(),
                         local.model.get_users(owner_ids))

    # Include permissions
    for w in worksheets:
        if 'group_permissions' in w:
            json_api_include(document, WorksheetPermissionSchema(),
                             w['group_permissions'])

    return document
Beispiel #8
0
def expand_raw_item(raw_item):
    """
    Raw items that include searches must be expanded into more raw items.
    Input: Raw item.
    Output: Array of raw items. If raw item does not need expanding,
    this returns an 1-length array that contains original raw item,
    otherwise it contains the search result. You do not need to call
    resolve_items_into_infos on the returned raw_items.
    """

    (bundle_info, subworksheet_info, value_obj, item_type) = raw_item

    is_search = item_type == TYPE_DIRECTIVE and get_command(value_obj) == 'search'
    is_wsearch = item_type == TYPE_DIRECTIVE and get_command(value_obj) == 'wsearch'

    if is_search or is_wsearch:
        command = get_command(value_obj)
        keywords = value_obj[1:]
        raw_items = []

        if is_search:
            keywords = rest_util.resolve_owner_in_keywords(keywords)
            search_result = local.model.search_bundles(request.user.user_id, keywords)
            if search_result['is_aggregate']:
                raw_items.append(markup_item(str(search_result['result'])))
            else:
                bundle_uuids = search_result['result']
                bundle_infos = rest_util.get_bundle_infos(bundle_uuids)
                for bundle_uuid in bundle_uuids:
                    raw_items.append(bundle_item(bundle_infos[bundle_uuid]))
        elif is_wsearch:
            worksheet_infos = search_worksheets(keywords)
            for worksheet_info in worksheet_infos:
                raw_items.append(subworksheet_item(worksheet_info))

        return raw_items
    else:
        return [raw_item]
Beispiel #9
0
def fetch_worksheets():
    """
    Fetch worksheets by worksheet specs (names) OR search keywords.

    Query parameters:

     - `include`: comma-separated list of related resources to include, such as "owner"
    """
    keywords = query_get_list('keywords')
    specs = query_get_list('specs')
    base_worksheet_uuid = request.query.get('base')
    include_set = query_get_json_api_include_set(supported={'owner', 'group_permissions'})

    if specs:
        uuids = [get_worksheet_uuid_or_create(base_worksheet_uuid, spec) for spec in specs]
        worksheets = [
            w.to_dict() for w in local.model.batch_get_worksheets(fetch_items=False, uuid=uuids)
        ]
    else:
        keywords = resolve_owner_in_keywords(keywords)
        worksheets = local.model.search_worksheets(request.user.user_id, keywords)

    # Build response document
    document = WorksheetSchema(many=True).dump(worksheets).data

    # Include users
    if 'owner' in include_set:
        owner_ids = {w['owner_id'] for w in worksheets}
        if owner_ids:
            json_api_include(document, UserSchema(), local.model.get_users(owner_ids))

    # Include permissions
    if 'group_permissions' in include_set:
        for w in worksheets:
            if 'group_permissions' in w:
                json_api_include(document, WorksheetPermissionSchema(), w['group_permissions'])

    return document
Beispiel #10
0
def search_worksheets(keywords):
    keywords = resolve_owner_in_keywords(keywords)
    results = local.model.search_worksheets(request.user.user_id, keywords)
    _set_owner_names(results)
    return results
def _fetch_bundles():
    """
    Fetch bundles in the following two ways:
    1. By bundle `specs` OR search `keywords` . Behavior is undefined
    when both `specs` and `keywords` are provided.

    Query parameters:

     - `worksheet`: UUID of the base worksheet. Required when fetching by specs.
     - `specs`: Bundle spec of bundle to fetch. May be provided multiples times
        to fetch multiple bundle specs. A bundle spec is either:
        1. a UUID (8 or 32 hex characters with a preceding '0x')
        2. a bundle name referring to the last bundle with that name on the
           given base worksheet
        3. or a reverse index of the form `^N` referring to the Nth-to-last
           bundle on the given base worksheet.
     - `keywords`: Search keyword. May be provided multiple times for multiple
        keywords. Bare keywords match the names and descriptions of bundles.
        Examples of other special keyword forms:
        - `name=<name>            ` : More targeted search of using metadata fields.
        - `size=.sort             ` : Sort by a particular field.
        - `size=.sort-            ` : Sort by a particular field in reverse.
        - `size=.sum              ` : Compute total of a particular field.
        - `.mine                  ` : Match only bundles I own.
        - `.floating              ` : Match bundles that aren't on any worksheet.
        - `.count                 ` : Count the number of bundles.
        - `.limit=10              ` : Limit the number of results to the top 10.
     - `include_display_metadata`: `1` to include additional metadata helpful
       for displaying the bundle info, `0` to omit them. Default is `0`.
     - `include`: comma-separated list of related resources to include, such as "owner"

    When aggregation keywords such as `.count` are used, the resulting value
    is returned as:
    ```
    {
        "meta": {
            "results": <value>
        }
    }
    ```
    2. By bundle `command` and/or `dependencies` (for `--memoized` option in cl [run/mimic] command).
    When `dependencies` is not defined, the searching result will include bundles that match with command only.

    Query parameters:
     - `command`      : the command of a bundle in string
     - `dependencies` : the dependencies of a bundle in the format of
                        '[{"child_path":key1, "parent_uuid":UUID1},
                        {"child_path":key2, "parent_uuid":UUID2}]'
        1. a UUID should be in the format of 32 hex characters with a preceding '0x' (partial UUID is not allowed).
        2. the key should be able to uniquely identify a (child_path, parent_uuid) pair in the list.
    The returning result will be aggregated in the same way as 1.
    """
    keywords = query_get_list('keywords')
    specs = query_get_list('specs')
    worksheet_uuid = request.query.get('worksheet')
    descendant_depth = query_get_type(int, 'depth', None)
    command = query_get_type(str, 'command', '')
    dependencies = query_get_type(str, 'dependencies', '[]')

    if keywords:
        # Handle search keywords
        keywords = resolve_owner_in_keywords(keywords)
        search_result = local.model.search_bundles(request.user.user_id,
                                                   keywords)
        # Return simple dict if scalar result (e.g. .sum or .count queries)
        if search_result['is_aggregate']:
            return json_api_meta({}, {'result': search_result['result']})
        # If not aggregate this is a list
        bundle_uuids = search_result['result']
    elif specs:
        # Resolve bundle specs
        bundle_uuids = canonicalize.get_bundle_uuids(local.model, request.user,
                                                     worksheet_uuid, specs)
    elif command:
        bundle_uuids = local.model.get_memoized_bundles(
            request.user.user_id, command, dependencies)
    else:
        abort(
            http.client.BAD_REQUEST,
            "Request must include either 'keywords' "
            "or 'specs' query parameter",
        )

    # Find all descendants down to the provided depth
    if descendant_depth is not None:
        bundle_uuids = local.model.get_self_and_descendants(
            bundle_uuids, depth=descendant_depth)

    return build_bundles_document(bundle_uuids)
def search_bundles(keywords):
    keywords = resolve_owner_in_keywords(keywords)
    results = local.model.search_bundles(request.user.user_id, keywords)
    return results
Beispiel #13
0
 def search_bundle_uuids(worksheet_uuid, keywords):
     keywords = resolve_owner_in_keywords(keywords)
     return local.model.search_bundle_uuids(request.user.user_id, worksheet_uuid, keywords)
Beispiel #14
0
 def search_worksheets(keywords, worksheet_uuid=None):
     keywords = resolve_owner_in_keywords(keywords)
     results = local.model.search_worksheets(request.user.user_id, keywords)
     BundleService._set_owner_names(results)
     return results
Beispiel #15
0
def _fetch_bundles():
    """
    Fetch bundles by bundle `specs` OR search `keywords`. Behavior is undefined
    when both `specs` and `keywords` are provided.

    Query parameters:

     - `worksheet`: UUID of the base worksheet. Required when fetching by specs.
     - `specs`: Bundle spec of bundle to fetch. May be provided multiples times
        to fetch multiple bundle specs. A bundle spec is either:
        1. a UUID (8 or 32 hex characters with a preceding '0x')
        2. a bundle name referring to the last bundle with that name on the
           given base worksheet
        3. or a reverse index of the form `^N` referring to the Nth-to-last
           bundle on the given base worksheet.
     - `keywords`: Search keyword. May be provided multiples times for multiple
        keywords. Bare keywords match the names and descriptions of bundles.
        Examples of other special keyword forms:
        - `name=<name>            ` : More targeted search of using metadata fields.
        - `size=.sort             ` : Sort by a particular field.
        - `size=.sort-            ` : Sort by a particular field in reverse.
        - `size=.sum              ` : Compute total of a particular field.
        - `.mine                  ` : Match only bundles I own.
        - `.floating              ` : Match bundles that aren't on any worksheet.
        - `.count                 ` : Count the number of bundles.
        - `.limit=10              ` : Limit the number of results to the top 10.
     - `include_display_metadata`: `1` to include additional metadata helpful
       for displaying the bundle info, `0` to omit them. Default is `0`.
     - `include`: comma-separated list of related resources to include, such as "owner"

    When aggregation keywords such as `.count` are used, the resulting value
    is returned as:
    ```
    {
        "meta": {
            "results": <value>
        }
    }
    ```

    """
    keywords = query_get_list('keywords')
    specs = query_get_list('specs')
    worksheet_uuid = request.query.get('worksheet')
    descendant_depth = query_get_type(int, 'depth', None)

    if keywords:
        # Handle search keywords
        keywords = resolve_owner_in_keywords(keywords)
        bundle_uuids = local.model.search_bundle_uuids(request.user.user_id, keywords)
    elif specs:
        # Resolve bundle specs
        bundle_uuids = canonicalize.get_bundle_uuids(local.model, request.user, worksheet_uuid, specs)
    else:
        abort(httplib.BAD_REQUEST,
              "Request must include either 'keywords' "
              "or 'specs' query parameter")

    # Find all descendants down to the provided depth
    if descendant_depth is not None:
        bundle_uuids = local.model.get_self_and_descendants(bundle_uuids, depth=descendant_depth)

    # Return simple dict if scalar result (e.g. .sum or .count queries)
    if not isinstance(bundle_uuids, list):
        return json_api_meta({}, {'result': bundle_uuids})

    return build_bundles_document(bundle_uuids)
def search_worksheets(keywords):
    keywords = resolve_owner_in_keywords(keywords)
    results = local.model.search_worksheets(request.user.user_id, keywords)
    _set_owner_names(results)
    return results