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)
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}
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)))
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
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 _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 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