(self, sketch_id)
return self.to_json(sketch, meta=meta)
Handles GET request to the resource.

        Returns:
            A sketch in JSON (instance of flask.wrappers.Response)
Handles GET request to the resource.
Handles GET request to the resource .
def get(self, sketch_id):
        """Handles GET request to the resource.

        Returns:
            A sketch in JSON (instance of flask.wrappers.Response)
        """
        if current_user.admin:
            sketch = Sketch.query.get(sketch_id)
            if not sketch.has_permission(current_user, 'read'):
                return self._get_sketch_for_admin(sketch)
        else:
            sketch = Sketch.query.get_with_acl(sketch_id)

        if not sketch:
            abort(
                HTTP_STATUS_CODE_NOT_FOUND, 'No sketch found with this ID.')

        aggregators = {}
        for _, cls in aggregator_manager.AggregatorManager.get_aggregators():
            aggregators[cls.NAME] = {
                'form_fields': cls.FORM_FIELDS,
                'display_name': cls.DISPLAY_NAME,
                'description': cls.DESCRIPTION
            }

        # Get mappings for all indices in the sketch. This is used to set
        # columns shown in the event list.
        sketch_indices = [
            t.searchindex.index_name
            for t in sketch.active_timelines
        ]

        # Make sure the list of index names is uniq
        sketch_indices = list(set(sketch_indices))

        # Get event count and size on disk for each index in the sketch.
        indices_metadata = {}
        stats_per_timeline = {}
        for timeline in sketch.active_timelines:
            indices_metadata[timeline.searchindex.index_name] = {}
            stats_per_timeline[timeline.id] = {
                'count': 0
            }

        if not sketch_indices:
            mappings_settings = {}
        else:
            try:
                mappings_settings = self.datastore.client.indices.get_mapping(
                    index=sketch_indices)
            except opensearchpy.NotFoundError:
                logger.error(
                    'Unable to get indices mapping in datastore, for '
                    'indices: {0:s}'.format(','.join(sketch_indices)))
                mappings_settings = {}

        mappings = []

        for index_name, value in mappings_settings.items():
            # The structure is different in ES version 6.x and lower. This check
            # makes sure we support both old and new versions.
            properties = value['mappings'].get('properties')
            if not properties:
                properties = next(
                    iter(value['mappings'].values())).get('properties')

            # Determine if index is from the time before multiple timelines per
            # index. This is used in the UI to support both modes.
            is_legacy = bool('__ts_timeline_id' not in properties)
            indices_metadata[index_name]['is_legacy'] = is_legacy

            for field, value_dict in properties.items():
                mapping_dict = {}
                # Exclude internal fields
                if field.startswith('__'):
                    continue
                if field == 'timesketch_label':
                    continue
                mapping_dict['field'] = field
                mapping_dict['type'] = value_dict.get('type', 'n/a')
                mappings.append(mapping_dict)

        # Get number of events per timeline
        if sketch_indices:
            # Support legacy indices.
            for timeline in sketch.active_timelines:
                index_name = timeline.searchindex.index_name
                if indices_metadata[index_name].get('is_legacy', False):
                    doc_count, _ = self.datastore.count(indices=index_name)
                    stats_per_timeline[timeline.id] = {'count': doc_count}
            count_agg_spec = {
                'aggs': {
                    'per_timeline': {
                        'terms': {
                            'field': '__ts_timeline_id',
                            'size': len(sketch.timelines),
                        }
                    }
                }
            }
            # pylint: disable=unexpected-keyword-arg, no-value-for-parameter
            count_agg = self.datastore.client.search(
                index=sketch_indices, body=count_agg_spec, size=0)

            count_per_timeline = count_agg.get(
                'aggregations', {}).get(
                    'per_timeline', {}).get(
                        'buckets', [])
            for count_stat in count_per_timeline:
                stats_per_timeline[count_stat['key']] = {
                    'count': count_stat['doc_count']
                }

        # Make the list of dicts unique
        mappings = {v['field']: v for v in mappings}.values()

        views = []
        for view in sketch.get_named_views:
            if not view.user:
                username = 'System'
            else:
                username = view.user.username
            view = {
                'name': view.name,
                'description': view.description,
                'id': view.id,
                'query': view.query_string,
                'filter': view.query_filter,
                'user': username,
                'created_at': view.created_at,
                'updated_at': view.updated_at
            }
            views.append(view)

        views.sort(key=lambda x: x.get('name', 'Z').lower())

        stories = []
        for story in sketch.stories:
            if not story.user:
                username = 'System'
            else:
                username = story.user.username
            story = {
                'id': story.id,
                'title': story.title,
                'user': username,
                'created_at': story.created_at,
                'updated_at': story.updated_at
            }
            stories.append(story)

        meta = dict(
            aggregators=aggregators,
            views=views,
            stories=stories,
            searchtemplates=[{
                'name': searchtemplate.name,
                'id': searchtemplate.id
            } for searchtemplate in SearchTemplate.query.all()],
            emojis=get_emojis_as_dict(),
            permissions={
                'public': bool(sketch.is_public),
                'read': bool(sketch.has_permission(current_user, 'read')),
                'write': bool(sketch.has_permission(current_user, 'write')),
                'delete': bool(sketch.has_permission(current_user, 'delete')),
            },
            collaborators={
                'users': [user.username for user in sketch.collaborators],
                'groups': [group.name for group in sketch.groups],
            },
            attributes=utils.get_sketch_attributes(sketch),
            mappings=list(mappings),
            indices_metadata=indices_metadata,
            stats_per_timeline=stats_per_timeline,
            last_activity=utils.get_sketch_last_activity(sketch),
            filter_labels=self.datastore.get_filter_labels(
                sketch.id, sketch_indices),
            sketch_labels=[label.label for label in sketch.labels]
        )
        return self.to_json(sketch, meta=meta)
def get ( self , sketch_id ) : if current_user . admin : sketch = Sketch . query . get ( sketch_id ) if not sketch . has_permission ( current_user , 'read' ) : return self . _get_sketch_for_admin ( sketch ) else : sketch = Sketch . query . get_with_acl ( sketch_id ) if not sketch : abort ( HTTP_STATUS_CODE_NOT_FOUND , 'No sketch found with this ID.' ) aggregators = { } for _ , cls in aggregator_manager . AggregatorManager . get_aggregators ( ) : aggregators [ cls . NAME ] = { 'form_fields' : cls . FORM_FIELDS , 'display_name' : cls . DISPLAY_NAME , 'description' : cls . DESCRIPTION } # Get mappings for all indices in the sketch. This is used to set # columns shown in the event list. sketch_indices = [ t . searchindex . index_name for t in sketch . active_timelines ] # Make sure the list of index names is uniq sketch_indices = list ( set ( sketch_indices ) ) # Get event count and size on disk for each index in the sketch. indices_metadata = { } stats_per_timeline = { } for timeline in sketch . active_timelines : indices_metadata [ timeline . searchindex . index_name ] = { } stats_per_timeline [ timeline . id ] = { 'count' : 0 } if not sketch_indices : mappings_settings = { } else : try : mappings_settings = self . datastore . client . indices . get_mapping ( index = sketch_indices ) except opensearchpy . NotFoundError : logger . error ( 'Unable to get indices mapping in datastore, for ' 'indices: {0:s}' . format ( ',' . join ( sketch_indices ) ) ) mappings_settings = { } mappings = [ ] for index_name , value in mappings_settings . items ( ) : # The structure is different in ES version 6.x and lower. This check # makes sure we support both old and new versions. properties = value [ 'mappings' ] . get ( 'properties' ) if not properties : properties = next ( iter ( value [ 'mappings' ] . values ( ) ) ) . get ( 'properties' ) # Determine if index is from the time before multiple timelines per # index. This is used in the UI to support both modes. is_legacy = bool ( '__ts_timeline_id' not in properties ) indices_metadata [ index_name ] [ 'is_legacy' ] = is_legacy for field , value_dict in properties . items ( ) : mapping_dict = { } # Exclude internal fields if field . startswith ( '__' ) : continue if field == 'timesketch_label' : continue mapping_dict [ 'field' ] = field mapping_dict [ 'type' ] = value_dict . get ( 'type' , 'n/a' ) mappings . append ( mapping_dict ) # Get number of events per timeline if sketch_indices : # Support legacy indices. for timeline in sketch . active_timelines : index_name = timeline . searchindex . index_name if indices_metadata [ index_name ] . get ( 'is_legacy' , False ) : doc_count , _ = self . datastore . count ( indices = index_name ) stats_per_timeline [ timeline . id ] = { 'count' : doc_count } count_agg_spec = { 'aggs' : { 'per_timeline' : { 'terms' : { 'field' : '__ts_timeline_id' , 'size' : len ( sketch . timelines ) , } } } } # pylint: disable=unexpected-keyword-arg, no-value-for-parameter count_agg = self . datastore . client . search ( index = sketch_indices , body = count_agg_spec , size = 0 ) count_per_timeline = count_agg . get ( 'aggregations' , { } ) . get ( 'per_timeline' , { } ) . get ( 'buckets' , [ ] ) for count_stat in count_per_timeline : stats_per_timeline [ count_stat [ 'key' ] ] = { 'count' : count_stat [ 'doc_count' ] } # Make the list of dicts unique mappings = { v [ 'field' ] : v for v in mappings } . values ( ) views = [ ] for view in sketch . get_named_views : if not view . user : username = 'System' else : username = view . user . username view = { 'name' : view . name , 'description' : view . description , 'id' : view . id , 'query' : view . query_string , 'filter' : view . query_filter , 'user' : username , 'created_at' : view . created_at , 'updated_at' : view . updated_at } views . append ( view ) views . sort ( key = lambda x : x . get ( 'name' , 'Z' ) . lower ( ) ) stories = [ ] for story in sketch . stories : if not story . user : username = 'System' else : username = story . user . username story = { 'id' : story . id , 'title' : story . title , 'user' : username , 'created_at' : story . created_at , 'updated_at' : story . updated_at } stories . append ( story ) meta = dict ( aggregators = aggregators , views = views , stories = stories , searchtemplates = [ { 'name' : searchtemplate . name , 'id' : searchtemplate . id } for searchtemplate in SearchTemplate . query . all ( ) ] , emojis = get_emojis_as_dict ( ) , permissions = { 'public' : bool ( sketch . is_public ) , 'read' : bool ( sketch . has_permission ( current_user , 'read' ) ) , 'write' : bool ( sketch . has_permission ( current_user , 'write' ) ) , 'delete' : bool ( sketch . has_permission ( current_user , 'delete' ) ) , } , collaborators = { 'users' : [ user . username for user in sketch . collaborators ] , 'groups' : [ group . name for group in sketch . groups ] , } , attributes = utils . get_sketch_attributes ( sketch ) , mappings = list ( mappings ) , indices_metadata = indices_metadata , stats_per_timeline = stats_per_timeline , last_activity = utils . get_sketch_last_activity ( sketch ) , filter_labels = self . datastore . get_filter_labels ( sketch . id , sketch_indices ) , sketch_labels = [ label . label for label in sketch . labels ] ) return self . to_json ( sketch , meta = meta )