Example #1
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)
Example #2
0
    def full_worksheet(self, uuid):
        """
        Return information about a worksheet. Calls
        - get_worksheet_info: get basic info
        - resolve_interpreted_items: get more information about a worksheet.
        In the future, for large worksheets, might want to break this up so
        that we can render something basic.
        """
        worksheet_info = self.client.get_worksheet_info(uuid, True, True)

        # Fetch items.
        worksheet_info['raw'] = worksheet_util.get_worksheet_lines(worksheet_info)

        # Set permissions
        worksheet_info['edit_permission'] = (worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL)
        # Check enable chat box
        worksheet_info['enable_chat'] = local.config.get('enable_chat', False)
        # Format permissions into strings
        worksheet_info['permission_str'] = permission_str(worksheet_info['permission'])
        for group_permission in worksheet_info['group_permissions']:
            group_permission['permission_str'] = permission_str(group_permission['permission'])

        # Go and fetch more information about the worksheet contents by
        # resolving the interpreted items.
        try:
            interpreted_items = worksheet_util.interpret_items(
                                worksheet_util.get_default_schemas(),
                                worksheet_info['items'])
        except UsageError, e:
            interpreted_items = {'items': []}
            worksheet_info['error'] = str(e)
Example #3
0
        def worksheet(self, uuid, interpreted=False):
            try:
                worksheet_info  = self.client.get_worksheet_info(
                                            uuid,
                                            True,  #fetch_items
                                            True,  # get_permissions

                                )
            except PermissionError:
                raise UsageError # forces a not found
            worksheet_info['raw'] = worksheet_util.get_worksheet_lines(worksheet_info)
            # set permissions
            worksheet_info['edit_permission'] = False
            if worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL:
                worksheet_info['edit_permission'] = True

            worksheet_info['permission_str'] = permission_str(worksheet_info['permission'])
            # format each groups as well
            for group_permission in worksheet_info['group_permissions']:
                group_permission['permission_str'] = permission_str(group_permission['permission'])


            if interpreted:
                interpreted_items = worksheet_util.interpret_items(
                                    worksheet_util.get_default_schemas(),
                                    worksheet_info['items']
                                )
                worksheet_info['items'] = self.client.resolve_interpreted_items(interpreted_items['items'])
                return worksheet_info
            else:
                return worksheet_info
Example #4
0
    def full_worksheet(self, uuid, bundle_uuids=None):
        """
        Return information about a worksheet. Calls
        - get_worksheet_info: get basic info
        - resolve_interpreted_items: get more information about a worksheet.
        In the future, for large worksheets, might want to break this up so
        that we can render something basic.
        """
        worksheet_info = get_worksheet_info(uuid, fetch_items=True, fetch_permission=True, legacy=True)

        # Fetch items.
        worksheet_info['raw'] = worksheet_util.get_worksheet_lines(worksheet_info)

        # Set permissions
        worksheet_info['edit_permission'] = (worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL)
        # Check enable chat box
        worksheet_info['enable_chat'] = local.config.get('enable_chat', False)
        # Format permissions into strings
        worksheet_info['permission_str'] = permission_str(worksheet_info['permission'])
        for group_permission in worksheet_info['group_permissions']:
            group_permission['permission_str'] = permission_str(group_permission['permission'])

        # Go and fetch more information about the worksheet contents by
        # resolving the interpreted items.
        try:
            interpreted_items = worksheet_util.interpret_items(
                                worksheet_util.get_default_schemas(),
                                worksheet_info['items'])
        except UsageError, e:
            interpreted_items = {'items': []}
            worksheet_info['error'] = str(e)
Example #5
0
        def worksheet(self, uuid, interpreted=False, fetch_items=True, get_raw=True):
            try:
                worksheet_info  = self.client.get_worksheet_info(
                                            uuid,
                                            fetch_items,  # fetch_items
                                            True,  # get_permissions
                                )
            except PermissionError:
                raise UsageError # forces a not found
            if get_raw:
                worksheet_info['raw'] = worksheet_util.get_worksheet_lines(worksheet_info)
            # set permissions
            worksheet_info['edit_permission'] = False
            if worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL:
                worksheet_info['edit_permission'] = True

            worksheet_info['permission_str'] = permission_str(worksheet_info['permission'])
            # format each groups as well
            for group_permission in worksheet_info['group_permissions']:
                group_permission['permission_str'] = permission_str(group_permission['permission'])


            if interpreted:
                interpreted_items = worksheet_util.interpret_items(
                                    worksheet_util.get_default_schemas(),
                                    worksheet_info['items']
                                )
                worksheet_info['items'] = self.client.resolve_interpreted_items(interpreted_items['items'])
                # Currently, only certain fields are base64 encoded.
                for item in worksheet_info['items']:
                    if item['mode'] in ['html', 'contents']:
                        # item['name'] in ['stdout', 'stderr']
                        if item['interpreted'] is None:
                            item['interpreted'] = ['MISSING']
                        else:
                            item['interpreted'] = map(base64.b64decode, item['interpreted'])
                    elif item['mode'] == 'table':
                        for row_map in item['interpreted'][1]:
                            for k, v in row_map.iteritems():
                                if v is None:
                                     row_map[k] = 'MISSING'
                    if 'bundle_info' in item:
                        if isinstance(item['bundle_info'], list):
                            for bundle_info in item['bundle_info']:
                                try:
                                    ## sometimes bundle_info is a string. when item['mode'] is image
                                    if isinstance(bundle_info, dict):
                                        worksheet_util.format_metadata(bundle_info.get('metadata'))
                                        if bundle_info.get('bundle_type', None) == 'run':
                                            if 'stdout' in bundle_info.keys():
                                                bundle_info['stdout'] = base64.b64decode(bundle_info['stdout'])
                                            if 'stderr' in bundle_info.keys():
                                                bundle_info['stderr'] = base64.b64decode(bundle_info['stderr'])
                                except Exception, e:
                                    print e
                                    import ipdb; ipdb.set_trace()
                        elif isinstance(item['bundle_info'], dict):
                            worksheet_util.format_metadata(item['bundle_info'].get('metadata'))

                return worksheet_info
Example #6
0
        def worksheet(self, uuid, fetch_items, get_permissions, interpreted):
            """
            Return information about a worksheet. Calls
            - get_worksheet_info: get basic info
            - resolve_interpreted_items: get more information about a worksheet.
            In the future, for large worksheets, might want to break this up so
            that we can render something basic.
            """
            worksheet_info = self.client.get_worksheet_info(uuid, fetch_items, get_permissions)

            if fetch_items:
                worksheet_info['raw'] = worksheet_util.get_worksheet_lines(worksheet_info)

            # Set permissions
            worksheet_info['edit_permission'] = (worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL)
            # Format permissions into strings
            worksheet_info['permission_str'] = permission_str(worksheet_info['permission'])
            for group_permission in worksheet_info['group_permissions']:
                group_permission['permission_str'] = permission_str(group_permission['permission'])

            # Go and fetch more information about the worksheet contents by
            # resolving the interpreted items.
            if interpreted:
                try:
                    interpreted_items = worksheet_util.interpret_items(
                                        worksheet_util.get_default_schemas(),
                                        worksheet_info['items'])
                except UsageError, e:
                    interpreted_items = {'items': []}
                    worksheet_info['error'] = str(e)

                worksheet_info['items'] = self.client.resolve_interpreted_items(interpreted_items['items'])
                # Currently, only certain fields are base64 encoded.
                for item in worksheet_info['items']:
                    if item['mode'] in ['html', 'contents']:
                        if item['interpreted'] is None:
                            item['interpreted'] = [formatting.contents_str(item['interpreted'])]
                        else:
                            item['interpreted'] = map(base64.b64decode, item['interpreted'])
                    elif item['mode'] == 'table':
                        for row_map in item['interpreted'][1]:
                            for k, v in row_map.iteritems():
                                if v is None:
                                     row_map[k] = formatting.contents_str(v)
                    elif 'bundle_info' in item:
                        infos = []
                        if isinstance(item['bundle_info'], list):
                            infos = item['bundle_info']
                        elif isinstance(item['bundle_info'], dict):
                            infos = [item['bundle_info']]
                        for bundle_info in infos:
                            try:
                                if isinstance(bundle_info, dict):
                                    worksheet_util.format_metadata(bundle_info.get('metadata'))
                            except Exception, e:
                                print e
                                import ipdb; ipdb.set_trace()
Example #7
0
def interpret_wsearch(query):
    """
    Input: specification of a worksheet search query.
    Output: worksheet items based on the result of issuing the search query.
    """
    # Get the worksheet uuids
    worksheet_infos = search_worksheets(query['keywords'])
    items = [subworksheet_item(worksheet_info) for worksheet_info in worksheet_infos]

    # Finally, interpret the items
    return interpret_items([], items)
Example #8
0
 def worksheet(self, uuid, interpreted=False):
     worksheet_info = _call_with_retries(
         lambda: self.client.get_worksheet_info(uuid, True))
     if interpreted:
         interpreted_items = worksheet_util.interpret_items(
             worksheet_util.get_default_schemas(),
             worksheet_info['items'])
         worksheet_info[
             'items'] = self.client.resolve_interpreted_items(
                 interpreted_items['items'])
         return worksheet_info
     else:
         return worksheet_info
Example #9
0
def fetch_interpreted_worksheet(uuid):
    """
    Return information about a worksheet. Calls
    - get_worksheet_info: get basic info
    - resolve_interpreted_items: get more information about a worksheet.
    In the future, for large worksheets, might want to break this up so
    that we can render something basic.
    """
    bundle_uuids = request.query.getall('bundle_uuid')
    worksheet_info = get_worksheet_info(uuid,
                                        fetch_items=True,
                                        fetch_permissions=True)

    # Shim in additional data for the frontend
    worksheet_info['items'] = resolve_items_into_infos(worksheet_info['items'])
    if worksheet_info['owner_id'] is None:
        worksheet_info['owner_name'] = None
    else:
        owner = local.model.get_user(user_id=worksheet_info['owner_id'])
        worksheet_info['owner_name'] = owner.user_name

    # Fetch items.
    worksheet_info['raw'] = get_worksheet_lines(worksheet_info)

    # Replace searches with raw items.
    # This needs to be done before get_worksheet_lines because this replaces
    # user-written raw items.
    worksheet_info['items'] = expand_raw_items(worksheet_info['items'])

    # Set permissions
    worksheet_info['edit_permission'] = (
        worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL)
    # Check enable chat box
    worksheet_info['enable_chat'] = local.config.get('enable_chat', False)
    # Format permissions into strings
    worksheet_info['permission_spec'] = permission_str(
        worksheet_info['permission'])
    for group_permission in worksheet_info['group_permissions']:
        group_permission['permission_spec'] = permission_str(
            group_permission['permission'])

    # Go and fetch more information about the worksheet contents by
    # resolving the interpreted items.
    try:
        interpreted_items = interpret_items(get_default_schemas(),
                                            worksheet_info['items'])
    except UsageError, e:
        interpreted_items = {'items': []}
        worksheet_info['error'] = str(e)
Example #10
0
 def worksheet(self, uuid, interpreted=False):
     worksheet_info  = _call_with_retries(
             lambda: self.client.get_worksheet_info(
                     uuid,
                     True
             )
         )
     if interpreted:
         interpreted_items = worksheet_util.interpret_items(
                             worksheet_util.get_default_schemas(),
                             worksheet_info['items']
                         )
         worksheet_info['items'] = self.client.resolve_interpreted_items(interpreted_items['items'])
         return worksheet_info
     else:
         return worksheet_info
Example #11
0
        def worksheet(self, uuid, interpreted=False):
            try:
                worksheet_info  = self.client.get_worksheet_info(
                                            uuid,
                                            True,  #fetch_items
                                            True,  # get_permissions
                                )
            except PermissionError:
                raise UsageError # forces a not found
            worksheet_info['raw'] = worksheet_util.get_worksheet_lines(worksheet_info)
            # set permissions
            worksheet_info['edit_permission'] = False
            if worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL:
                worksheet_info['edit_permission'] = True

            worksheet_info['permission_str'] = permission_str(worksheet_info['permission'])
            # format each groups as well
            for group_permission in worksheet_info['group_permissions']:
                group_permission['permission_str'] = permission_str(group_permission['permission'])


            if interpreted:
                interpreted_items = worksheet_util.interpret_items(
                                    worksheet_util.get_default_schemas(),
                                    worksheet_info['items']
                                )
                worksheet_info['items'] = self.client.resolve_interpreted_items(interpreted_items['items'])
                # Currently, only certain fields are base64 encoded.
                for item in worksheet_info['items']:
                    if item['mode'] in ['html', 'contents']:
                        # item['name'] in ['stdout', 'stderr']
                        item['interpreted'] = map(base64.b64decode, item['interpreted'])
                    elif 'bundle_info' in item:
                        for bundle_info in item['bundle_info']:
                            try:
                                ## sometimes bundle_info is a string. when item['mode'] is image
                                if isinstance(bundle_info, dict) and bundle_info.get('bundle_type', None) == 'run':
                                    if 'stdout' in bundle_info.keys():
                                        bundle_info['stdout'] = base64.b64decode(bundle_info['stdout'])
                                    if 'stderr' in bundle_info.keys():
                                        bundle_info['stderr'] = base64.b64decode(bundle_info['stderr'])
                            except Exception, e:
                                print e
                                import ipdb; ipdb.set_trace()


                return worksheet_info
Example #12
0
        def worksheet(self, uuid, interpreted=False):
            try:
                worksheet_info  = self.client.get_worksheet_info(
                                            uuid,
                                            True,  #fetch_items
                                            True,  # get_permissions
                                )
            except PermissionError:
                raise UsageError # forces a not found
            worksheet_info['raw'] = worksheet_util.get_worksheet_lines(worksheet_info)
            # set permissions
            worksheet_info['edit_permission'] = False
            if worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL:
                worksheet_info['edit_permission'] = True

            worksheet_info['permission_str'] = permission_str(worksheet_info['permission'])
            # format each groups as well
            for group_permission in worksheet_info['group_permissions']:
                group_permission['permission_str'] = permission_str(group_permission['permission'])


            if interpreted:
                interpreted_items = worksheet_util.interpret_items(
                                    worksheet_util.get_default_schemas(),
                                    worksheet_info['items']
                                )
                worksheet_info['items'] = self.client.resolve_interpreted_items(interpreted_items['items'])
                # Currently, only certain fields are base64 encoded.
                import base64
                for item in worksheet_info['items']:
                    if item['mode'] in ['html', 'contents']:
                        item['interpreted'] = map(base64.b64decode, item['interpreted'])

                return worksheet_info
            else:
                return worksheet_info
Example #13
0
def fetch_interpreted_worksheet(uuid):
    """
    Return information about a worksheet. Calls
    - get_worksheet_info: get basic info
    - resolve_interpreted_items: get more information about a worksheet.
    In the future, for large worksheets, might want to break this up so
    that we can render something basic.
    """
    bundle_uuids = request.query.getall('bundle_uuid')
    worksheet_info = get_worksheet_info(uuid, fetch_items=True, fetch_permissions=True)

    # Shim in additional data for the frontend
    worksheet_info['items'] = resolve_items_into_infos(worksheet_info['items'])
    if worksheet_info['owner_id'] is None:
        worksheet_info['owner_name'] = None
    else:
        owner = local.model.get_user(user_id=worksheet_info['owner_id'])
        worksheet_info['owner_name'] = owner.user_name

    # Fetch items.
    worksheet_info['raw'] = get_worksheet_lines(worksheet_info)

    # Replace searches with raw items.
    # This needs to be done before get_worksheet_lines because this replaces
    # user-written raw items.
    worksheet_info['items'] = expand_raw_items(worksheet_info['items'])

    # Set permissions
    worksheet_info['edit_permission'] = worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL
    # Check enable chat box
    worksheet_info['enable_chat'] = local.config.get('enable_chat', False)
    # Format permissions into strings
    worksheet_info['permission_spec'] = permission_str(worksheet_info['permission'])
    for group_permission in worksheet_info['group_permissions']:
        group_permission['permission_spec'] = permission_str(group_permission['permission'])

    # Go and fetch more information about the worksheet contents by
    # resolving the interpreted items.
    try:
        interpreted_blocks = interpret_items(get_default_schemas(), worksheet_info['items'])
    except UsageError as e:
        interpreted_blocks = {'blocks': []}
        worksheet_info['error'] = str(e)

    # bundle_uuids is an optional argument that, if exists, contain the uuids of all the unfinished run bundles that need updating
    # In this case, full_worksheet will return a list of item parallel to ws.info.items that contain only items that need updating.
    # More specifically, all blocks that don't contain run bundles that need updating are None.
    # Also, a non-None block could contain a list of bundle_infos, which represent a list of bundles. Usually not all of them need updating.
    # The bundle_infos for bundles that don't need updating are also None.
    if bundle_uuids:
        for i, block in enumerate(interpreted_blocks['blocks']):
            if 'bundle_info' not in block:
                interpreted_blocks['blocks'][i] = None
            else:
                if isinstance(block['bundle_info'], dict):
                    block['bundle_info'] = [block['bundle_info']]
                is_relevant_block = False
                for j, bundle in enumerate(block['bundle_info']):
                    if bundle['uuid'] in bundle_uuids:
                        is_relevant_block = True
                    else:
                        block['bundle_info'][j] = None
                if not is_relevant_block:
                    interpreted_blocks['blocks'][i] = None

    worksheet_info['items'] = resolve_interpreted_blocks(interpreted_blocks['blocks'])
    worksheet_info['raw_to_block'] = interpreted_blocks['raw_to_block']
    worksheet_info['block_to_raw'] = interpreted_blocks['block_to_raw']

    for item in worksheet_info['items']:
        if item is None:
            continue
        if item['mode'] == 'table':
            for row_map in item['rows']:
                for k, v in row_map.iteritems():
                    if v is None:
                        row_map[k] = formatting.contents_str(v)
        if 'bundle_info' in item:
            infos = []
            if isinstance(item['bundle_info'], list):
                infos = item['bundle_info']
            elif isinstance(item['bundle_info'], dict):
                infos = [item['bundle_info']]
            for bundle_info in infos:
                if bundle_info is None:
                    continue
                if 'bundle_type' not in bundle_info:
                    continue  # empty info: invalid bundle reference
                if isinstance(bundle_info, dict):
                    format_metadata(bundle_info.get('metadata'))
    if bundle_uuids:
        return {'items': worksheet_info['items']}
    return worksheet_info
Example #14
0
        def worksheet(self, uuid, fetch_items, get_permissions, interpreted):
            """
            Return information about a worksheet. Calls
            - get_worksheet_info: get basic info
            - resolve_interpreted_items: get more information about a worksheet.
            In the future, for large worksheets, might want to break this up so
            that we can render something basic.
            """
            worksheet_info = self.client.get_worksheet_info(
                uuid, fetch_items, get_permissions)

            if fetch_items:
                worksheet_info['raw'] = worksheet_util.get_worksheet_lines(
                    worksheet_info)

            # Set permissions
            worksheet_info['edit_permission'] = (
                worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL)
            # Format permissions into strings
            worksheet_info['permission_str'] = permission_str(
                worksheet_info['permission'])
            for group_permission in worksheet_info['group_permissions']:
                group_permission['permission_str'] = permission_str(
                    group_permission['permission'])

            # Go and fetch more information about the worksheet contents by
            # resolving the interpreted items.
            if interpreted:
                try:
                    interpreted_items = worksheet_util.interpret_items(
                        worksheet_util.get_default_schemas(),
                        worksheet_info['items'])
                except UsageError, e:
                    interpreted_items = {'items': []}
                    worksheet_info['error'] = str(e)

                worksheet_info[
                    'items'] = self.client.resolve_interpreted_items(
                        interpreted_items['items'])
                # Currently, only certain fields are base64 encoded.
                for item in worksheet_info['items']:
                    if item['mode'] in ['html', 'contents']:
                        if item['interpreted'] is None:
                            item['interpreted'] = [
                                formatting.contents_str(item['interpreted'])
                            ]
                        else:
                            item['interpreted'] = map(base64.b64decode,
                                                      item['interpreted'])
                    elif item['mode'] == 'table':
                        for row_map in item['interpreted'][1]:
                            for k, v in row_map.iteritems():
                                if v is None:
                                    row_map[k] = formatting.contents_str(v)
                    elif 'bundle_info' in item:
                        infos = []
                        if isinstance(item['bundle_info'], list):
                            infos = item['bundle_info']
                        elif isinstance(item['bundle_info'], dict):
                            infos = [item['bundle_info']]
                        for bundle_info in infos:
                            try:
                                if isinstance(bundle_info, dict):
                                    worksheet_util.format_metadata(
                                        bundle_info.get('metadata'))
                            except Exception, e:
                                print e
                                import ipdb
                                ipdb.set_trace()
Example #15
0
def fetch_interpreted_worksheet(uuid):
    """
    Return information about a worksheet. Calls
    - get_worksheet_info: get basic info
    - resolve_interpreted_items: get more information about a worksheet.
    In the future, for large worksheets, might want to break this up so
    that we can render something basic.
    Return:
        worksheet_info dict{}:
            key:[value_type] <description>
            blocks:[list]
                    Resolved worksheet blocks from raw_items.
                        Bundles will be grouped into table block items,
                        text items might be grouped into one markdown block etc.
            source:[list] source lines
            raw_to_block:[list]
                            Raw_items to its block index pair.
                                For example, assume the first resolved block item is a bundle table that has 2 rows,
                                then the 2nd element in the list would be [0, 1]
                                [0, 1]: 0 means the item belongs to the first block,
                                        1 means the item is the second item of the block (2nd bundle in our example)
                                NOTE: Used for setting focus on frontend
            block_to_raw:[dict]
                            Maps the blocks (table, markdown, records) to their corresponding source line indices,
                            it's mostly a reverse mapping of raw_to_block, by mostly: raw_to_block has some bug,
                            please refer to worksheet_utils flush_bundles function.
                            This can be used to index the source on the frontend
                            Example:
                            [0, 0]: 0
                            [0, 1]: 1
                            [1, 0]: 9
                            This means the first blocks' first item corresponds to the first line in source,
                            the second item corresponds to the second line in source
                            The second block corresponds the 10th line in source.
                            2-8 can be skipped for multiple reasons: blank lines, comments, schema lines etc.
                                NOTE: Used for setting focus on frontend
    This endpoint can be called with &brief=1 in order to give an abbreviated version,
    which does not resolve searches or wsearches.
    To return an interpreted worksheet that only resolves a particular search/wsearch,
    pass in the search query to the "directive" argument. The value for this argument
    must be a search/wsearch query -- for example, &directive=search 0x .limit=100
    """
    bundle_uuids = request.query.getall('bundle_uuid')
    brief = request.query.get("brief", "0") == "1"

    directive = request.query.get("directive", None)
    search_results = []

    worksheet_info = get_worksheet_info(uuid,
                                        fetch_items=True,
                                        fetch_permissions=True)

    # Shim in additional data for the frontend
    worksheet_info['items'] = resolve_items_into_infos(worksheet_info['items'])

    if worksheet_info['owner_id'] is None:
        worksheet_info['owner_name'] = None
    else:
        owner = local.model.get_user(user_id=worksheet_info['owner_id'])
        worksheet_info['owner_name'] = owner.user_name

    # Fetch items.
    worksheet_info['source'] = get_worksheet_lines(worksheet_info)

    if not directive and not brief:
        expanded_items = []
        for index, raw_item in enumerate(worksheet_info['items']):
            expanded = expand_search_item(raw_item)
            expanded_items.append(expanded)
            # Multiple items can correspond to the same source line (i.e: search directives)
            # raw_items_to_source_index.extend([index] * len(expanded))
        worksheet_info['items'] = list(chain.from_iterable(expanded_items))
    elif directive:
        # Only expand the search item corresponding to the given directive.
        # Used in async loading to only load a single table.
        items_to_show = []
        for i, item in enumerate(worksheet_info['items']):
            (bundle_info, subworksheet_info, value_obj, item_type, id,
             sort_key) = item
            if directive == formatting.tokens_to_string(value_obj):
                search_results = perform_search_query(value_obj)
                items_to_show.append(item)
                break
            elif item_type == TYPE_DIRECTIVE:
                # We need to include previous directives
                # so that the final search result can be properly
                # rendered (it may depend on a schema defined earlier
                # in the worksheet).
                items_to_show.append(item)
        # Make sure the search item is at the end of worksheet_info['items'],
        # so we can isolate it later after interpret_items is called.
        worksheet_info['items'] = items_to_show
        worksheet_info['items'].extend(search_results)

    # Set permissions
    worksheet_info['edit_permission'] = worksheet_info[
        'permission'] == GROUP_OBJECT_PERMISSION_ALL
    # Check enable chat box
    worksheet_info['enable_chat'] = local.config.get('enable_chat', False)
    # Format permissions into strings
    worksheet_info['permission_spec'] = permission_str(
        worksheet_info['permission'])
    for group_permission in worksheet_info['group_permissions']:
        group_permission['permission_spec'] = permission_str(
            group_permission['permission'])

    # Go and fetch more information about the worksheet contents by
    # resolving the interpreted items.
    try:
        interpreted_blocks = interpret_items(get_default_schemas(),
                                             worksheet_info['items'],
                                             db_model=local.model)
    except UsageError as e:
        interpreted_blocks = {'blocks': []}
        worksheet_info['error'] = str(e)

    # bundle_uuids is an optional argument that, if exists, contain the uuids of all the unfinished run bundles that need updating
    # In this case, full_worksheet will return a list of item parallel to ws.info.items that contain only items that need updating.
    # More specifically, all blocks that don't contain run bundles that need updating are None.
    # Also, a non-None block could contain a list of bundle_infos, which represent a list of bundles. Usually not all of them need updating.
    # The bundle_infos for bundles that don't need updating are also None.
    if bundle_uuids:
        for i, block in enumerate(interpreted_blocks['blocks']):
            if 'bundle_info' not in block:
                interpreted_blocks['blocks'][i] = None
            else:
                if isinstance(block['bundle_info'], dict):
                    block['bundle_info'] = [block['bundle_info']]
                is_relevant_block = False
                for j, bundle in enumerate(block['bundle_info']):
                    if bundle['uuid'] in bundle_uuids:
                        is_relevant_block = True
                    else:
                        block['bundle_info'][j] = None
                if not is_relevant_block:
                    interpreted_blocks['blocks'][i] = None
    # Grouped individual items into blocks
    worksheet_info['blocks'] = resolve_interpreted_blocks(
        interpreted_blocks['blocks'], brief=brief)
    worksheet_info['raw_to_block'] = interpreted_blocks['raw_to_block']
    worksheet_info['block_to_raw'] = interpreted_blocks['block_to_raw']

    if directive:
        # If we're only async loading a single table_block / subworksheets_block,
        # return only that block (which is at the end of worksheet_info['items'])
        worksheet_info['blocks'] = [worksheet_info['blocks'][-1]
                                    ] if len(search_results) else []

    for block in worksheet_info['blocks']:
        if block is None:
            continue
        if block['mode'] == 'table':
            for row_map in block['rows']:
                for k, v in row_map.items():
                    if v is None:
                        row_map[k] = formatting.contents_str(v)
        if 'bundle_info' in block:
            infos = []
            if isinstance(block['bundle_info'], list):
                infos = block['bundle_info']
            elif isinstance(block['bundle_info'], dict):
                infos = [block['bundle_info']]
            for bundle_info in infos:
                if bundle_info is None:
                    continue
                if 'bundle_type' not in bundle_info:
                    continue  # empty info: invalid bundle reference
                if isinstance(bundle_info, dict):
                    format_metadata(bundle_info.get('metadata'))
    # Frontend doesn't use individual 'items' for now
    del worksheet_info['items']
    if bundle_uuids:
        return {'blocks': worksheet_info['blocks']}
    return worksheet_info
Example #16
0
def fetch_interpreted_worksheet(uuid):
    """
    Return information about a worksheet. Calls
    - get_worksheet_info: get basic info
    - resolve_interpreted_items: get more information about a worksheet.
    In the future, for large worksheets, might want to break this up so
    that we can render something basic.
    """
    bundle_uuids = request.query.getall('bundle_uuid')
    worksheet_info = get_worksheet_info(uuid, fetch_items=True, fetch_permissions=True)

    # Shim in additional data for the frontend
    worksheet_info['items'] = resolve_items_into_infos(worksheet_info['items'])
    if worksheet_info['owner_id'] is None:
        worksheet_info['owner_name'] = None
    else:
        owner = local.model.get_user(user_id=worksheet_info['owner_id'])
        worksheet_info['owner_name'] = owner.user_name

    # Fetch items.
    worksheet_info['raw'] = get_worksheet_lines(worksheet_info)

    # Replace searches with raw items.
    # This needs to be done before get_worksheet_lines because this replaces
    # user-written raw items.
    worksheet_info['items'] = expand_raw_items(worksheet_info['items'])

    # Set permissions
    worksheet_info['edit_permission'] = worksheet_info['permission'] == GROUP_OBJECT_PERMISSION_ALL
    # Check enable chat box
    worksheet_info['enable_chat'] = local.config.get('enable_chat', False)
    # Format permissions into strings
    worksheet_info['permission_spec'] = permission_str(worksheet_info['permission'])
    for group_permission in worksheet_info['group_permissions']:
        group_permission['permission_spec'] = permission_str(group_permission['permission'])

    # Go and fetch more information about the worksheet contents by
    # resolving the interpreted items.
    try:
        interpreted_blocks = interpret_items(
            get_default_schemas(), worksheet_info['items'], db_model=local.model
        )
    except UsageError as e:
        interpreted_blocks = {'blocks': []}
        worksheet_info['error'] = str(e)

    # bundle_uuids is an optional argument that, if exists, contain the uuids of all the unfinished run bundles that need updating
    # In this case, full_worksheet will return a list of item parallel to ws.info.items that contain only items that need updating.
    # More specifically, all blocks that don't contain run bundles that need updating are None.
    # Also, a non-None block could contain a list of bundle_infos, which represent a list of bundles. Usually not all of them need updating.
    # The bundle_infos for bundles that don't need updating are also None.
    if bundle_uuids:
        for i, block in enumerate(interpreted_blocks['blocks']):
            if 'bundle_info' not in block:
                interpreted_blocks['blocks'][i] = None
            else:
                if isinstance(block['bundle_info'], dict):
                    block['bundle_info'] = [block['bundle_info']]
                is_relevant_block = False
                for j, bundle in enumerate(block['bundle_info']):
                    if bundle['uuid'] in bundle_uuids:
                        is_relevant_block = True
                    else:
                        block['bundle_info'][j] = None
                if not is_relevant_block:
                    interpreted_blocks['blocks'][i] = None

    worksheet_info['items'] = resolve_interpreted_blocks(interpreted_blocks['blocks'])
    worksheet_info['raw_to_block'] = interpreted_blocks['raw_to_block']
    worksheet_info['block_to_raw'] = interpreted_blocks['block_to_raw']

    for item in worksheet_info['items']:
        if item is None:
            continue
        if item['mode'] == 'table':
            for row_map in item['rows']:
                for k, v in row_map.items():
                    if v is None:
                        row_map[k] = formatting.contents_str(v)
        if 'bundle_info' in item:
            infos = []
            if isinstance(item['bundle_info'], list):
                infos = item['bundle_info']
            elif isinstance(item['bundle_info'], dict):
                infos = [item['bundle_info']]
            for bundle_info in infos:
                if bundle_info is None:
                    continue
                if 'bundle_type' not in bundle_info:
                    continue  # empty info: invalid bundle reference
                if isinstance(bundle_info, dict):
                    format_metadata(bundle_info.get('metadata'))
    if bundle_uuids:
        return {'items': worksheet_info['items']}
    return worksheet_info