def copy_collection(self, message): '''Creating a copy of a user collection. Parameters ---------- message : Message User message. ''' # Getting a copy of the name and number of cards in the collection. fetch = db.Fetch(message.chat.id, 'collections', 'collection') name = fetch.general_collection(message.text, 'name') cards = fetch.general_collection(message.text, 'cards') karma = fetch.general_collection(message.text, 'user_id') # Checking for a duplicate collection in the database. fetch = db.Fetch(message.chat.id, 'collections', 'collection') result = fetch.copy_check('name', f'{name} (Копия)') if result: self.bot.send_message(message.chat.id, messages.ERRORS[9]) self.bot.register_next_step_handler(message, self.copy_collection) return # Getting a unique collection key from the database. fetch = db.Fetch(message.chat.id) key = fetch.user_attribute('session') # Making copies of cards from the original collection. date = datetime.datetime.now() insert = db.Insert(message.chat.id, 'collections', 'card') insert.copy_collection(message.text, key, date) # Inserting the name of the collection # and the number of cards in the database. update = db.Update(message.chat.id, 'collections', 'collection') update.collection_attribute(key, 'name', f'{name} (Копия)') update.collection_attribute(key, 'cards', cards) # User status update. update = db.Update(message.chat.id) update.user_attribute('action', 0) update.user_attribute('session', None) update.change_user_attribute('collections', 1) update.change_user_attribute('cards', cards) # Adding karma to the user whose collection was copied. if karma != message.chat.id: update = db.Update(karma) update.change_user_attribute('karma', 1) text = messages.COLLECTIONS['COLLECTION_COPIED'] self.bot.send_message(message.chat.id, text.format(name)) self.send_menu(message)
def cancel(message): '''Canceling the current operation. Parameters ---------- message : Message User message. ''' # Getting information about user status from the database. fetch = db.Fetch(message.chat.id) action = fetch.user_attribute('action') session = fetch.user_attribute('session') if action == 1: # Removing a collection-reserved space from the database. delete = db.Delete(message.chat.id, 'collections', 'collection') delete.delete_collection(session) elif action == 3: # Removing a card-reserved space from the database. delete = db.Delete(message.chat.id, 'collections', 'card') delete.delete_card(session) # User status update. update = db.Update(message.chat.id) update.user_attribute('action', 0) update.user_attribute('session', None) bot.send_message(message.chat.id, messages.ASSISTANCE['CANCEL']) private_office(message)
def _save_new_description(self, message): '''Getting a new card description. Parameters ---------- message : Message User message. ''' handler = tools.Handler(self.bot) if handler.cancel(message): return # Getting a unique card key from the database. fetch = db.Fetch(message.chat.id) card_key = fetch.user_attribute('session') # Card description update. update = db.Update(message.chat.id, 'collections', 'card') update.card_attribute(card_key, 'description', message.text) # User status update. update = db.Update(message.chat.id) update.user_attribute('action', 0) update.user_attribute('session', None) self.bot.send_message(message.chat.id, messages.CARDS['CARD_EDITED']) self.send_menu(message, card_key)
def info(self, call): '''Additional information about the card. Parameters ---------- call : CallbackQuery Response to button press. ''' card_key = re.findall(r'\w-\d+-\d+-\w+', call.data)[0] # Getting card information from the database. fetch = db.Fetch(call.message.chat.id, 'collections', 'card') key = fetch.card_attribute(card_key, 'key') name = fetch.card_attribute(card_key, 'name') description = fetch.card_attribute(card_key, 'description') date = tools.Format.date(fetch.card_attribute(card_key, 'date')) status = tools.Format.date(fetch.card_attribute(card_key, 'status')) # Creating a card menu. buttons = messages.CARD['INFO_BUTTONS'] keyboard = tools.Format.keyboard(buttons=buttons, card=card_key, collection=key) menu = tools.Maker.keyboard(2, **keyboard) text = messages.CARD['INFO'].format(name, description, date, status) self.bot.answer_callback_query(call.id) self.bot.edit_message_text(text=text, chat_id=call.message.chat.id, message_id=call.message.message_id, reply_markup=menu, parse_mode='Markdown')
def _create_menu(self, message, card_key): '''Creating the main card menu. Parameters ---------- message : Message User message. card_key : str Unique card key. Returns ------- menu : InlineKeyboardMarkup Card menu. text : str Card interface text. ''' # Getting card information from the database. fetch = db.Fetch(message.chat.id, 'collections', 'card') key = fetch.card_attribute(card_key, 'key') name = fetch.card_attribute(card_key, 'name') description = fetch.card_attribute(card_key, 'description') # Creating a card menu. buttons = messages.CARD['BUTTONS'] keyboard = tools.Format.keyboard(buttons=buttons, card=card_key, collection=key) menu = tools.Maker.keyboard(2, **keyboard) text = messages.CARD['INTERFACE'].format(name, description) return menu, text
def start_learning(self, call): '''Start learning the card. Parameters ---------- call : CallbackQuery Response to button press. ''' card_key = re.findall(r'\w-\d+-\d+-\w', call.data)[0] # Getting card information from the database. fetch = db.Fetch(call.message.chat.id, 'collections', 'card') description = fetch.card_attribute(card_key, 'description') key = fetch.card_attribute(card_key, 'key') # Creating a card result menu. buttons = messages.CARD['RESULT_BUTTONS'] keyboard = tools.Format.keyboard(buttons=buttons, card=card_key, collection=key) menu = tools.Maker.keyboard(1, **keyboard) self.bot.answer_callback_query(call.id) self.bot.edit_message_text(text=description, chat_id=call.message.chat.id, message_id=call.message.message_id, parse_mode='Markdown', reply_markup=menu)
def delete_yes(self, call): '''Consent to remove the card. Parameters ---------- call : CallbackQuery Response to button press. ''' card_key = re.findall(r'\w-\d+-\d+-\w+', call.data)[0] # Getting card information from the database. fetch = db.Fetch(call.message.chat.id, 'collections', 'card') name = fetch.card_attribute(card_key, 'name') key = fetch.card_attribute(card_key, 'key') # Updating the number of user cards. update = db.Update(call.message.chat.id) update.change_user_attribute('cards', -1) # Updating the number of cards in the user's collection. update = db.Update(call.message.chat.id, 'collections', 'collection') update.change_collection_attribute(key, 'cards', -1) # Removing a card from the database. delete = db.Delete(call.message.chat.id, 'collections', 'card') delete.delete_card(card_key) text = messages.CARD['DELETE']['SUCCESSFUL'].format(name) self.bot.answer_callback_query(call.id, text, True) cards = Cards(self.bot) cards.call_menu(call, key, 0)
def _create_menu(self, message, key): '''Creating the main menu and collection text. Parameters ---------- message : Message User message. key : str Unique collection key. Returns ------- menu : InlineKeyboardMarkup Collection menu. text : str Collection interface text. ''' # Getting information about a collection from a database. fetch = db.Fetch(message.chat.id, 'collections', 'collection') name = fetch.collection_attribute(key, 'name') cards = fetch.collection_attribute(key, 'cards') date = tools.Format.date(fetch.collection_attribute(key, 'date')) # Creating a collection menu. buttons = messages.COLLECTION['BUTTONS'] keyboard = tools.Format.keyboard(buttons=buttons, collection=key) menu = tools.Maker.keyboard(2, **keyboard) text = messages.COLLECTION['INTERFACE'].format(name, key, cards, date) return menu, text
def delete_yes(self, call): '''Consent to delete collection. Parameters ---------- call : CallbackQuery Response to button press. ''' key = re.findall(r'\w-\d+-\d+-\w+', call.data)[0] # Getting collection name from database. fetch = db.Fetch(call.message.chat.id, 'collections', 'collection') name = fetch.collection_attribute(key, 'name') cards = fetch.collection_attribute(key, 'cards') # Change the number of collections and cards in the user profile. update_user_status = db.Update(call.message.chat.id) update_user_status.change_user_attribute('collections', -1) update_user_status.change_user_attribute('cards', -int(cards)) # Removing a collection from a database. delete = db.Delete(call.message.chat.id, 'collections', 'collection') delete.delete_collection(key) # Removing all cards in a collection from the database. delete = db.Delete(call.message.chat.id, 'collections', 'card') delete.delete_collection_cards(key) text = messages.COLLECTION['DELETE']['SUCCESSFUL'].format(name) self.bot.answer_callback_query(call.id, text, True) collections = Collections(self.bot) collections.call_menu(call)
def profile_menu(call): '''User profile. Parameters ---------- call : CallbackQuery Response to button press. ''' # Getting information about a user. fetch = db.Fetch(call.message.chat.id) karma = fetch.user_attribute('karma') cards = fetch.user_attribute('cards') username = fetch.user_attribute('username') collections = fetch.user_attribute('collections') # Creating a user profile menu. menu = tools.Maker.keyboard(1, **messages.PROFILE['BUTTONS']) text = messages.PROFILE['INTERFACE'].format(username, karma, collections, cards) bot.answer_callback_query(call.id) bot.edit_message_text(text=text, chat_id=call.message.chat.id, message_id=call.message.message_id, parse_mode='Markdown', reply_markup=menu)
def _create_menu(self, message): '''Create user collections menu. Parameters ---------- message : Message User message. Returns ------- menu : InlineKeyboardMarkup Collections menu. ''' # Getting information about collections from the database. fetch = db.Fetch(message.chat.id, 'collections', 'collection') info = fetch.user_collections() # Create a menu from all user collections. if info: buttons = tools.Format.buttons('collection_show_{}', info, 3, 1) keyboard = tools.Maker.keyboard(2, **buttons) else: keyboard = None # Create menu. menu_buttons = messages.COLLECTIONS['BUTTONS'] menu = tools.Maker.keyboard(2, keyboard, **menu_buttons) return menu
def _save_collection(self, message): '''Get the name of the collection and save it to the database. Parameters ---------- message : Message User message. ''' handler = tools.Handler(self.bot) if handler.cancel(message): return # Checking for the existence of a collection with a similar key. fetch = db.Fetch(message.chat.id, 'collections', 'collection') copy_key = fetch.general_collection(message.text, 'key') if copy_key: self.copy_collection(message) return # Checking for a duplicate collection in the database. fetch = db.Fetch(message.chat.id, 'collections', 'collection') result = fetch.copy_check('name', message.text) if result: self.bot.send_message(message.chat.id, messages.ERRORS[3]) self.bot.register_next_step_handler(message, self._save_collection) return # Getting a unique collection key from the database. fetch = db.Fetch(message.chat.id) key = fetch.user_attribute('session') # Inserting the collection name to the database. update = db.Update(message.chat.id, 'collections', 'collection') update.collection_attribute(key, 'name', message.text) # User status update. update = db.Update(message.chat.id) update.user_attribute('action', 0) update.user_attribute('session', None) update.change_user_attribute('collections', 1) text = messages.COLLECTIONS['COLLECTION_CREATED'] self.bot.send_message(message.chat.id, text.format(message.text)) self.send_menu(message)
def _create_menu(self, message, key, level=0): '''User collection cards. Parameters ---------- call : CallbackQuery Response to button press. key : str Unique collection key. level : int Menu page (default is 0). Returns ------- menu : InlineKeyboardMarkup Collection menu. text : str Collection interface text. ''' # Getting the name of a collection from the database. fetch = db.Fetch(message.chat.id, 'collections', 'collection') collection_name = fetch.collection_attribute(key, 'name') # Getting card information from the database. fetch = db.Fetch(message.chat.id, 'collections', 'card') cards_info = fetch.user_cards(key) if cards_info: # Adding navigation buttons to menu. nav_obj = cards_info[8*level : 8*(level + 1)] navigation = tools.Maker.navigation(key, len(cards_info), level) # Creating a menu from all cards in a user collection. cards = tools.Format.buttons('card_show_{}', nav_obj, 4, 2) cards_menu = tools.Maker.keyboard(2, navigation, **cards) else: cards_menu = None # Adding exit buttons to menu. buttons = messages.CARDS['BUTTONS'] keyboard = tools.Format.keyboard(buttons=buttons, collection=key) menu = tools.Maker.keyboard(2, cards_menu, **keyboard) text = messages.CARDS['INTERFACE'].format(collection_name) return menu, text
def _save_new_name(self, message): '''Getting a new card name. Parameters ---------- message : Message User message. ''' handler = tools.Handler(self.bot) if handler.cancel(message): return # Getting a unique card key. fetch = db.Fetch(message.chat.id) card_key = fetch.user_attribute('session') # Getting the unique key of the collection that the card belongs to. fetch = db.Fetch(message.chat.id, 'collections', 'card') key = fetch.card_attribute(card_key, 'key') # Getting the old card name and # checking for a duplicate card in the database. fetch = db.Fetch(message.chat.id, 'collections', 'card') old_name = fetch.card_attribute(card_key, 'name') result = fetch.card_copy_check(key, 'name', message.text) if result: self.bot.send_message(message.chat.id, messages.ERRORS[6]) self.bot.register_next_step_handler(message, self._save_new_name) return # Updating the card name in the database. update = db.Update(message.chat.id, 'collections', 'card') update.card_attribute(card_key, 'name', message.text) # User status update. update = db.Update(message.chat.id) update.user_attribute('action', 0) update.user_attribute('session', None) text = messages.CARDS['CARD_RENAMED'].format(old_name, message.text) self.bot.send_message(message.chat.id, text) self.send_menu(message, card_key)
def _card_description(self, message): '''Getting a card description. Parameters ---------- message : Message User message. ''' handler = tools.Handler(self.bot) if handler.cancel(message): return # Getting a unique card key. fetch = db.Fetch(message.chat.id) card_key = fetch.user_attribute('session') # Getting the unique key of the collection that the card belongs to. fetch = db.Fetch(message.chat.id, 'collections', 'card') key = fetch.card_attribute(card_key, 'key') # Getting the card name. fetch = db.Fetch(message.chat.id, 'collections', 'card') card_name = fetch.card_attribute(card_key, 'name') # Inserting a card description to the database. update = db.Update(message.chat.id, 'collections', 'card') update.card_attribute(card_key, 'description', message.text) # Updating user status and number of cards. update = db.Update(message.chat.id) update.user_attribute('action', 0) update.user_attribute('session', None) update.change_user_attribute('cards', 1) # Updating the number of cards in the user's collection. update = db.Update(message.chat.id, 'collections', 'collection') update.change_collection_attribute(key, 'cards', 1) text = messages.CARDS['CARD_CREATED'] self.bot.send_message(message.chat.id, text.format(card_name)) self.send_menu(message, key)
def _save_new_name(self, message): '''Getting a new collection name. Parameters ---------- message : Message User message. ''' handler = tools.Handler(self.bot) if handler.cancel(message): return # Getting the name of a collection to check for a duplicate # collection in the database. fetch = db.Fetch(message.chat.id, 'collections', 'collection') result = fetch.copy_check('name', message.text) if result: self.bot.send_message(message.chat.id, messages.ERRORS[3]) self.bot.register_next_step_handler(message, self._save_new_name) return # Getting a unique key and old collection name. fetch_status = db.Fetch(message.chat.id) key = fetch_status.user_attribute('session') old_name = fetch.collection_attribute(key, 'name') # Updating the collection name in the database. update = db.Update(message.chat.id, 'collections', 'collection') update.collection_attribute(key, 'name', message.text) # User status update. update = db.Update(message.chat.id) update.user_attribute('action', 0) update.user_attribute('session', None) text = messages.COLLECTIONS['COLLECTION_RENAMED'] formatted_text = text.format(old_name, message.text) self.bot.send_message(message.chat.id, formatted_text) self.send_menu(message, key)
def phrase_handler(self): '''Defines the type of user questione. Returns ------- fetch : str Returns the bot's response or message about unrecognized text. ''' actions = {} text = re.sub(r'(\,|\.|\?|\!|\:)', '', self.message.text.lower()) fetch = db.Fetch(self.message.chat.id, 'intents', 'training_phrases') intents = fetch.intents_attribute() # Finding key commands in a user's query. for intent in intents: if intent[1] in text: actions[intent[0]] = intent[1] phrases = '' fetch = db.Fetch(self.message.chat.id, 'intents', 'responses') for key in actions: var_text = random.choice(fetch.responses_attribute(key))[0] # Checking for the presence in the line of the command "find". if key == 'find': phrases += f'{var_text} '.format(self._action(actions[key])) else: phrases += f'{var_text} ' # Selecting a random answer from the bot phrases database. if phrases == '': var_text = random.choice(fetch.responses_attribute('error'))[0] phrases = var_text return phrases
def _card_name(self, message): '''Getting the name of the card. Parameters ---------- message : Message User message. ''' handler = tools.Handler(self.bot) if handler.cancel(message): return # Getting a unique card key. fetch = db.Fetch(message.chat.id) card_key = fetch.user_attribute('session') # Getting the unique key of the collection that the card belongs to. fetch = db.Fetch(message.chat.id, 'collections', 'card') key = fetch.card_attribute(card_key, 'key') # Checking for the existence of a duplicate card in the database. fetch = db.Fetch(message.chat.id, 'collections', 'card') result = fetch.card_copy_check(key, 'name', message.text) if result: self.bot.send_message(message.chat.id, messages.ERRORS[6]) self.bot.register_next_step_handler(message, self._card_name) return # Inserting the card name to the database. update = db.Update(message.chat.id, 'collections', 'card') update.card_attribute(card_key, 'name', message.text) text = messages.CARDS['CARD_DESCRIPTION'] self.bot.send_message(message.chat.id, text) self.bot.register_next_step_handler(message, self._card_description)
def error(self, message): '''Checking for errors. Parameters ---------- message : Message User message. Returns ------- bool True if error, False otherwise. ''' # Getting information about the user's actions and # the ID of his last Personal Account. fetch = db.Fetch(message.chat.id) action = fetch.user_attribute('action') menu_id = fetch.user_attribute('menu_id') if action == 1: self.bot.send_message(message.chat.id, messages.ERRORS[1]) return True elif action == 2: self.bot.send_message(message.chat.id, messages.ERRORS[2]) return True elif action == 3: self.bot.send_message(message.chat.id, messages.ERRORS[4]) return True elif action == 4: self.bot.send_message(message.chat.id, messages.ERRORS[5]) return True elif action == 5: self.bot.send_message(message.chat.id, messages.ERRORS[7]) return True elif message.message_id != menu_id and action != 1: text = messages.ERRORS[0] self.bot.edit_message_text(text, message.chat.id, message.message_id) return True return False
def continue_learning(self, call): '''Training program. Parameters ---------- call : CallbackQuery Response to button press. ''' key = re.findall(r'\w-\d+-\d+-\w', call.data)[0] # Find a card that the user has repeated fewer times. fetch = db.Fetch(call.message.chat.id, 'collections', 'card') cards = fetch.user_cards(key) if not cards: self.bot.answer_callback_query(call.id, messages.ERRORS[8], True) return # Choosing the optimal card for repetition. rare_card = sorted(cards, key=lambda card: card[6])[0] date_format = '%Y-%m-%d %H:%M:%S.%f' card_date = datetime.datetime.strptime(rare_card[6], date_format) # Card repetition cycle. if (card_date - datetime.datetime.now()).days >= 0: text_date = tools.Format.date(rare_card[6]) text = messages.CARDS['THE_END'].format(text_date) display = not ('result' in call.data) self.bot.answer_callback_query(call.id, text, display) # Create a card study menu. buttons = messages.COLLECTION['CONTINUE_BUTTONS'] keyboard = tools.Format.keyboard(buttons=buttons, card=rare_card[2], collection=rare_card[1]) menu = tools.Maker.keyboard(1, **keyboard) self.bot.answer_callback_query(call.id) self.bot.edit_message_text(text=rare_card[4], chat_id=call.message.chat.id, message_id=call.message.message_id, reply_markup=menu)
def dialog(message): '''Answers the user to a question. Parameters ---------- message : Message User message. ''' conv = conversation.Intents(message) phrase = conv.phrase_handler() bot.send_message(message.chat.id, phrase, parse_mode='Markdown') fetch = db.Fetch(message.chat.id) voice = fetch.user_attribute('voice') engine = pyttsx3.init() if voice == 3: engine.setProperty('rate', 118) engine.setProperty('voice', engine.getProperty('voices')[voice].id) engine.save_to_file(phrase, f'dboqp_bot_{message.chat.id}.mp3') engine.runAndWait() bot.send_voice(message.chat.id, open(f'dboqp_bot_{message.chat.id}.mp3', 'rb'))
def _action(self, ans): '''Performs the action requested by the user. Returns ------- fetch : str Returns the bot's response or message about unrecognized text. ''' # Finding key phrases in a query with a colon. if re.findall(':', self.message.text): try: response = re.findall(r'\: (.*)[\,\.\?\!]', self.message.text)[0] except: try: response = re.findall(r'\: (.*)\b', self.message.text)[0] except: response = 'error' # Finding similarities between user cards and query. try: fetch = db.Fetch(self.message.chat.id, 'collections', 'card') all_cards = [i[4] for i in fetch.all_user_cards()] card = difflib.get_close_matches(response, all_cards) except: return messages.ERRORS[10] if card: fetch = db.Fetch(self.message.chat.id, 'collections', 'card') card = fetch.general_card(card[0]) return card[5] # Finding key phrases in a query without a colon. elif ans in self.message.text.lower(): try: try: fr_text = fr'{ans} (.*)[\,\.\?\!]' response = re.findall(fr_text, self.message.text)[0] except: fr_text = fr'{ans.capitalize()} (.*)[\,\.\?\!]' response = re.findall(fr_text, self.message.text)[0] except: try: try: fr_text = fr'{ans} (.*)\b' response = re.findall(fr_text, self.message.text)[0] except: fr_text = fr'{ans.capitalize()} (.*)\b' response = re.findall(fr_text, self.message.text)[0] except: response = 'error' # Finding similarities between user cards and query. try: fetch = db.Fetch(self.message.chat.id, 'collections', 'card') all_cards = [i[4] for i in fetch.all_user_cards()] card = difflib.get_close_matches(response, all_cards) except: return messages.ERRORS[10] if card: fetch = db.Fetch(self.message.chat.id, 'collections', 'card') card = fetch.general_card(card[0]) return card[5] return messages.ERRORS[10]