示例#1
0
 def __init__(self, delay, thread_logging = True):
     self.oauth = Oauth()
     self.chats = Chats()
     self.delay = delay
     self.thread_logging = thread_logging
     self.queue = []
     self.polling = True
     self.thread = None
示例#2
0
 def __init__(self, name='Fibot', local=False, debug=True):
     self.local = local
     self.debug = debug
     self.name = name
     self.bot_token = getenv('FibotTOKEN')
     self.chats = Chats()
     self.oauth = Oauth()
     self.qa = Query_answer_unit()
     self.message_handler = None
     self.delay = 60
     self.refresh_token_thread = None
     self.notification_thread = None
     self.messages = {}
     self.state_machine = {'MessageHandler': '0', 'Wait_authorisation': '1'}
示例#3
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     access_token = Chats().get_chat_lite(chat_id)['access_token']
     if not access_token:
         dispatcher.utter_message("{}".format(
             Not_understood(user_lang, 'not_logged')))
         print(colored("El usuario NO está identificado en el Racó", 'red'))
         return [SlotSet('user_logged', False)]
     else:
         print(colored("El usuario está identificado en el Racó", 'green'))
         return [SlotSet('user_logged', True)]
示例#4
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     subject_acro = tracker.get_slot("subject_acronym").upper()
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     access_token = Chats().get_chat_lite(chat_id)['access_token']
     response = API_raco().get_schedule(access_token, user_lang,
                                        subject_acro)
     for data in response:
         lecture = Lecture(data, user_lang)
         dispatcher.utter_message("{}".format(lecture))
     return []
示例#5
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     subject_acro = tracker.get_slot("subject_acronym").upper()
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     teachers_info = API_raco().get_subject_teachers(acronym=subject_acro,
                                                     language=user_lang)
     teachers_info = Subject_teachers(subject_acro, teachers_info,
                                      user_lang)
     if teachers_info.amount <= 4:
         for response in teachers_info.get_offices():
             dispatcher.utter_message("{}".format(response))
     else:
         answers = {
             'ca': "Aquests són els professors de {}. Qui t'interessa?!\n",
             'es': 'Éstos son los profesores de {}. ¿Quién te interesa?\n',
             'en': "These are {}'s teachers. Who are you interested in?\n"
         }
         answer = answers[user_lang].format(subject_acro)
         for teacher in teachers_info.get_names():
             answer = answer + teacher + '\n'
         dispatcher.utter_message("{}".format(answer))
         return [SlotSet("matches", True)]
     return [SlotSet("matches", False)]
示例#6
0
 def __init__(self, name='Fibot'):
     self.name = name
     self.bot_token = getenv('FibotTOKEN')
     self.chats = Chats()
     self.oauth = Oauth()
     self.nlg = NLG_unit()
     self.qa = Query_answer_unit()
     self.translator = Translator()
     self.messages = {}
     self.state_machine = {
         'MessageHandler': '0',
         'Authorise': '1',
         'Wait_authorisation': '2',
         'Erase_user': '******',
         'Push_notification': '4',
     }
示例#7
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     access_token = Chats().get_chat_lite(chat_id)['access_token']
     schedule = API_raco().get_schedule(access_token=access_token,
                                        language=user_lang)
     schedule = Schedule(schedule, user_lang)
     answer = schedule.get_response()
     if isinstance(answer, list):
         dispatcher.utter_message("{}".format(answer[0]))
     else:
         dispatcher.utter_message("{}".format(answer))
     return []
示例#8
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     subject_acro = tracker.get_slot("subject_acronym").upper()
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     access_token = Chats().get_chat_lite(chat_id)['access_token']
     if not API_raco().user_enrolled_subject(subject_acro, access_token,
                                             user_lang):
         response = str(Not_understood(user_lang, 'not_enrolled'))
         if '{}' in response:
             dispatcher.utter_message(response.format(subject_acro))
         else:
             dispatcher.utter_message(response)
         print(colored("El usuario NO está matriculado", 'red'))
         return [SlotSet("subject_enrollment", False)]
     else:
         print(colored("El usuario está matriculado", 'green'))
         return [SlotSet("subject_enrollment", True)]
示例#9
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     chat_id = tracker.sender_id
     subject_acro = tracker.get_slot("subject_acronym")
     user_lang = Chats().get_chat_lite(chat_id)['language']
     access_token = Chats().get_chat_lite(chat_id)['access_token']
     if subject_acro: acro_filter = subject_acro
     else: acro_filter = None
     pracs = list(API_raco().get_practiques(access_token=access_token,
                                            language=user_lang))
     p_e = Practical_schedule(pracs, user_lang)
     pracs = list(p_e.get_closest_pracs(range=62, acro_filter=acro_filter))
     if pracs:
         for prac in pracs:
             dispatcher.utter_message("{}".format(prac))
         tracker._reset_slots()
         return []
     dispatcher.utter_message("{}".format(
         Not_understood(user_lang, 'not_pracs')))
     return []
示例#10
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     with open('./Data/responses.json', 'rb') as fp:
         data = json.load(fp)
         responses = data['thank']
     chosen_response = randint(0, len(responses[user_lang]) - 1)
     final_response = responses[user_lang][chosen_response]
     dispatcher.utter_message("{}".format(final_response))
     return []
示例#11
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     subject_acro = tracker.get_slot("subject_acronym")
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     if subject_acro:
         subject_acro = subject_acro.upper()
         if not API_raco().subject_exists(subject_acro):
             dispatcher.utter_message(
                 str(Not_understood(user_lang, 'wrong_subject')))
         else:
             print(colored("Asignatura existe", 'green'))
             return [SlotSet("subject_existance", True)]
     else:
         dispatcher.utter_message("{}".format(
             Not_understood(user_lang, 'not_understand')))
     print(colored("Asignatura NO existe", 'red'))
     return [SlotSet("subject_existance", False)]
示例#12
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     teacher_name = tracker.get_slot("teacher_name")
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     if teacher_name:
         teacher, dist = Teachers(
             language=user_lang).get_closer_teacher(teacher_name)
         if dist <= 5:
             dispatcher.utter_message("{}".format(teacher))
         else:
             dispatcher.utter_message("{}".format(
                 Not_understood(user_lang, 'wrong_teacher')))
     else:
         dispatcher.utter_message("{}".format(
             Not_understood(user_lang, 'not_understand')))
     return []
示例#13
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     subject_acro = tracker.get_slot("subject_acronym").upper()
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     teachers_info = API_raco().get_subject_teachers(acronym=subject_acro,
                                                     language=user_lang)
     teachers_info = Subject_teachers(subject_acro, teachers_info,
                                      user_lang)
     answers = {
         'ca': "Aquests són els professors de {}:\n",
         'es': 'Éstos son los profesores de {}:\n',
         'en': "These are {}'s teachers:\n"
     }
     answer = answers[user_lang].format(subject_acro)
     for teacher in teachers_info.get_names():
         answer = answer + teacher + '\n'
     dispatcher.utter_message("{}".format(answer))
     return []
示例#14
0
 def run(self, dispatcher, tracker, domain):
     print("\nEjecutando acción:\t{}".format(
         colored(self.name(), 'yellow', attrs=['bold'])))
     print("Representación de los slots:")
     color_print_slots(tracker)
     subject_acro = tracker.get_slot("subject_acronym").upper()
     group = tracker.get_slot("group")
     chat_id = tracker.sender_id
     user_lang = Chats().get_chat_lite(chat_id)['language']
     response = list(API_raco().get_free_spots(subject_acro, user_lang))
     if not response:
         dispatcher.utter_message("{}".format(
             Not_understood(
                 user_lang,
                 'not_enrollment_possible')).format(subject_acro))
         return []
     s_s = Subject_spots(response, user_lang)
     if group:
         dispatcher.utter_message("{}".format(s_s.get_group_spots(group)))
     else:
         for group in s_s.group_info.keys():
             dispatcher.utter_message("{}".format(
                 s_s.get_group_spots(group)))
     return []
示例#15
0
class Fibot(object):
    """ This object contains information and methods to manage the bot, and interact with
		its users.

	Attributes:
		local (:obj:`bool`): Indicates if it runs from Telegram or Locally
		name (:obj:`str`): Unique identifier for the bot
		bot_token (:obj:`str`): Token to access the bot
		chats (:class:`Fibot.Chat`): Object that represents the chats
		oauth (:class:`Fibot.api.Oauth`): Object that does the oauth communication necessary
		qa (:class:`Fibot.NLP.nlg.Query_answer_unit`): Object that responds to FIB-related queries
		message_handler (:class:`Fibot.message_handler.Message_handler`): Object that handles messages
		delay (:obj:`int`): Cantidad de segundos entre escaneos en los threads
		notification_thread (:class:`Fibot.multithreading.threads.Notification_thread`): Object that enables a thread to scan for notifications.
		refresh_token_thread(:class:`Fibot.multithreading.threads.Refresh_token_thread`): Object that enables a thread to scan for tokens to refresh.
		messages (:obj:`dict`): Object that contains the Fibot configuration messages
		state_machine (:obj:`dict`): Object that simplifies the state machine management
	"""
    def __init__(self, name='Fibot', local=False, debug=True):
        self.local = local
        self.debug = debug
        self.name = name
        self.bot_token = getenv('FibotTOKEN')
        self.chats = Chats()
        self.oauth = Oauth()
        self.qa = Query_answer_unit()
        self.message_handler = None
        self.delay = 60
        self.refresh_token_thread = None
        self.notification_thread = None
        self.messages = {}
        self.state_machine = {'MessageHandler': '0', 'Wait_authorisation': '1'}

    def log(self, text):
        print(colored("LOG: {}".format(text), 'cyan'))

    """
		Loads the following components:
			chats: Loads the chats information from persistence
			message_handler: Enables it to send messages to users
			notification_thread: Starts its activation and defines the polling interval
			refresh_token_thread: Starts its activation and defines the polling interval (and the offset)
			nlu: Loads the trained models
			qa: Loads the trained models
			messages: Loads the preset messages to memory
	"""

    def load_components(self, thread_logging=True):
        self.chats.load()
        self.log("Base de datos de usuarios cargados")
        if self.local: self.message_handler = Local_Message_handler(self.chats)
        else: self.message_handler = Message_handler(self.chats)

        self.refresh_token_thread = Refresh_token_thread(
            self.delay, thread_logging=thread_logging)
        self.refresh_token_thread.run(initial_offset=30)

        self.notification_thread = Notification_thread(
            self.message_handler, self.delay, thread_logging=thread_logging)
        self.notification_thread.run()
        self.log("Threads creados")

        self.qa.load()
        with open('./Data/messages.json', 'r') as fp:
            self.messages = json.load(fp)
        self.log("Mensajes predefinidos cargados")
        return

    """
		Parameters:
			chat_id (:obj:`int`): chat id of the user to send the message to
			action (:obj:`str`): defines the action to send the user (default is typing)

		This function sends an action to the chat with chat_id (using ChatAction helper)
	"""

    def send_chat_action(self, chat_id, action=ChatAction.TYPING):
        self.message_handler.send_chat_action(chat_id, message, typing,
                                              reply_to)

    """
		Parameters:
			chat_id (:obj:`int`): chat id of the user to send the message to
			message (:obj:`str`): content of the message to be sent
			typing (:obj:`bool`): value that defines whether to send typing action or not
			reply_to (:obj:`int` or None): If defined, it is the message_id of the message
				that will be replied to, else no message will be replied.
			parse_mode (:obj:`str`): The parse mode to use (normally Markdown or None)

		This function sends a message to the chat with chat_id with content text,
		and depending on the rest of the parameters it might do extra functionality.
	"""

    def send_message(self,
                     chat_id,
                     message,
                     typing=False,
                     reply_to=None,
                     parse_mode='Markdown'):
        self.message_handler.send_message(chat_id, message, typing, reply_to,
                                          parse_mode)

    """
		Parameters:
			chat_id (:obj:`str`): chat_id of the user to send the message to
			preset (:obj:`str`): the preset of the message to send
			param (:obj:`str` or None): the parameter of the messages

		This function sends a preset message to the user with user id.
		See /Data/messages.json to see the preset messages.
	"""

    def send_preset_message(self, chat_id, preset, param=None):
        user_lang = self.chats.get_chat(chat_id)['language']
        if param:
            message = self.messages[user_lang][preset].format(param)
        else:
            message = self.messages[user_lang][preset]
        if 'set_lang' in message:
            self.send_message(chat_id, message, typing=True, parse_mode=None)
        else:
            self.send_message(chat_id, message, typing=True)

    """
		Parameters:
			chat_id (:obj:`str`): chat_id of the user that sent the messages
			message (:obj:`str`): text the user sent
			message_id (:obj:`int`): message_id of the message to reply to


		This function receives a message from a user and decides which mechanism is responsible
		for responding the message.
	"""

    def process_income_message(self, chat_id, message, message_id=None):
        user_language = self.chats.get_chat(chat_id)['language']
        now = time()
        response = self.qa.get_response(message,
                                        sender_id=chat_id,
                                        language=user_language,
                                        debug=self.debug)
        response = [i['text'] for i in response]
        self.send_message(chat_id,
                          response,
                          typing=True,
                          reply_to=message_id,
                          parse_mode=None)
示例#16
0
class Fibot(object):
    """ This object contains information and methods to manage the bot, and interact with
		its users.

	Attributes:
		name(:obj:`str`): Unique identifier for the bot
		bot_token(:obj:`str`): Token to access the bot
		chats(:class:`Fibot.Chat`): Object that represents the chats
		oauth(:class:`Fibot.api.Oauth`): Object that does the oauth communication necessary
		nlg(:class:`Fibot.NLP.nlg.NLG_unit`): Object that interacts with non FIB messages
		~ query_answer(:class:`Fibot.NLP.nlg.Query_answer_unit`): Object that responds to FIB-related queries
		translator(:class:`Fibot.NLP.language.Translator`): Object that eases the translation of the messages
		messages(:obj:`dict`): Object that contains the Fibot configuration messages
		state_machine(:obj:`dict`): Object that simplifies the state machine management
	"""
    def __init__(self, name='Fibot'):
        self.name = name
        self.bot_token = getenv('FibotTOKEN')
        self.chats = Chats()
        self.oauth = Oauth()
        self.nlg = NLG_unit()
        self.qa = Query_answer_unit()
        self.translator = Translator()
        self.messages = {}
        self.state_machine = {
            'MessageHandler': '0',
            'Authorise': '1',
            'Wait_authorisation': '2',
            'Erase_user': '******',
            'Push_notification': '4',
        }

    """
		Loads the following components:
			chats: Loads the chats information from persistence
			nlu: Loads the trained model
			nlg: Loads the trained model
	"""

    def load_components(self):
        self.chats.load()
        print("Chats loaded")
        self.nlg.load()
        print("NLG model loaded")
        self.qa.load(train=False)
        print("Query answering model loaded")
        with open('./Data/messages.json', 'r') as fp:
            self.messages = json.load(fp)
        print("Preset messages loaded")

    """
		Sends an action to a chat (using ChatAction helper)
	"""

    def send_chat_action(self, chat_id, action=ChatAction.TYPING):
        params = {'chat_id': chat_id, 'action': action}
        base_url = 'https://api.telegram.org/bot{}/sendChatAction'.format(
            self.bot_token)
        response = requests.get(base_url, params=params)

    """
		Sends a message to the chat with chat_id with content text
	"""

    def send_message(self, chat_id, message, typing=False, reply_to=None):
        ini = time()
        if isinstance(message, list):
            for item in message:
                self.send_message(chat_id, item, typing, reply_to)
        else:
            if typing: self.send_chat_action(chat_id)
            print("chat action sent in {}".format((time() - ini)))
            user_language = self.chats.get_chat(chat_id)['language']
            if user_language != 'English':
                urls = re.findall(
                    'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',
                    message)
                if urls: message = message.replace(urls[0], "{}")
                message = self.translator.translate(message, to=user_language)
                if urls: message = message.format(urls[0])

            params = {'chat_id': chat_id, 'text': message}
            if reply_to: params['reply_to_message_id'] = reply_to
            base_url = 'https://api.telegram.org/bot{}/sendMessage'.format(
                self.bot_token)
            response = requests.get(base_url, params=params)
            print("message sent in {}".format((time() - ini)))

    """
		Parameters:
			chat_id (:obj:`str`): chat_id of the user to send the message to
			preset (:obj:`str`): the preset of the message to send
			param (:obj:`str` or None): the parameter of the messages

		This function sends a preset message to the user with user id.
		See /Data/messages.json to see the preset messages.
	"""

    def send_preset_message(self, chat_id, preset, param=None):
        print("sending {}".format(preset))
        if param:
            message = self.messages[preset].format(param)
        else:
            message = self.messages[preset]
        self.send_message(chat_id, message, typing=True)

    """
		Parameters:
			chat_id (:obj:`str`): chat_id of the user that sent the messages
			message (:obj:`str`): text the user sent

		This function receives a message from a user and decides which mechanism is responsible
		for responding the message.
	"""

    def process_income_message(self,
                               chat_id,
                               message,
                               message_id=None,
                               debug=False):
        print("Processing income message...")
        user_language = self.chats.get_chat(chat_id)['language']
        if user_language != 'English':
            message = self.translator.translate(message,
                                                to='English',
                                                _from=user_language)
        ini = time()
        response = self.qa.get_response(message, sender_id=chat_id)
        print("Getting response time is {}".format((time() - ini)))
        print(response)
        if message_id:
            self.send_message(chat_id,
                              response,
                              typing=True,
                              reply_to=message_id)
        else:
            self.send_message(chat_id, response, typing=True)
示例#17
0
from Fibot.chats import Chats
from Fibot.api.api_raco import API_raco
from Fibot.Data.data_types.exam import Exam_schedule
from Fibot.Data.data_types.practical_work import Practical_schedule
from pprint import pprint

c = Chats()
c.load()
a = API_raco()
a_t = c.get_chat('349611162')['access_token']
user_lang = c.get_chat('349611162')['language']
exams = list(a.get_exams_user(a_t))
e_e = Exam_schedule(exams, user_lang)

pprint(list(e_e.get_closest_exams(range=50)))

pracs = list(a.get_practiques(a_t))
p_e = Practical_schedule(pracs, user_lang)

pprint(list(p_e.get_closest_pracs(range=50)))
示例#18
0
class Refresh_token_thread(object):

    """This class enables multithreading capabilities by using an extra thread to scan looking for
    chats with expired tokens to refresh.

        Attributes:
            oauth(:class:`Fibot.api.oauth.Oauth`): Object that manages the oauth processes.
            chats(:class:`Fibot.chats.Chats`): Chat records of users.
            delay(:obj:`int`): Amount of seconds between scans.
            queue(:obj:`list`): Lists of chat_id's of the people with tokens to be refreshed.
            thread(:class:`threading.Timer`): Thread that does the scanning.
            polling(:obj:`bool`): Object that indicates if polling has to be done.
    """
    def __init__(self, delay, thread_logging = True):
        self.oauth = Oauth()
        self.chats = Chats()
        self.delay = delay
        self.thread_logging = thread_logging
        self.queue = []
        self.polling = True
        self.thread = None

    """
        Updates the internal representation of the chats with the last dumped values.
    """
    def update_chats(self):
        self.chats.load()
        self.queue = self.chats.get_expired_chats()

    """
        This function defines the new timer and starts it (effectively allows the scanning)
    """
    def run(self, initial_offset = 0):
        if self.polling:
            self.thread = Timer(self.delay - initial_offset, self.poll)
            self.thread.start()

    """
        Does a scan over all users with expired tokens, and then returns to the activation function
    """
    def poll(self):
        if self.thread_logging: print("\n")
        if self.thread_logging: log("R_Thread: Refrescando tokens\n")
        self.update_chats()
        for chat in self.queue:
            if self.thread_logging: log("R_Thread: Refrescando token de {}\n".format(self.chats.get_chat(chat)['name']))
            refresh_token = self.chats.get_chat(chat)['refresh_token']
            callback = self.oauth.refresh_token(refresh_token)
            if callback: self.chats.update_chat(chat, data = callback, full_data = False)
            if callback and self.thread_logging: log("R_Thread: Token refrescado correctamente!\n")
        self.queue = []
        self.run()

    """
        Allows polling
    """
    def stop_polling(self):
        self.polling = False

    """
        Forbids polling
    """
    def start_polling(self):
        self.polling = True
        self.run()