def parse_worksheet_form(form_result, client, 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_specs = (line_indices, bundle_specs) bundle_lines = [ (i, BUNDLE_REGEX.match(line).group(3)) for i, line in enumerate(form_result) if line_types[i] == TYPE_BUNDLE ] bundle_specs = zip(*bundle_lines) if len(bundle_lines) > 0 else [(), ()] # bundle_uuids = {line_i: bundle_uuid, ...} bundle_uuids = dict(zip(bundle_specs[0], get_bundle_uuids(client, 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 = get_worksheet_uuid(client, 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('!'): # 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 convert_items_from_db(items): """ Helper function. (bundle_uuid, subworksheet_uuid, value, type) -> (bundle_info, subworksheet_info, value_obj, type) """ # Database only contains the uuid; need to expand to info. # We need to do to convert the bundle_uuids into bundle_info dicts. # However, we still make O(1) database calls because we use the # optimized batch_get_bundles multiget method. bundle_uuids = set(bundle_uuid for (bundle_uuid, subworksheet_uuid, value, type) in items if bundle_uuid is not None) bundle_dict = get_bundle_infos(bundle_uuids) # Go through the items and substitute the components new_items = [] for (bundle_uuid, subworksheet_uuid, value, type) in items: bundle_info = bundle_dict.get( bundle_uuid, {'uuid': bundle_uuid}) if bundle_uuid else None if subworksheet_uuid: try: subworksheet_info = local.model.get_worksheet( subworksheet_uuid, fetch_items=False).to_dict(legacy=True) except UsageError, e: # If can't get the subworksheet, it's probably invalid, so just replace it with an error # type = worksheet_util.TYPE_MARKUP subworksheet_info = {'uuid': subworksheet_uuid} # value = 'ERROR: non-existent worksheet %s' % subworksheet_uuid else: subworksheet_info = None value_obj = formatting.string_to_tokens( value) if type == worksheet_util.TYPE_DIRECTIVE else value new_items.append((bundle_info, subworksheet_info, value_obj, type))
def resolve_items_into_infos(items): """ Helper function. {'bundle_uuid': '...', 'subworksheet_uuid': '...', 'value': '...', 'type': '...') -> (bundle_info, subworksheet_info, value_obj, type) """ # Database only contains the uuid; need to expand to info. # We need to do to convert the bundle_uuids into bundle_info dicts. # However, we still make O(1) database calls because we use the # optimized batch_get_bundles multiget method. bundle_uuids = set( i['bundle_uuid'] for i in items if i['bundle_uuid'] is not None ) bundle_dict = rest_util.get_bundle_infos(bundle_uuids) # Go through the items and substitute the components new_items = [] for i in items: bundle_info = bundle_dict.get(i['bundle_uuid'], {'uuid': i['bundle_uuid']}) if i['bundle_uuid'] else None if i['subworksheet_uuid']: try: subworksheet_info = local.model.get_worksheet(i['subworksheet_uuid'], fetch_items=False).to_dict() except UsageError, e: # If can't get the subworksheet, it's probably invalid, so just replace it with an error # type = worksheet_util.TYPE_MARKUP subworksheet_info = {'uuid': i['subworksheet_uuid']} # value = 'ERROR: non-existent worksheet %s' % subworksheet_uuid else: subworksheet_info = None value_obj = formatting.string_to_tokens(i['value']) if i['type'] == TYPE_DIRECTIVE else i['value'] new_items.append((bundle_info, subworksheet_info, value_obj, i['type']))
def resolve_items_into_infos(items): """ Helper function. {'bundle_uuid': '...', 'subworksheet_uuid': '...', 'value': '...', 'type': '...') -> (bundle_info, subworksheet_info, value_obj, type) """ # Database only contains the uuid; need to expand to info. # We need to do to convert the bundle_uuids into bundle_info dicts. # However, we still make O(1) database calls because we use the # optimized batch_get_bundles multiget method. bundle_uuids = set(i['bundle_uuid'] for i in items if i['bundle_uuid'] is not None) bundle_dict = rest_util.get_bundle_infos(bundle_uuids) # Go through the items and substitute the components new_items = [] for i in items: bundle_info = ( bundle_dict.get(i['bundle_uuid'], {'uuid': i['bundle_uuid']}) if i['bundle_uuid'] else None ) if i['subworksheet_uuid']: try: subworksheet_info = local.model.get_worksheet( i['subworksheet_uuid'], fetch_items=False ).to_dict() except UsageError as e: # If can't get the subworksheet, it's probably invalid, so just replace it with an error # type = worksheet_util.TYPE_MARKUP subworksheet_info = {'uuid': i['subworksheet_uuid']} # value = 'ERROR: non-existent worksheet %s' % subworksheet_uuid else: subworksheet_info = None value_obj = ( formatting.string_to_tokens(i['value']) if i['type'] == TYPE_DIRECTIVE else i['value'] ) new_items.append((bundle_info, subworksheet_info, value_obj, i['type'])) return new_items
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 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