<commit_before>from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from rasa_core_sdk import Action
from rasa_core_sdk.forms import FreeTextFormField, FormAction
from rasa_core_sdk.events import SlotSet
from datetime import datetime
from difflib import SequenceMatcher

import requests
import logging
import json
import uuid
import os

logging.basicConfig(format="[NLULOGS] %(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s", level=logging.DEBUG)

auth_token = os.getenv('TOKEN_X')

BASE_URL = os.getenv('BASE_URL', 'https://staging.grassroot.org.za/v2/api')
DATETIME_URL = os.getenv('DATE_TIME_URL', 'http://learning.grassroot.cloud')

TOKEN_PATH = '/whatsapp/user/token'
GROUP_PATH = '/group/fetch/minimal/filtered'
MEETING_PATH = 

parentType = 'GROUP'
session_vote_options = {'user_id': []}
session_media_files = {'user_id': []}

permissionsMap = {
    'default': 'GROUP_PERMISSION_UPDATE_GROUP_DETAILS',
    'create_meeting': 'GROUP_PERMISSION_CREATE_GROUP_MEETING',
    'call_vote': 'GROUP_PERMISSION_CREATE_GROUP_VOTE'
}

class ActionGetGroup(Action):

    def name(self):
        return 'action_get_group'

    def run(self, dispatcher, tracker, domain):
        current_action = tracker.get_slot("action")
        if current_action is None: 
            current_action = "default"
        logging.info("Fetching groups, action = %s, required permission = %s" % (current_action, permissionsMap[current_action]))
        dispatcher.utter_button_message("Choose a group", get_group_menu_items(tracker.sender_id, permissionsMap[current_action]))
        return []


def get_group_menu_items(sender_id, required_permission = permissionsMap['default']):
    full_url = BASE_URL + GROUP_PATH + "?requiredPermission=" + required_permission 
    raw_json = json.loads(requests.get(full_url, headers={'Authorization': 'Bearer ' + get_token(sender_id)}).text)
    page_content = raw_json['content']
    logging.info('Page content: %s' % page_content)
    menu_items = []
    try:
        logging.info('How many groups do we have? %d' % len(page_content))
        for group in range(len(page_content)):
            menu_items.append({'title': page_content[group]['name'], 'payload': 'group::' + page_content[group]['groupUid']})
    except KeyError as e:
        logging.error('GAAAH! The child of Fort Knox sprang a leak and is dying. platform_actions.py: get_group_menu_items(): %s' % str(e))
        return []
    return menu_items


class ActionSaveGroup(Action):

    def name(self):
        return 'action_utter_save_selected_group'

    def run(self, dispatcher, tracker, domain):
        group = (tracker.latest_message)['text']
        return [SlotSet("group", group)]


class ActionCreateMeetingRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("location"),
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_create_meeting_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as your location." % tracker.get_slot("location"),
                     "You have chosen %s as your subject." % tracker.get_slot("subject"),
                     "You have described this meeting as %s." % tracker.get_slot("description"),
                     "You want this to happen %s." % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionCreateVoteRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]
        # voteOptions are acquired through a different Action

    def name(self):
        return 'action_create_vote_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as your subject of your vote." % tracker.get_slot("subject"),
                     "You have described this vote as %s" % tracker.get_slot("description"),
                     "You want this to happen %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoInfoRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("response_tag"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_info_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as the subject of this todo." % tracker.get_slot("subject"),
                     "You have described this todo as %s" % tracker.get_slot("description"),
                     "You would like participant responses to be tagged with a '%s'" % tracker.get_slot("response_tag"),
                     "Participants may respond until %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoVolunteerRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_volunteer_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s the subject of this volunteer task." % tracker.get_slot("subject"),
                     "You have described this volunteer task as %s" % tracker.get_slot("description"),
                     "You want this to happen %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoValidationRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_validation_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as subject of validation." % tracker.get_slot("subject"),
                     "You have described this validation as %s." % tracker.get_slot("description"),
                     "You want everyone to have responded by %s." % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoActionRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_action_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                    "You have chosen %s as the subject for this action." % tracker.get_slot("subject"),
                    "You have described this action as %s" % tracker.get_slot("description"),
                    "You want this to happen %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                   ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionLivewireRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("contact_name"),
            FreeTextFormField("contact_number")
        ]

    def name(self):
        return 'action_livewire_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as the title." % tracker.get_slot("subject"),
                     "You have entered '%s' as the content." % tracker.get_slot("description"),
                     "You have identified yourself as %s" % tracker.get_slot("contact_name"),
                     "and provided %s as your contact detail." % tracker.get_slot("contact_number"),
                     # "you have also included %s media file." % traker.get_slot("session_media_keys"),
                     "You would like this to appear within the group %s." % tracker.get_slot("group"),
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionGetVoteOption(Action):

    def name(self):
        return 'action_get_vote_option'

    def run(self, dispatcher, tracker, domain):
        dispatcher.utter_message("What are your vote options?")
        return []


class ActionStoreVoteOption(Action):

    def name(self):
        return 'action_store_vote_option'

    def run(self, dispatcher, tracker, domain):
        vote_option = (tracker.latest_message)['text']

        user_id = tracker.sender_id
        if user_id in list(session_vote_options):
            session_vote_options[user_id].append(vote_option)
        else:
            session_vote_options[user_id] = [vote_option]
        return []


class CreateMeetingComplete(Action):

    def name(self):
        return 'action_create_meeting_complete'

    def run(self, dispatcher, tracker, domain):
        groupUid = get_group_uid(tracker.get_slot("group"), tracker.sender_id)
        if groupUid == '':
            dispatcher.utter_message('Could not find %s within registered groups.' % tracker.get_slot("group"))
            return []
        meeting_path = '/task/create/meeting/%s/%s' % (parentType, groupUid)
        url = BASE_URL + meeting_path
        logging.info('Constructed url for create meeting: %s' % url)
        response = requests.post(url, headers={'Authorization': 'Bearer ' + get_token(tracker.sender_id)},
                                 params={
                                         'location': tracker.get_slot("location"),
                                         'dateTimeEpochMillis': epoch(formalize(tracker.get_slot("datetime"))),
                                         'subject': tracker.get_slot("subject"),
                                         'description': tracker.get_slot("description")
                                         }
                                )
        dispatcher.utter_message('We are making it happen for you. Thank you for using our service.')
        logging.info('Constructed url for create meeting: %s' % response.url)
        logging.info('Dispatched to platform, response: %s' % response)
        clean_session(tracker.sender_id)
        return []


class CreateVoteComplete(Action):

    def name(self):
        return 'action_create_vote_complete'

    def run(self, dispatcher, tracker, domain):
        groupUid = get_group_uid(tracker.get_slot("group"), tracker.sender_id)
        if groupUid == '':
            dispatcher.utter_message('Could not find %s within registered groups.' % tracker.get_slot("group"))
            return []
        vote_path = '/task/create/vote/%s/%s' % (parentType, groupUid)
        url = BASE_URL + vote_path
        response = requests.post(url, headers={'Authorization': 'Bearer ' + get_token(tracker.sender_id)},
                                 params={<commit_msg>refined url generation<commit_after>from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from rasa_core_sdk import Action
from rasa_core_sdk.forms import FreeTextFormField, FormAction
from rasa_core_sdk.events import SlotSet
from datetime import datetime
from difflib import SequenceMatcher

import requests
import logging
import json
import uuid
import os

logging.basicConfig(format="[NLULOGS] %(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]  %(message)s", level=logging.DEBUG)

auth_token = os.getenv('TOKEN_X')

BASE_URL = os.getenv('BASE_URL', 'https://staging.grassroot.org.za/v2/api')
DATETIME_URL = os.getenv('DATE_TIME_URL', 'http://learning.grassroot.cloud')

TOKEN_PATH = '/whatsapp/user/token'
GROUP_PATH = '/group/fetch/minimal/filtered'

parentType = 'GROUP'
session_vote_options = {'user_id': []}
session_media_files = {'user_id': []}

permissionsMap = {
    'default': 'GROUP_PERMISSION_UPDATE_GROUP_DETAILS',
    'create_meeting': 'GROUP_PERMISSION_CREATE_GROUP_MEETING',
    'call_vote': 'GROUP_PERMISSION_CREATE_GROUP_VOTE'
}

class ActionGetGroup(Action):

    def name(self):
        return 'action_get_group'

    def run(self, dispatcher, tracker, domain):
        current_action = tracker.get_slot("action")
        if current_action is None: 
            current_action = "default"
        logging.info("Fetching groups, action = %s, required permission = %s" % (current_action, permissionsMap[current_action]))
        dispatcher.utter_button_message("Choose a group", get_group_menu_items(tracker.sender_id, permissionsMap[current_action]))
        return []


def get_group_menu_items(sender_id, required_permission = permissionsMap['default']):
    full_url = BASE_URL + GROUP_PATH + "?requiredPermission=" + required_permission 
    raw_json = json.loads(requests.get(full_url, headers={'Authorization': 'Bearer ' + get_token(sender_id)}).text)
    page_content = raw_json['content']
    logging.info('Page content: %s' % page_content)
    menu_items = []
    try:
        logging.info('How many groups do we have? %d' % len(page_content))
        for group in range(len(page_content)):
            menu_items.append({'title': page_content[group]['name'], 'payload': 'group::' + page_content[group]['groupUid']})
    except KeyError as e:
        logging.error('GAAAH! The child of Fort Knox sprang a leak and is dying. platform_actions.py: get_group_menu_items(): %s' % str(e))
        return []
    return menu_items


class ActionSaveGroup(Action):

    def name(self):
        return 'action_utter_save_selected_group'

    def run(self, dispatcher, tracker, domain):
        group = (tracker.latest_message)['text']
        return [SlotSet("group", group)]


class ActionCreateMeetingRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("location"),
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_create_meeting_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as your location." % tracker.get_slot("location"),
                     "You have chosen %s as your subject." % tracker.get_slot("subject"),
                     "You have described this meeting as %s." % tracker.get_slot("description"),
                     "You want this to happen %s." % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionCreateVoteRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]
        # voteOptions are acquired through a different Action

    def name(self):
        return 'action_create_vote_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as your subject of your vote." % tracker.get_slot("subject"),
                     "You have described this vote as %s" % tracker.get_slot("description"),
                     "You want this to happen %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoInfoRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("response_tag"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_info_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as the subject of this todo." % tracker.get_slot("subject"),
                     "You have described this todo as %s" % tracker.get_slot("description"),
                     "You would like participant responses to be tagged with a '%s'" % tracker.get_slot("response_tag"),
                     "Participants may respond until %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoVolunteerRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_volunteer_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s the subject of this volunteer task." % tracker.get_slot("subject"),
                     "You have described this volunteer task as %s" % tracker.get_slot("description"),
                     "You want this to happen %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoValidationRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_validation_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as subject of validation." % tracker.get_slot("subject"),
                     "You have described this validation as %s." % tracker.get_slot("description"),
                     "You want everyone to have responded by %s." % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionTodoActionRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("datetime")
        ]

    def name(self):
        return 'action_todo_action_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                    "You have chosen %s as the subject for this action." % tracker.get_slot("subject"),
                    "You have described this action as %s" % tracker.get_slot("description"),
                    "You want this to happen %s" % tracker.get_slot("datetime"),
                     "You have chosen %s as your group." % tracker.get_slot("group")
                   ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionLivewireRoutine(FormAction):

    RANDOMIZE = False

    @staticmethod
    def required_fields():
        return [
            FreeTextFormField("subject"),
            FreeTextFormField("description"),
            FreeTextFormField("contact_name"),
            FreeTextFormField("contact_number")
        ]

    def name(self):
        return 'action_livewire_routine'

    def submit(self, dispatcher, tracker, domain):
        responses = [
                     "You have chosen %s as the title." % tracker.get_slot("subject"),
                     "You have entered '%s' as the content." % tracker.get_slot("description"),
                     "You have identified yourself as %s" % tracker.get_slot("contact_name"),
                     "and provided %s as your contact detail." % tracker.get_slot("contact_number"),
                     # "you have also included %s media file." % traker.get_slot("session_media_keys"),
                     "You would like this to appear within the group %s." % tracker.get_slot("group"),
                    ]
        dispatcher.utter_message(' '.join(responses))
        return []


class ActionGetVoteOption(Action):

    def name(self):
        return 'action_get_vote_option'

    def run(self, dispatcher, tracker, domain):
        dispatcher.utter_message("What are your vote options?")
        return []


class ActionStoreVoteOption(Action):

    def name(self):
        return 'action_store_vote_option'

    def run(self, dispatcher, tracker, domain):
        vote_option = (tracker.latest_message)['text']

        user_id = tracker.sender_id
        if user_id in list(session_vote_options):
            session_vote_options[user_id].append(vote_option)
        else:
            session_vote_options[user_id] = [vote_option]
        return []


class CreateMeetingComplete(Action):

    def name(self):
        return 'action_create_meeting_complete'

    def run(self, dispatcher, tracker, domain):
        groupUid = get_group_uid(tracker.get_slot("group"), tracker.sender_id)
        if groupUid == '':
            dispatcher.utter_message('Could not find %s within registered groups.' % tracker.get_slot("group"))
            return []
        meeting_path = '/task/create/meeting/%s/%s' % (parentType, groupUid)
        url = BASE_URL + meeting_path
        logging.info('Constructed url for create meeting: %s' % url)
        response = requests.post(url, headers={'Authorization': 'Bearer ' + get_token(tracker.sender_id)},
                                 params={
                                         'location': tracker.get_slot("location"),
                                         'dateTimeEpochMillis': epoch(formalize(tracker.get_slot("datetime"))),
                                         'subject': tracker.get_slot("subject"),
                                         'description': tracker.get_slot("description")
                                         })
        dispatcher.utter_message('We are making it happen for you. Thank you for using our service.')
        logging.info('Constructed url for create meeting: %s' % response.url)
        logging.info('Dispatched to platform, response: %s' % response)
        clean_session(tracker.sender_id)
        return []


class CreateVoteComplete(Action):

    def name(self):
        return 'action_create_vote_complete'

    def run(self, dispatcher, tracker, domain):
        groupUid = get_group_uid(tracker.get_slot("group"), tracker.sender_id)
        if groupUid == '':
            dispatcher.utter_message('Could not find %s within registered groups.' % tracker.get_slot("group"))
            return []
        vote_path = '/task/create/vote/%s/%s' % (parentType, groupUid)
        url = BASE_URL + vote_path
        response = requests.post(url, headers={'Authorization': 'Bearer ' + get_token(tracker.sender_id)},
                                 params={
{'fraction_non_alphanumeric': 0.10695468914646997, 'fraction_numerical': 0.0005673988814136338, 'mean_word_length': 2.466076696165192, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5092732', 'n_tokens_mistral': 6847, 'n_tokens_neox': 6524, 'n_words': 1600}