<commit_before>__author__ = 'topcircler'

import datetime

import endpoints
from protorpc import remote
from protorpc import messages
from protorpc import message_types
from google.appengine.datastore.datastore_query import Cursor
from google.appengine.ext.db import BadValueError

from helper.settings import anno_js_client_id
from helper.utils import auth_user
from model.anno import Anno
from model.follow_up import FollowUp
from model.userannostate import UserAnnoState
from message.followup_message import FollowupMessage
from message.followup_message import FollowupListMessage
from helper.utils import put_search_document
from helper.activity_push_notifications import ActivityPushNotifications
from helper.utils_enum import AnnoActionType
from helper.utils_enum import SearchIndexName

@endpoints.api(name='followup', version='1.0', description='Followup API',
               allowed_client_ids=[endpoints.API_EXPLORER_CLIENT_ID, anno_js_client_id])
class FollowupApi(remote.Service):
    """
    Class which defines Follow up API v1.
    """

    @endpoints.method(FollowupMessage, FollowupMessage, path='followup', http_method='POST', name='followup.insert')
    def followup_insert(self, request):
        """
        Exposes and API endpoint to insert a follow up for the current user.
        """
        user = auth_user(self.request_state.headers)

        anno = Anno.get_by_id(request.anno_id)
        if anno is None:
            raise endpoints.NotFoundException('No anno entity with the id "%s" exists.' % request.id)

        followup = FollowUp()
        followup.anno_key = anno.key
        followup.creator = user.key
        followup.comment = request.comment
        if request.created is not None:
            followup.created = request.created
        followup.put()

        anno.followup_count += 1
        anno.last_update_time = datetime.datetime.now()
        anno.last_activity = 'follwup'
        anno.last_update_type = 'create'
        anno.put()

        # update user anno state
        UserAnnoState.insert(user=user, anno=anno)

        # update search document
        put_search_document(anno.generate_search_document(), SearchIndexName.ANNO)
        put_search_document(followup.generate_search_document(), SearchIndexName.FOLLOWUP)

        # send notifications
        ActivityPushNotifications.send_push_notification(first_user=user, anno=anno, action_type=AnnoActionType.COMMENTED,
                                                         comment=request.comment)

        return followup.to_message()

    followup_with_id_resource_container = endpoints.ResourceContainer(
        message_types.VoidMessage,
        id=messages.IntegerField(2, required=True)
    )

    @endpoints.method(followup_with_id_resource_container, message_types.VoidMessage, path='followup/{id}',
                      http_method='DELETE', name='followup.delete')
    def followup_delete(self, request):
        """
        Exposes an API endpoint to delete an existing follow up.
        """
        user = auth_user(self.request_state.headers)
        if request.id is None:
            raise endpoints.BadRequestException('id field is required.')
        followup = FollowUp.get_by_id(request.id)
        if followup is None:
            raise endpoints.NotFoundException('No follow up entity with the id "%s" exists.' % request.id)
        anno = followup.anno_key.get()<commit_msg>[GAE Server] Finding and inserting hashtags in database from followup when user insert a followup<commit_after>__author__ = 'topcircler'

import datetime

import endpoints
from protorpc import remote
from protorpc import messages
from protorpc import message_types
from google.appengine.datastore.datastore_query import Cursor
from google.appengine.ext.db import BadValueError

from helper.settings import anno_js_client_id
from helper.utils import auth_user
from model.anno import Anno
from model.follow_up import FollowUp
from model.userannostate import UserAnnoState
from message.followup_message import FollowupMessage
from message.followup_message import FollowupListMessage
from helper.utils import put_search_document
from helper.activity_push_notifications import ActivityPushNotifications
from helper.utils_enum import AnnoActionType
from helper.utils_enum import SearchIndexName

@endpoints.api(name='followup', version='1.0', description='Followup API',
               allowed_client_ids=[endpoints.API_EXPLORER_CLIENT_ID, anno_js_client_id])
class FollowupApi(remote.Service):
    """
    Class which defines Follow up API v1.
    """

    @endpoints.method(FollowupMessage, FollowupMessage, path='followup', http_method='POST', name='followup.insert')
    def followup_insert(self, request):
        """
        Exposes and API endpoint to insert a follow up for the current user.
        """
        user = auth_user(self.request_state.headers)

        anno = Anno.get_by_id(request.anno_id)
        if anno is None:
            raise endpoints.NotFoundException('No anno entity with the id "%s" exists.' % request.id)

        followup = FollowUp()
        followup.anno_key = anno.key
        followup.creator = user.key
        followup.comment = request.comment
        if request.created is not None:
            followup.created = request.created
        followup.put()

        anno.followup_count += 1
        anno.last_update_time = datetime.datetime.now()
        anno.last_activity = 'follwup'
        anno.last_update_type = 'create'
        anno.put()

        # update user anno state
        UserAnnoState.insert(user=user, anno=anno)

        # update search document
        put_search_document(anno.generate_search_document(), SearchIndexName.ANNO)
        put_search_document(followup.generate_search_document(), SearchIndexName.FOLLOWUP)

        # find all hashtags
        tags = extract_tags_from_text(followup.comment.lower())
        for tag, count in tags.iteritems():
            # Write the cumulative amount per tag
            Tag.add_tag_total(tag, total=count)

        # send notifications
        ActivityPushNotifications.send_push_notification(first_user=user, anno=anno, action_type=AnnoActionType.COMMENTED,
                                                         comment=request.comment)

        return followup.to_message()

    followup_with_id_resource_container = endpoints.ResourceContainer(
        message_types.VoidMessage,
        id=messages.IntegerField(2, required=True)
    )

    @endpoints.method(followup_with_id_resource_container, message_types.VoidMessage, path='followup/{id}',
                      http_method='DELETE', name='followup.delete')
    def followup_delete(self, request):
        """
        Exposes an API endpoint to delete an existing follow up.
        """
        user = auth_user(self.request_state.headers)
        if request.id is None:
            raise endpoints.BadRequestException('id field is required.')
        followup = FollowUp.get_by_id(request.id)
        if followup is None:
            raise endpoints.NotFoundException('No follow up entity with the id "%s" exists.' % request.id)
        anno = followup.anno_key.get()
{'fraction_non_alphanumeric': 0.07711686494051785, 'fraction_numerical': 0.0013995801259622112, 'mean_word_length': 3.230905861456483, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4720578', 'n_tokens_mistral': 1996, 'n_tokens_neox': 1942, 'n_words': 477}