Пример #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)
Пример #2
0
def _get_parents(uuid):
    print("REACHED HERE 3")
    depth = query_get_type(int, 'depth', default=0)
    if depth < 0:
        abort(httplib.BAD_REQUEST, "Depth must be at least 0")
    specs = query_get_list('specs')
    worksheet_uuid = request.query.get('worksheet')
    if 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",
        )
    parent_uuids = local.model.get_self_and_ancesters(bundle_uuids,
                                                      depth=depth)
    final_result = []
    for level in range(len(parent_uuids)):
        final_result.append([])
        final_result[level].extend(
            [build_bundles_document(parent_uuids[level])])
    return {'data': final_result}
Пример #3
0
def parse_worksheet_form(form_result, model, user, worksheet_uuid):
    """
    Input: form_result is a list of lines.
    Return (list of (bundle_info, subworksheet_info, value, type) tuples, commands to execute)
    """

    def get_line_type(line):
        if line.startswith('!'):  # Run commands
            return 'command'
        elif line.startswith('//'):
            return 'comment'
        elif BUNDLE_REGEX.match(line) is not None:
            return TYPE_BUNDLE
        elif SUBWORKSHEET_REGEX.match(line) is not None:
            return TYPE_WORKSHEET
        elif DIRECTIVE_REGEX.match(line) is not None:
            return TYPE_DIRECTIVE
        else:
            return TYPE_MARKUP

    line_types = [get_line_type(line) for line in form_result]

    # Extract bundle specs and resolve uuids in one batch
    bundle_lines = [
        (i, BUNDLE_REGEX.match(line).group(3))
        for i, line in enumerate(form_result)
        if line_types[i] == TYPE_BUNDLE
        ]
    # bundle_specs = (line_indices, bundle_specs)
    bundle_specs = zip(*bundle_lines) if len(bundle_lines) > 0 else [(), ()]
    # bundle_uuids = {line_i: bundle_uuid, ...}
    bundle_uuids = dict(zip(bundle_specs[0], canonicalize.get_bundle_uuids(model, user, worksheet_uuid, bundle_specs[1])))

    commands = []
    items = []
    for line_i, (line_type, line) in enumerate(izip(line_types, form_result)):
        if line_type == 'command':
            command = formatting.string_to_tokens(line[1:].strip())
            # The user can specify '!<command> ^', which perform actions on the previous bundle.
            # Replace ^ with the reference to the last bundle.
            command = [(bundle_uuids[-1][1] if arg == '^' else arg) for arg in command]
            commands.append(command)
        elif line_type == 'comment':
            comment = line[2:]
            items.append(directive_item([DIRECTIVE_CHAR, comment]))
        elif line_type == TYPE_BUNDLE:
            bundle_info = {'uuid': bundle_uuids[line_i]}  # info doesn't need anything other than uuid
            items.append(bundle_item(bundle_info))
        elif line_type == TYPE_WORKSHEET:
            subworksheet_spec = SUBWORKSHEET_REGEX.match(line).group(3)
            try:
                subworksheet_uuid = canonicalize.get_worksheet_uuid(model, user, worksheet_uuid, subworksheet_spec)
                subworksheet_info = {'uuid': subworksheet_uuid}  # info doesn't need anything other than uuid
                items.append(subworksheet_item(subworksheet_info))
            except UsageError, e:
                items.append(markup_item(e.message + ': ' + line))
        elif line_type == TYPE_DIRECTIVE:
            directive = DIRECTIVE_REGEX.match(line).group(1)
            items.append(directive_item(formatting.string_to_tokens(directive)))
Пример #4
0
def parse_worksheet_form(form_result, model, user, worksheet_uuid):
    """
    Input: form_result is a list of lines.
    Return (list of (bundle_info, subworksheet_info, value, type) tuples, commands to execute)
    """
    def get_line_type(line):
        if line.startswith('//'):
            return 'comment'
        elif BUNDLE_REGEX.match(line) is not None:
            return TYPE_BUNDLE
        elif SUBWORKSHEET_REGEX.match(line) is not None:
            return TYPE_WORKSHEET
        elif DIRECTIVE_REGEX.match(line) is not None:
            return TYPE_DIRECTIVE
        else:
            return TYPE_MARKUP

    line_types = [get_line_type(line) for line in form_result]

    # Extract bundle specs and resolve uuids in one batch
    bundle_lines = [(i, BUNDLE_REGEX.match(line).group(3))
                    for i, line in enumerate(form_result)
                    if line_types[i] == TYPE_BUNDLE]
    # bundle_specs = (line_indices, bundle_specs)
    bundle_specs = list(zip(*bundle_lines)) if len(bundle_lines) > 0 else [(),
                                                                           ()]
    # bundle_uuids = {line_i: bundle_uuid, ...}
    bundle_uuids = dict(
        list(
            zip(
                bundle_specs[0],
                canonicalize.get_bundle_uuids(model, user, worksheet_uuid,
                                              bundle_specs[1]),
            )))

    items = []
    for line_i, (line_type, line) in enumerate(zip(line_types, form_result)):
        if line_type == 'comment':
            comment = line[2:]
            items.append(directive_item([DIRECTIVE_CHAR, comment]))
        elif line_type == TYPE_BUNDLE:
            bundle_info = {
                'uuid': bundle_uuids[line_i]
            }  # info doesn't need anything other than uuid
            items.append(bundle_item(bundle_info))
        elif line_type == TYPE_WORKSHEET:
            subworksheet_spec = SUBWORKSHEET_REGEX.match(line).group(3)
            try:
                subworksheet_uuid = canonicalize.get_worksheet_uuid(
                    model, user, worksheet_uuid, subworksheet_spec)
                subworksheet_info = {
                    'uuid': subworksheet_uuid
                }  # info doesn't need anything other than uuid
                items.append(subworksheet_item(subworksheet_info))
            except UsageError as e:
                items.append(markup_item(str(e) + ': ' + line))
        elif line_type == TYPE_DIRECTIVE:
            directive = DIRECTIVE_REGEX.match(line).group(1)
            items.append(directive_item(
                formatting.string_to_tokens(directive)))
        elif line_type == TYPE_MARKUP:
            items.append(markup_item(line))
        else:
            raise RuntimeError(
                "Invalid line type %s: this should not happen." % line_type)

    return items
Пример #5
0
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)
Пример #6
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)
Пример #7
0
def parse_worksheet_form(form_result, model, user, worksheet_uuid):
    """
    Input: form_result is a list of lines.
    Return (list of (bundle_info, subworksheet_info, value, type) tuples, commands to execute)
    """

    def get_line_type(line):
        if line.startswith('//'):
            return 'comment'
        elif BUNDLE_REGEX.match(line) is not None:
            return TYPE_BUNDLE
        elif SUBWORKSHEET_REGEX.match(line) is not None:
            return TYPE_WORKSHEET
        elif DIRECTIVE_REGEX.match(line) is not None:
            return TYPE_DIRECTIVE
        else:
            return TYPE_MARKUP

    line_types = [get_line_type(line) for line in form_result]

    # Extract bundle specs and resolve uuids in one batch
    bundle_lines = [
        (i, BUNDLE_REGEX.match(line).group(3))
        for i, line in enumerate(form_result)
        if line_types[i] == TYPE_BUNDLE
    ]
    # bundle_specs = (line_indices, bundle_specs)
    bundle_specs = zip(*bundle_lines) if len(bundle_lines) > 0 else [(), ()]
    # bundle_uuids = {line_i: bundle_uuid, ...}
    bundle_uuids = dict(
        zip(
            bundle_specs[0],
            canonicalize.get_bundle_uuids(model, user, worksheet_uuid, bundle_specs[1]),
        )
    )

    items = []
    for line_i, (line_type, line) in enumerate(izip(line_types, form_result)):
        if line_type == 'comment':
            comment = line[2:]
            items.append(directive_item([DIRECTIVE_CHAR, comment]))
        elif line_type == TYPE_BUNDLE:
            bundle_info = {
                'uuid': bundle_uuids[line_i]
            }  # info doesn't need anything other than uuid
            items.append(bundle_item(bundle_info))
        elif line_type == TYPE_WORKSHEET:
            subworksheet_spec = SUBWORKSHEET_REGEX.match(line).group(3)
            try:
                subworksheet_uuid = canonicalize.get_worksheet_uuid(
                    model, user, worksheet_uuid, subworksheet_spec
                )
                subworksheet_info = {
                    'uuid': subworksheet_uuid
                }  # info doesn't need anything other than uuid
                items.append(subworksheet_item(subworksheet_info))
            except UsageError as e:
                items.append(markup_item(e.message + ': ' + line))
        elif line_type == TYPE_DIRECTIVE:
            directive = DIRECTIVE_REGEX.match(line).group(1)
            items.append(directive_item(formatting.string_to_tokens(directive)))
        elif line_type == TYPE_MARKUP:
            items.append(markup_item(line))
        else:
            raise RuntimeError("Invalid line type %s: this should not happen." % line_type)

    return items