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
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 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)]
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 []
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)]
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', }
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 []
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)]
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 []
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 []
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)]
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 []
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 []
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 []
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)
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)
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)))
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()