class MainBot: """The main bot class""" def __init__(self, token): super(MainBot, self).__init__() self.bot = TelegramHigh(token) # the last time when the data was grabbed from server self.last_update_time = 1 # the raw data about train delays self.data = None # handler of user data self.userparams = SubscribersHandler( savefile_path=SUBSCRIBERS_DATABASE_PATH, initial_params=INITIAL_SUBSCRIBER_PARAMS) self.bot.start(processingFunction=self.processUpdate, periodicFunction=self.periodicRoutine) def periodicRoutine(self): if time() - self.last_update_time > FILE_UPDATE_PERIOD: lh.warning("Updating the trains data!") data = delays_scraper.get_data() if data: self.data = data self.last_update_time = time() def processUpdate(self, u): bot = self.bot Message = u.message message = Message.text message_id = Message.message_id chat_id = Message.chat_id subs = self.userparams # # initialize the user's params if they are not present yet subs.initializeUser(chat_id=chat_id) # language support class for convenience LS = LanguageSupport(subs.getEntry(chat_id=chat_id, param="lang")) lS = LS.languageSupport allv = LS.allVariants MM = getMainMenu(subs.getEntry(chat_id=chat_id, param="subscribed")) MMKM = lS(MM) def getDelaysTable(user=None, formatted=False): """ Returns a text representation of delays table :param user: a chat_id to read train numbers from. If None, returns the whole current table. :return: string table """ data = self.data train_data = data["trains"] #Inits result, user_trains = "", [] if user: user_trains = self.userparams.getEntry(user, "trains") for train in train_data: # check data for each train if not user or (user and train["number"] in user_trains): if not formatted: result = result + "\t".join([ i for i in train.values() if isinstance(i, str) ]) + "\n" else: result = result + lS(TABLE_ENTRY_BEGINNING_MESSAGE).format(train["number"])\ + (lS(DEPARTED_FROM_APPENDIX).format(train["station"]) if train["departed"] else lS(ARRIVED_AT_APPENDIX).format(train["station"]))\ + (lS(COMES_ONTIME_APPENDIX) if train["delay"][1:] == "0" else lS(TABLE_ENTRY_ONOFFTIME_APPENDIX).format( train["delay"].replace("-","").replace("+",""), lS(COMES_EARLY_APPENDIX) if train["delay"][0] == "-" else lS(COMES_LATE_APPENDIX) ) )\ + (lS(RED_LIGHT_APPENDIX) if train["red_light"] else "")\ + "\n" return result def sendTable(user=None): """ Sends a table of delays :param user: a chat_id to read train numbers from. If None, returns the whole current table. """ table = getDelaysTable(user, formatted=True) cur_time = self.data["time"] if table: since_last_update = time() - self.last_update_time msg = (lS(PERSONAL_TABLE_HEADER) if user else lS(FULL_TABLE_HEADER) ) + "\n" \ + lS("Current time: ") + cur_time + "\n\n" \ + table \ + "\n" + lS(SECONDS_SINCE_LAST_UPDATE_MESSAGE).format(int(since_last_update)) else: msg = lS(USER_TRAINS_NOT_FOUND_MESSAGE) bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM, markdown=True) if message == "/start": bot.sendMessage(chat_id=chat_id, message=lS(START_MESSAGE), key_markup=MMKM) elif message == "/help" or message == lS(HELP_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(HELP_MESSAGE), key_markup=MMKM, markdown=True) elif message == "/about" or message == lS(ABOUT_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(ABOUT_MESSAGE).format(".".join( [str(i) for i in VERSION_NUMBER])), key_markup=MMKM, markdown=True) elif message == "/otherbots" or message == lS(OTHER_BOTS_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(OTHER_BOTS_MESSAGE), key_markup=MMKM, markdown=True) elif message == "/get" or message == lS(GET_FULL_TABLE_BUTTON): sendTable(user=None) elif message == "/getmy" or message == lS( GET_USER_TRAINS_DELAYS_BUTTON): sendTable(user=chat_id) elif message == "/mylist" or message == lS( GET_USER_TRAINS_LIST_BUTTON): trains = subs.getEntry(chat_id, "trains") if trains: msg = lS(PERSONAL_LIST_MESSAGE) + "\n" + "\n".join([i + "\t /del" + i for i in trains])\ + "\n" + lS(TO_DELETE_INFO_MESSAGE) else: msg = lS(PERSONAL_LIST_IS_EMPTY_MESSAGE) bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM # ,markdown=True ) elif re.fullmatch(r"^/del[0-9]+[A-Za-z]?$", message): train = message[4:] trains = subs.getEntry(chat_id, "trains") if train in trains: subs.setEntry(chat_id, "trains", list(filter(train.__ne__, trains))) msg = lS(TRAIN_DELETED_MESSAGE).format(train) else: msg = lS(TRAIN_NOT_ON_LIST_MESSAGE).format(train) bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM # ,markdown=True ) elif re.fullmatch(r"^[0-9]+[A-Za-z]?$", message): train = message.upper() subs.setEntry(chat_id, "trains", train, append=True) bot.sendMessage(chat_id=chat_id, message=lS(TRAIN_ADDED_MESSAGE).format(train), key_markup=MMKM # ,markdown=True ) elif message == RU_LANG_BUTTON: subs.setEntry(chat_id, "lang", 'RU') LS = LanguageSupport("RU") bot.sendMessage( chat_id=chat_id, message="Сообщения бота будут отображаться на русском языке.", key_markup=LS.languageSupport(MM)) elif message == EN_LANG_BUTTON: subs.setEntry(chat_id, "lang", 'EN') LS = LanguageSupport("EN") bot.sendMessage(chat_id=chat_id, message="Bot messages will be shown in English.", key_markup=LS.languageSupport(MM)) else: bot.sendMessage(chat_id=chat_id, message=lS(UNKNOWN_COMMAND_MESSAGE), key_markup=MMKM)
class MainBot: """The main bot class""" def __init__(self, token): super(MainBot, self).__init__() self.bot = TelegramHigh(token) # the last time when the data was grabbed from server self.last_update_time = 1 # the raw data about train delays self.data = None # handler of user data self.userparams = SubscribersHandler(savefile_path=SUBSCRIBERS_DATABASE_PATH, initial_params=INITIAL_SUBSCRIBER_PARAMS) self.bot.start(processingFunction=self.processUpdate, periodicFunction=self.periodicRoutine) def periodicRoutine(self): if time() - self.last_update_time > FILE_UPDATE_PERIOD: lh.warning("Updating the trains data!") data = delays_scraper.get_data() if data: self.data = data self.last_update_time = time() def processUpdate(self, u): bot = self.bot Message = u.message message = Message.text message_id = Message.message_id chat_id = Message.chat_id subs = self.userparams # # initialize the user's params if they are not present yet subs.initializeUser(chat_id=chat_id) # language support class for convenience LS = LanguageSupport(subs.getEntry(chat_id=chat_id, param="lang")) lS = LS.languageSupport allv = LS.allVariants MM = getMainMenu(subs.getEntry(chat_id=chat_id, param="subscribed")) MMKM = lS(MM) def getDelaysTable(user=None, formatted=False): """ Returns a text representation of delays table :param user: a chat_id to read train numbers from. If None, returns the whole current table. :return: string table """ data = self.data train_data = data["trains"] #Inits result, user_trains = "", [] if user: user_trains = self.userparams.getEntry(user,"trains") for train in train_data: # check data for each train if not user or (user and train["number"] in user_trains): if not formatted: result = result + "\t".join([i for i in train.values() if isinstance(i, str)]) + "\n" else: result = result + lS(TABLE_ENTRY_BEGINNING_MESSAGE).format(train["number"])\ + (lS(DEPARTED_FROM_APPENDIX).format(train["station"]) if train["departed"] else lS(ARRIVED_AT_APPENDIX).format(train["station"]))\ + (lS(COMES_ONTIME_APPENDIX) if train["delay"][1:] == "0" else lS(TABLE_ENTRY_ONOFFTIME_APPENDIX).format( train["delay"].replace("-","").replace("+",""), lS(COMES_EARLY_APPENDIX) if train["delay"][0] == "-" else lS(COMES_LATE_APPENDIX) ) )\ + (lS(RED_LIGHT_APPENDIX) if train["red_light"] else "")\ + "\n" return result def sendTable(user=None): """ Sends a table of delays :param user: a chat_id to read train numbers from. If None, returns the whole current table. """ table = getDelaysTable(user, formatted=True) cur_time = self.data["time"] if table: since_last_update = time()-self.last_update_time msg = (lS(PERSONAL_TABLE_HEADER) if user else lS(FULL_TABLE_HEADER) ) + "\n" \ + lS("Current time: ") + cur_time + "\n\n" \ + table \ + "\n" + lS(SECONDS_SINCE_LAST_UPDATE_MESSAGE).format(int(since_last_update)) else: msg = lS(USER_TRAINS_NOT_FOUND_MESSAGE) bot.sendMessage(chat_id=chat_id ,message=msg ,key_markup=MMKM ,markdown=True ) if message == "/start": bot.sendMessage(chat_id=chat_id ,message=lS(START_MESSAGE) ,key_markup=MMKM ) elif message == "/help" or message == lS(HELP_BUTTON): bot.sendMessage(chat_id=chat_id ,message=lS(HELP_MESSAGE) ,key_markup=MMKM ,markdown=True ) elif message == "/about" or message == lS(ABOUT_BUTTON): bot.sendMessage(chat_id=chat_id ,message=lS(ABOUT_MESSAGE).format(".".join([str(i) for i in VERSION_NUMBER])) ,key_markup=MMKM ,markdown=True ) elif message == "/otherbots" or message == lS(OTHER_BOTS_BUTTON): bot.sendMessage(chat_id=chat_id ,message=lS(OTHER_BOTS_MESSAGE) ,key_markup=MMKM ,markdown=True ) elif message == "/get" or message == lS(GET_FULL_TABLE_BUTTON): sendTable(user=None) elif message == "/getmy" or message == lS(GET_USER_TRAINS_DELAYS_BUTTON): sendTable(user=chat_id) elif message == "/mylist" or message == lS(GET_USER_TRAINS_LIST_BUTTON): trains = subs.getEntry(chat_id,"trains") if trains: msg = lS(PERSONAL_LIST_MESSAGE) + "\n" + "\n".join([i + "\t /del" + i for i in trains])\ + "\n" + lS(TO_DELETE_INFO_MESSAGE) else: msg = lS(PERSONAL_LIST_IS_EMPTY_MESSAGE) bot.sendMessage(chat_id=chat_id ,message=msg ,key_markup=MMKM # ,markdown=True ) elif re.fullmatch(r"^/del[0-9]+[A-Za-z]?$", message): train = message[4:] trains = subs.getEntry(chat_id,"trains") if train in trains: subs.setEntry(chat_id,"trains",list(filter(train.__ne__,trains))) msg = lS(TRAIN_DELETED_MESSAGE).format(train) else: msg = lS(TRAIN_NOT_ON_LIST_MESSAGE).format(train) bot.sendMessage(chat_id=chat_id ,message=msg ,key_markup=MMKM # ,markdown=True ) elif re.fullmatch(r"^[0-9]+[A-Za-z]?$", message): train = message.upper() subs.setEntry(chat_id,"trains",train,append=True) bot.sendMessage(chat_id=chat_id ,message=lS(TRAIN_ADDED_MESSAGE).format(train) ,key_markup=MMKM # ,markdown=True ) elif message == RU_LANG_BUTTON: subs.setEntry(chat_id, "lang", 'RU') LS = LanguageSupport("RU") bot.sendMessage(chat_id=chat_id , message="Сообщения бота будут отображаться на русском языке." , key_markup=LS.languageSupport(MM) ) elif message == EN_LANG_BUTTON: subs.setEntry(chat_id, "lang", 'EN') LS = LanguageSupport("EN") bot.sendMessage(chat_id=chat_id , message="Bot messages will be shown in English." , key_markup=LS.languageSupport(MM) ) else: bot.sendMessage(chat_id=chat_id, message=lS(UNKNOWN_COMMAND_MESSAGE) ,key_markup=MMKM )
class LanguageLearner(object): """docstring for LanguageLearner""" def __init__(self, token): super(LanguageLearner, self).__init__() self.bot = TelegramHigh(token) self.databases = DB_Manager() def run(self): self.bot.start(processingFunction=self.processingRoutine) def processingRoutine(self, u): bot = self.bot Message = u.message message = Message.text message_id = Message.message_id chat_id = Message.chat_id databases = self.databases # # initialize the user's params if they are not present yet databases.initializeUser(chat_id=chat_id) # language support class for convenience LS = LanguageSupport(databases.getLanguage(chat_id=chat_id)) lS = LS.languageSupport allv = LS.allVariants MM = getMainMenu() MMKM = lS(MM) user_answer_state = databases.getUserAnswerState(chat_id) if user_answer_state: # the user is challenged with a word the_word = databases.getWordData(ID=user_answer_state)["word"] if message == "/refresh" or message == lS(REFRESH_BUTTON): msg = "You are already guessing!" bot.sendMessage(chat_id=chat_id , message=msg , key_markup=None ) else: if message.lower() == the_word.lower(): databases.incrementWordLevel(ID=user_answer_state) msg = "Correct!" else: databases.resetWordLevel(ID=user_answer_state) msg = "Wrong! The correct answer is {0}".format(the_word) databases.updateWordRefreshTime(ID=user_answer_state) databases.nullifyUserAnswerState(chat_id) bot.sendMessage(chat_id=chat_id ,message=msg ,key_markup=MMKM ) else: # all other commands if message == "/start": bot.sendMessage(chat_id=chat_id ,message=lS(START_MESSAGE) ,key_markup=MMKM ) elif message == "/help" or message == lS(HELP_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(HELP_MESSAGE) , key_markup=MMKM , markdown=True ) elif message == "/about" or message == lS(ABOUT_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(ABOUT_MESSAGE).format(".".join([str(i) for i in VERSION_NUMBER])) , key_markup=MMKM , markdown=True ) elif message == "/otherbots" or message == lS(OTHER_BOTS_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(OTHER_BOTS_MESSAGE) , key_markup=MMKM , markdown=True ) elif message == "/refresh" or message == lS(REFRESH_BUTTON): kbd_markup = MMKM course = databases.getUserCourse(chat_id) if course == None: msg = "No course is set!" else: result, number_of_refreshable_words = databases.askRefreshWord(chat_id, course) if isinstance(result, str): msg = "Words left to refresh: {}\n\n".format(number_of_refreshable_words) msg += result kbd_markup=None # hide custom keyboard when refreshing a word elif isinstance(result, int): msg = "Everything is fresh in this course!\n"\ + "Till next refresh: {}".format(utils.secondsToText(result)) else: msg = "Unknown error!" bot.sendMessage(chat_id=chat_id , message=msg , key_markup=kbd_markup ) elif message == "/words" or message == lS(WORD_LIST_BUTTON): def formatWordData(word_list): result = "" for word in word_list: result += "№{0} {1}; {2}\n".format(word["ID"],word["word"],word["translation"]) return result course = databases.getUserCourse(chat_id=chat_id) if course == None: msg = "You haven't selected a course yet!" else: word_list = databases.getCourseWordList(course=course) if not word_list: msg = "No words in this course yet" else: msg = formatWordData(word_list) bot.sendMessage(chat_id=chat_id ,message=msg ,key_markup=MMKM ) elif message == "/courses" or message == lS(COURSES_LIST_BUTTON): courses_list = databases.getUserCoursesList(chat_id) selected_course = databases.getUserCourse(chat_id) if courses_list: formatted_list = [( ("(*)" if selected_course == i["ID"] else "/setcourse" + str(i["ID"])) + " " # + "/courseinfo" + str(i["ID"]) + " " + i["name"]) for i in courses_list] msg = "\n".join(formatted_list) else: msg = "You have no courses yet!" bot.sendMessage(chat_id=chat_id , message=msg , key_markup=MMKM ) elif re.match("^addcourse ", message, re.IGNORECASE): databases.addCourse(chat_id=chat_id, course=message[10:]) bot.sendMessage(chat_id=chat_id , message=lS(COURSE_ADDED_MESSAGE) , key_markup=MMKM ) elif re.fullmatch("^/setcourse[0-9]*$", message): course_data = databases.getCourseData(course=message[len("/setcourse"):]) if not course_data: msg = "Course doesn't exist!" else: course_name = course_data["name"] databases.setUserCourse(chat_id,course=message[len('/setcourse'):]) msg = lS(COURSE_SET_MESSAGE).format(course_name) bot.sendMessage(chat_id=chat_id , message=msg , key_markup=MMKM ) elif re.match("^add ", message, re.IGNORECASE): course = databases.getUserCourse(chat_id=chat_id) if course == None: msg = "You haven't selected the course yet!" else: status = databases.addWordEntry(data=message[4:], course=course) if status: msg = lS(WORD_ADDED_MESSAGE) else: msg = lS(INCORRECT_FORMAT_MESSAGE) bot.sendMessage(chat_id=chat_id ,message=msg ,key_markup=MMKM ) elif re.fullmatch("^/del[0-9]*", message): databases.deleteWord(chat_id=chat_id, index=message[4:]) msg = "Word deleted!" bot.sendMessage(chat_id=chat_id ,message=msg ,key_markup=MMKM ) elif message == RU_LANG_BUTTON: databases.setLanguage(chat_id, 'RU') LS = LanguageSupport("RU") bot.sendMessage(chat_id=chat_id , message="Сообщения бота будут отображаться на русском языке." , key_markup=LS.languageSupport(MM) ) elif message == EN_LANG_BUTTON: databases.setLanguage(chat_id, 'EN') LS = LanguageSupport("EN") bot.sendMessage(chat_id=chat_id , message="Bot messages will be shown in English." , key_markup=LS.languageSupport(MM) ) else: bot.sendMessage(chat_id=chat_id, message=lS(UNKNOWN_COMMAND_MESSAGE) ,key_markup=MMKM )
class LanguageLearner(object): """docstring for LanguageLearner""" def __init__(self, token): super(LanguageLearner, self).__init__() self.bot = TelegramHigh(token) self.databases = DB_Manager() def run(self): self.bot.start(processingFunction=self.processingRoutine) def processingRoutine(self, u): bot = self.bot Message = u.message message = Message.text message_id = Message.message_id chat_id = Message.chat_id databases = self.databases # # initialize the user's params if they are not present yet databases.initializeUser(chat_id=chat_id) # language support class for convenience LS = LanguageSupport(databases.getLanguage(chat_id=chat_id)) lS = LS.languageSupport allv = LS.allVariants MM = getMainMenu() MMKM = lS(MM) user_answer_state = databases.getUserAnswerState(chat_id) if user_answer_state: # the user is challenged with a word the_word = databases.getWordData(ID=user_answer_state)["word"] if message == "/refresh" or message == lS(REFRESH_BUTTON): msg = "You are already guessing!" bot.sendMessage(chat_id=chat_id, message=msg, key_markup=None) else: if message.lower() == the_word.lower(): databases.incrementWordLevel(ID=user_answer_state) msg = "Correct!" else: databases.resetWordLevel(ID=user_answer_state) msg = "Wrong! The correct answer is {0}".format(the_word) databases.updateWordRefreshTime(ID=user_answer_state) databases.nullifyUserAnswerState(chat_id) bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM) else: # all other commands if message == "/start": bot.sendMessage(chat_id=chat_id, message=lS(START_MESSAGE), key_markup=MMKM) elif message == "/help" or message == lS(HELP_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(HELP_MESSAGE), key_markup=MMKM, markdown=True) elif message == "/about" or message == lS(ABOUT_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(ABOUT_MESSAGE).format(".".join( [str(i) for i in VERSION_NUMBER])), key_markup=MMKM, markdown=True) elif message == "/otherbots" or message == lS(OTHER_BOTS_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(OTHER_BOTS_MESSAGE), key_markup=MMKM, markdown=True) elif message == "/refresh" or message == lS(REFRESH_BUTTON): kbd_markup = MMKM course = databases.getUserCourse(chat_id) if course == None: msg = "No course is set!" else: result, number_of_refreshable_words = databases.askRefreshWord( chat_id, course) if isinstance(result, str): msg = "Words left to refresh: {}\n\n".format( number_of_refreshable_words) msg += result kbd_markup = None # hide custom keyboard when refreshing a word elif isinstance(result, int): msg = "Everything is fresh in this course!\n"\ + "Till next refresh: {}".format(utils.secondsToText(result)) else: msg = "Unknown error!" bot.sendMessage(chat_id=chat_id, message=msg, key_markup=kbd_markup) elif message == "/words" or message == lS(WORD_LIST_BUTTON): def formatWordData(word_list): result = "" for word in word_list: result += "№{0} {1}; {2}\n".format( word["ID"], word["word"], word["translation"]) return result course = databases.getUserCourse(chat_id=chat_id) if course == None: msg = "You haven't selected a course yet!" else: word_list = databases.getCourseWordList(course=course) if not word_list: msg = "No words in this course yet" else: msg = formatWordData(word_list) bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM) elif message == "/courses" or message == lS(COURSES_LIST_BUTTON): courses_list = databases.getUserCoursesList(chat_id) selected_course = databases.getUserCourse(chat_id) if courses_list: formatted_list = [ (("(*)" if selected_course == i["ID"] else "/setcourse" + str(i["ID"])) + " " # + "/courseinfo" + str(i["ID"]) + " " + i["name"]) for i in courses_list ] msg = "\n".join(formatted_list) else: msg = "You have no courses yet!" bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM) elif re.match("^addcourse ", message, re.IGNORECASE): databases.addCourse(chat_id=chat_id, course=message[10:]) bot.sendMessage(chat_id=chat_id, message=lS(COURSE_ADDED_MESSAGE), key_markup=MMKM) elif re.fullmatch("^/setcourse[0-9]*$", message): course_data = databases.getCourseData( course=message[len("/setcourse"):]) if not course_data: msg = "Course doesn't exist!" else: course_name = course_data["name"] databases.setUserCourse(chat_id, course=message[len('/setcourse'):]) msg = lS(COURSE_SET_MESSAGE).format(course_name) bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM) elif re.match("^add ", message, re.IGNORECASE): course = databases.getUserCourse(chat_id=chat_id) if course == None: msg = "You haven't selected the course yet!" else: status = databases.addWordEntry(data=message[4:], course=course) if status: msg = lS(WORD_ADDED_MESSAGE) else: msg = lS(INCORRECT_FORMAT_MESSAGE) bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM) elif re.fullmatch("^/del[0-9]*", message): databases.deleteWord(chat_id=chat_id, index=message[4:]) msg = "Word deleted!" bot.sendMessage(chat_id=chat_id, message=msg, key_markup=MMKM) elif message == RU_LANG_BUTTON: databases.setLanguage(chat_id, 'RU') LS = LanguageSupport("RU") bot.sendMessage( chat_id=chat_id, message= "Сообщения бота будут отображаться на русском языке.", key_markup=LS.languageSupport(MM)) elif message == EN_LANG_BUTTON: databases.setLanguage(chat_id, 'EN') LS = LanguageSupport("EN") bot.sendMessage( chat_id=chat_id, message="Bot messages will be shown in English.", key_markup=LS.languageSupport(MM)) else: bot.sendMessage(chat_id=chat_id, message=lS(UNKNOWN_COMMAND_MESSAGE), key_markup=MMKM)