(self, sketch_id)
return self.to_json(
            searchindex, status_code=HTTP_STATUS_CODE_CREATED)
Handles POST request to the resource.
        Handler for /api/v1/sketches/:sketch_id/event/create/

        Args:
            sketch_id: Integer primary key for a sketch database model

        Returns:
            An annotation in JSON (instance of flask.wrappers.Response)
Handles POST request to the resource.
        Handler for /api/v1/sketches/:sketch_id/event/create/
Handles POST request to the resource . Handler for / api / v1 / sketches / : sketch_id / event / create /
def post(self, sketch_id):
        """Handles POST request to the resource.
        Handler for /api/v1/sketches/:sketch_id/event/create/

        Args:
            sketch_id: Integer primary key for a sketch database model

        Returns:
            An annotation in JSON (instance of flask.wrappers.Response)
        """
        sketch = Sketch.query.get_with_acl(sketch_id)
        if not sketch:
            abort(
                HTTP_STATUS_CODE_NOT_FOUND, 'No sketch found with this ID.')

        if not sketch.has_permission(current_user, 'write'):
            abort(HTTP_STATUS_CODE_FORBIDDEN,
                  'User does not have write access controls on sketch.')

        form = request.json
        if not form:
            form = request.data

        timeline_name = 'sketch specific timeline'
        index_name_seed = 'timesketch_{0:d}'.format(sketch_id)
        event_type = 'user_created_event'

        date_string = form.get('date_string')
        if not date_string:
            date = datetime.datetime.utcnow().isoformat()
        else:
            # derive datetime from timestamp:
            try:
                date = dateutil.parser.parse(date_string)
            except (dateutil.parser.ParserError, OverflowError) as e:
                logger.error('Unable to convert date string', exc_info=True)
                abort(
                    HTTP_STATUS_CODE_BAD_REQUEST,
                    'Unable to add event, not able to convert the date '
                    'string. Was it properly formatted? Error: '
                    '{0!s}'.format(e))

        timestamp = int(
            time.mktime(date.utctimetuple())) * 1000000
        timestamp += date.microsecond

        event = {
            'datetime': date_string,
            'timestamp': timestamp,
            'timestamp_desc': form.get('timestamp_desc', 'Event Happened'),
            'message': form.get('message', 'No message string'),
        }

        attributes = form.get('attributes', {})
        if not isinstance(attributes, dict):
            abort(
                HTTP_STATUS_CODE_BAD_REQUEST,
                'Unable to add an event where the attributes are not a '
                'dict object.')

        event.update(attributes)

        tag = form.get('tag', [])
        if not isinstance(tag, list):
            abort(
                HTTP_STATUS_CODE_BAD_REQUEST,
                'Unable to add an event where the tags are not a '
                'list of strings.')

        if tag and any(not isinstance(x, str) for x in tag):
            abort(
                HTTP_STATUS_CODE_BAD_REQUEST,
                'Unable to add an event where the tags are not a '
                'list of strings.')

        event['tag'] = tag

        # We do not need a human readable filename or
        # datastore index name, so we use UUIDs here.
        index_name = hashlib.md5(index_name_seed.encode()).hexdigest()
        if six.PY2:
            index_name = codecs.decode(index_name, 'utf-8')

        # Try to create index
        timeline = None
        try:
            # Create the index in OpenSearch (unless it already exists)
            self.datastore.create_index(
                index_name=index_name,
                doc_type=event_type)

            # Create the search index in the Timesketch database
            searchindex = SearchIndex.get_or_create(
                name=timeline_name,
                description='internal timeline for user-created events',
                user=current_user,
                index_name=index_name)
            searchindex.grant_permission(
                permission='read', user=current_user)
            searchindex.grant_permission(
                permission='write', user=current_user)
            searchindex.grant_permission(
                permission='delete', user=current_user)
            searchindex.set_status('ready')
            db_session.add(searchindex)
            db_session.commit()

            if sketch and sketch.has_permission(current_user, 'write'):
                self.datastore.import_event(
                    index_name,
                    event_type,
                    event,
                    flush_interval=1)

                timeline = Timeline.get_or_create(
                    name=searchindex.name,
                    description=searchindex.description,
                    sketch=sketch,
                    user=current_user,
                    searchindex=searchindex)

                if timeline not in sketch.timelines:
                    sketch.timelines.append(timeline)

                timeline.set_status('ready')
                db_session.add(timeline)
                db_session.commit()

        # TODO: Can this be narrowed down, both in terms of the scope it
        # applies to, as well as not to catch a generic exception.
        except Exception as e:  # pylint: disable=broad-except
            abort(
                HTTP_STATUS_CODE_BAD_REQUEST,
                'Failed to add event ({0!s})'.format(e))

        # Return Timeline if it was created.
        # pylint: disable=no-else-return
        if timeline:
            return self.to_json(
                timeline, status_code=HTTP_STATUS_CODE_CREATED)

        return self.to_json(
            searchindex, status_code=HTTP_STATUS_CODE_CREATED)
def post ( self , sketch_id ) : sketch = Sketch . query . get_with_acl ( sketch_id ) if not sketch : abort ( HTTP_STATUS_CODE_NOT_FOUND , 'No sketch found with this ID.' ) if not sketch . has_permission ( current_user , 'write' ) : abort ( HTTP_STATUS_CODE_FORBIDDEN , 'User does not have write access controls on sketch.' ) form = request . json if not form : form = request . data timeline_name = 'sketch specific timeline' index_name_seed = 'timesketch_{0:d}' . format ( sketch_id ) event_type = 'user_created_event' date_string = form . get ( 'date_string' ) if not date_string : date = datetime . datetime . utcnow ( ) . isoformat ( ) else : # derive datetime from timestamp: try : date = dateutil . parser . parse ( date_string ) except ( dateutil . parser . ParserError , OverflowError ) as e : logger . error ( 'Unable to convert date string' , exc_info = True ) abort ( HTTP_STATUS_CODE_BAD_REQUEST , 'Unable to add event, not able to convert the date ' 'string. Was it properly formatted? Error: ' '{0!s}' . format ( e ) ) timestamp = int ( time . mktime ( date . utctimetuple ( ) ) ) * 1000000 timestamp += date . microsecond event = { 'datetime' : date_string , 'timestamp' : timestamp , 'timestamp_desc' : form . get ( 'timestamp_desc' , 'Event Happened' ) , 'message' : form . get ( 'message' , 'No message string' ) , } attributes = form . get ( 'attributes' , { } ) if not isinstance ( attributes , dict ) : abort ( HTTP_STATUS_CODE_BAD_REQUEST , 'Unable to add an event where the attributes are not a ' 'dict object.' ) event . update ( attributes ) tag = form . get ( 'tag' , [ ] ) if not isinstance ( tag , list ) : abort ( HTTP_STATUS_CODE_BAD_REQUEST , 'Unable to add an event where the tags are not a ' 'list of strings.' ) if tag and any ( not isinstance ( x , str ) for x in tag ) : abort ( HTTP_STATUS_CODE_BAD_REQUEST , 'Unable to add an event where the tags are not a ' 'list of strings.' ) event [ 'tag' ] = tag # We do not need a human readable filename or # datastore index name, so we use UUIDs here. index_name = hashlib . md5 ( index_name_seed . encode ( ) ) . hexdigest ( ) if six . PY2 : index_name = codecs . decode ( index_name , 'utf-8' ) # Try to create index timeline = None try : # Create the index in OpenSearch (unless it already exists) self . datastore . create_index ( index_name = index_name , doc_type = event_type ) # Create the search index in the Timesketch database searchindex = SearchIndex . get_or_create ( name = timeline_name , description = 'internal timeline for user-created events' , user = current_user , index_name = index_name ) searchindex . grant_permission ( permission = 'read' , user = current_user ) searchindex . grant_permission ( permission = 'write' , user = current_user ) searchindex . grant_permission ( permission = 'delete' , user = current_user ) searchindex . set_status ( 'ready' ) db_session . add ( searchindex ) db_session . commit ( ) if sketch and sketch . has_permission ( current_user , 'write' ) : self . datastore . import_event ( index_name , event_type , event , flush_interval = 1 ) timeline = Timeline . get_or_create ( name = searchindex . name , description = searchindex . description , sketch = sketch , user = current_user , searchindex = searchindex ) if timeline not in sketch . timelines : sketch . timelines . append ( timeline ) timeline . set_status ( 'ready' ) db_session . add ( timeline ) db_session . commit ( ) # TODO: Can this be narrowed down, both in terms of the scope it # applies to, as well as not to catch a generic exception. except Exception as e : # pylint: disable=broad-except abort ( HTTP_STATUS_CODE_BAD_REQUEST , 'Failed to add event ({0!s})' . format ( e ) ) # Return Timeline if it was created. # pylint: disable=no-else-return if timeline : return self . to_json ( timeline , status_code = HTTP_STATUS_CODE_CREATED ) return self . to_json ( searchindex , status_code = HTTP_STATUS_CODE_CREATED )