def _infofile_thread(self, bot, dbx, chat_id, folder_name, username, comment, user_language, recreate): lS = LanguageSupport(user_language).languageSupport try: dbx.files_delete("/" + folder_name + "/" + INFO_FILE_FILENAME) if recreate: # TODO: this is bodging. Find a way to allow more symbols! #allow only alphanumeric allowed_symbols = ascii_letters + punctuation + digits + " " username = "".join(i if i in allowed_symbols else "_" for i in username) comment = "".join(i if i in allowed_symbols else "_" for i in comment) dbx.files_upload("Photos by " + username + "\n\n" + comment, "/" + folder_name + "/" + INFO_FILE_FILENAME) bot.sendMessage(chat_id=chat_id, message=lS(INFO_FILE_UPDATED_MESSAGE), key_markup="SAME") else: bot.sendMessage(chat_id=chat_id, message=lS(INFO_FILE_DELETED_MESSAGE), key_markup="SAME") except dropbox.exceptions.ApiError as e: if "not_found" in str(e): if not recreate: dbx.files_upload( "Photos by " + username + "\n\n" + comment, "/" + folder_name + "/" + INFO_FILE_FILENAME) bot.sendMessage(chat_id=chat_id, message=lS(INFO_FILE_CREATED_MESSAGE), key_markup="SAME")
def processUpdate(self, u): def sendParamsToThread(**kwargs): # process photo thread_params = dict(bot=bot, update=u, chat_id=chat_id, message_id=message_id) # save params to file self.queue_saver.append_to_list(thread_params, save=True) # send params to Queue for thread to process self.uploader_queue.put(thread_params) bot = self.bot Message = u.message message = Message.text message_id = Message.message_id chat_id = Message.chat_id subs = self.h_subscribers # try initializing user. If it exists, ignore (no forcing). user_folder_token = hex(getrandbits(128))[2:] while user_folder_token in [ subs.subscribers[chatid]['folder_token'] for chatid in subs.subscribers.keys() ]: # it is highly improbable, but if suddenly the folder token is generated - try again! user_folder_token = hex(getrandbits(128))[2:] subs.init_user(chat_id, params={"folder_token": user_folder_token}) # language support class for convenience LS = LanguageSupport(subs.get_param(chat_id=chat_id, param="lang")) lS = LS.languageSupport MMKM = lS(MAIN_MENU_KEY_MARKUP) 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).format( lS(DB_STORAGE_LINK_BUTTON), lS(FREE_DB_SPACE_BUTTON)), key_markup=MMKM, markdown=True) elif message == "/about" or message == lS(ABOUT_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(ABOUT_MESSAGE), 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) elif message == "/dblink" or message == lS(DB_STORAGE_LINK_BUTTON): bot.sendMessage( chat_id=chat_id, message=lS(DB_STORAGE_LINK_MESSAGE) % (DB_STORAGE_PUBLIC_LINK, subs.get_param(chat_id=chat_id, param="folder_token")), key_markup=MMKM, preview=False) elif message == "/free" or message == lS(FREE_DB_SPACE_BUTTON): bot.sendMessage(chat_id=chat_id, message=lS(FREE_DB_SPACE_MESSAGE) % self.get_free_dbx_space(), key_markup=MMKM) elif message == "/set_name" or message == lS(SET_USERNAME_BUTTON): subs.set_param(chat_id=chat_id, param="input_mode", value=1) bot.sendMessage(chat_id=chat_id, message=lS(SET_USERNAME_MESSAGE), key_markup=MMKM) elif message == "/set_comment" or message == lS(SET_COMMENT_BUTTON): subs.set_param(chat_id=chat_id, param="input_mode", value=2) bot.sendMessage(chat_id=chat_id, message=lS(SET_COMMENT_MESSAGE), key_markup=MMKM) elif message == "/toggle_infofile" or message == lS( TOGGLE_INFOFILE_BUTTON): InfofileThread(bot, self.dbx, chat_id, subs.get_param(chat_id, "folder_token"), subs.get_param(chat_id, "username"), subs.get_param(chat_id, "comment"), subs.get_param(chat_id, "lang")) elif message == RU_LANG_BUTTON: self.assignBotLanguage(chat_id, 'RU') LS = LanguageSupport(subs.get_param(chat_id=chat_id, param="lang")) key_markup = LS.languageSupport(message=MAIN_MENU_KEY_MARKUP) bot.sendMessage( chat_id=chat_id, message="Сообщения бота будут отображаться на русском языке.", key_markup=key_markup) elif message == EN_LANG_BUTTON: self.assignBotLanguage(chat_id, 'EN') LS = LanguageSupport(subs.get_param(chat_id=chat_id, param="lang")) key_markup = LS.languageSupport(message=MAIN_MENU_KEY_MARKUP) bot.sendMessage(chat_id=chat_id, message="Bot messages will be shown in English.", key_markup=key_markup) elif bot.isPhoto(u): print("Sending params to thread on message. photo") # debug sendParamsToThread(bot=bot, update=u, chat_id=chat_id, message_id=message_id) elif bot.isDocument(u): if ALLOW_FILES: try: # check supported file formats if not (bot.getFileExt(u, no_dot=True).lower() in SUPPORTED_FILE_FORMATS): bot.sendMessage( chat_id=chat_id, message=lS(WRONG_FILE_FORMAT_MESSAGE).format( ", ".join(SUPPORTED_FILE_FORMATS)), reply_to=message_id) # limit filesize elif bot.getFileSize(u) > MAX_FILE_SIZE: bot.sendMessage( chat_id=chat_id, message=lS(FILE_TOO_BIG_MESSAGE).format( MAX_FILE_SIZE / 1024**2), reply_to=message_id) else: print("Sending params to thread on message. Document" ) # debug sendParamsToThread(bot=bot, update=u, chat_id=chat_id, message_id=message_id) except TelegramError: logging.error("Could not process file.\n" + full_traceback()) bot.sendMessage(chat_id=chat_id, message="Failed to process file", reply_to=message_id) else: bot.sendMessage(chat_id=chat_id, message=lS(FILES_NOT_ALLOWED_MESSAGE), reply_to=message_id) else: if subs.get_param(chat_id, "input_mode") == 1: # Username input mode subs.set_param(chat_id, param="username", value=message) subs.set_param(chat_id, param="input_mode", value=0) bot.sendMessage(chat_id=chat_id, message="Username set!", key_markup=MMKM) InfofileThread(bot, self.dbx, chat_id, subs.get_param(chat_id, "folder_token"), subs.get_param(chat_id, "username"), subs.get_param(chat_id, "comment"), subs.get_param(chat_id, "lang"), recreate=True) elif subs.get_param(chat_id, "input_mode") == 2: # Comment input mode subs.set_param(chat_id, param="comment", value=message) subs.set_param(chat_id, param="input_mode", value=0) bot.sendMessage(chat_id=chat_id, message="Comment set!", key_markup=MMKM) InfofileThread(bot, self.dbx, chat_id, subs.get_param(chat_id, "folder_token"), subs.get_param(chat_id, "username"), subs.get_param(chat_id, "comment"), subs.get_param(chat_id, "lang"), recreate=True) else: bot.sendMessage(chat_id=chat_id, message="Unknown command!", key_markup=MMKM)
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.user_params subs.initializeUser(chat_id=chat_id, data=INITIAL_SUBSCRIBER_PARAMS) # language support class for convenience LS = LanguageSupport(subs.getEntry(chat_id=chat_id, param="lang")) lS = LS.languageSupport allv = LS.allVariants MMKM = lS(MAIN_MENU_KEY_MARKUP) if message == "/start": bot.sendMessage(chat_id=chat_id , message=lS(START_MESSAGE) , key_markup=MMKM ) elif message == "/help" or message in allv(HELP_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(HELP_MESSAGE).format(lS(GET_TIMETABLE_BUTTON), lS(ALL_DAYS_BUTTON), lS(MY_EVENTS_BUTTON), lS(SUBSCRIBE_BUTTON)) , key_markup=MMKM , markdown=True ) elif message == "/about" or message in allv(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 in allv(OTHER_BOTS_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(OTHER_BOTS_MESSAGE) , key_markup=MMKM ) elif message == "/map" or message in allv(MAP_BUTTON): map_filepath = path.join(SCRIPT_FOLDER, RESOURCES_FOLDER_NAME, MAP_FILENAME) if path.isfile(map_filepath): bot.sendPic(chat_id=chat_id , pic=open(map_filepath, "rb") , caption=MAP_MESSAGE ) else: # There is no map file, notify user bot.sendMessage(chat_id=chat_id , message=lS(NO_MAP_FILE_MESSAGE) , key_markup=MMKM ) elif message == "/timetable" or message in allv(GET_TIMETABLE_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(GET_TIMETABLE_MESSAGE) , key_markup=self.timetable_db.getTimetableMarkup() ) elif TimetableDatabase.isDate(message): # it is a date, show day timetable print('message', message) response = lS(CURRENT_TIME_MESSAGE).format(self.timetable_db.getOffsetTime().strftime("%H:%M")) \ + "\n\n" \ + self.timetable_db.getDayTimetable(message) bot.sendMessage(chat_id=chat_id , message=response , key_markup=MMKM ) #If a graphical file in format YYYY-MM-DD.png exists, send it as well try: filepath = path.join(SCRIPT_FOLDER, RESOURCES_FOLDER_NAME, message) + ".png" with open(filepath, "rb") as pic: bot.sendPic(chat_id=chat_id , pic=pic , caption=message ) except FileNotFoundError as e: print("Graph file not found") print(full_traceback()) elif message == '/all' or message in allv(ALL_DAYS_BUTTON): # it is a date, show day timetable response = lS(CURRENT_TIME_MESSAGE).format(self.timetable_db.getOffsetTime().strftime("%H:%M")) \ + "\n\n" \ + self.timetable_db.getAllDaysTimetable() bot.sendMessage(chat_id=chat_id , message=response , key_markup=MMKM ) elif re.match("^/event[0-9]+$", message): # Event link is pressed event_info = self.timetable_db.getEventInfo(message[6:]) response = lS(CURRENT_TIME_MESSAGE).format(self.timetable_db.getOffsetTime().strftime("%H:%M")) \ + "\n\n" \ + lS(event_info) bot.sendMessage(chat_id=chat_id , message=response , key_markup=MMKM , markdown="html" ) elif message == "/subscribe" or message in allv(SUBSCRIBE_BUTTON): if self.user_params.getEntry(chat_id, "subscribed") == 0: self.user_params.setEntry(chat_id, "subscribed", 1) bot.sendMessage(chat_id=chat_id , message=lS(SUBSCRIBED_MESSAGE) , key_markup=MMKM ) else: bot.sendMessage(chat_id=chat_id , message=lS(ALREADY_SUBSCRIBED_MESSAGE) , key_markup=MMKM ) elif message == "/unsubscribe" or message in allv(UNSUBSCRIBE_BUTTON): if self.user_params.getEntry(chat_id, "subscribed") == 1: self.user_params.setEntry(chat_id, "subscribed", 0) bot.sendMessage(chat_id=chat_id , message=lS(UNSUBSCRIBED_MESSAGE) , key_markup=MMKM ) else: bot.sendMessage(chat_id=chat_id , message=lS(ALREADY_UNSUBSCRIBED_MESSAGE) , key_markup=MMKM ) elif message == "/myevents" or message in allv(MY_EVENTS_BUTTON): # show a table of events to which a user is subscribed user_timetable = self.timetable_db.getUserTimetable(chat_id=chat_id) if user_timetable: response = lS(CURRENT_TIME_MESSAGE).format(self.timetable_db.getOffsetTime().strftime("%H:%M")) \ + "\n\n" \ + self.timetable_db.getUserTimetable(chat_id=chat_id) else: response = "Your personal timetable is empty!" bot.sendMessage(chat_id=chat_id , message=response , key_markup=MMKM ) elif re.match("^/sub[0-9]+$",message): event_index = message[4:] if self.timetable_db.eventIndexExists(event_index): # Event exists event_name = self.timetable_db.getEventData(event_index)['name'] if not self.timetable_db.subscriptionExists(chat_id, event_index): self.timetable_db.addSubscription(chat_id, event_index) bot.sendMessage(chat_id=chat_id , message="You have subscribed to the event: {0}".format(event_name, event_index) , key_markup=MMKM ) else: self.timetable_db.deleteSubscription(chat_id,event_index) bot.sendMessage(chat_id=chat_id , message="Subscription deleted: {0}".format(event_name, event_index) , key_markup=MMKM ) else: # such event doesn't exist bot.sendMessage(chat_id=chat_id , message="Event with index {0} doesn't exist!".format(event_index) , key_markup=MMKM , reply_to=message_id ) elif re.match("^[0-9]+$",message): remind_period = int(message) if remind_period < 1: self.user_params.setEntry(chat_id, 'remind_period', 1) bot.sendMessage(chat_id=chat_id , message="The minimum remind period possible is 1 minute. Setting to 1 minute." , key_markup=MMKM ) elif remind_period > 1439: self.user_params.setEntry(chat_id, 'remind_period', 1439) bot.sendMessage(chat_id=chat_id , message="The minimum remind period possible is 1439 minutes. Setting to 1439 minutes." , key_markup=MMKM ) else: self.user_params.setEntry(chat_id, 'remind_period', remind_period) bot.sendMessage(chat_id=chat_id , message="Preliminary reminder period has been set to {0}".format(message) , key_markup=MMKM ) elif message == RU_LANG_BUTTON: self.assignBotLanguage(chat_id, 'RU') LS = LanguageSupport(subs.getEntry(chat_id=chat_id, param="lang")) key_markup = LS.languageSupport(message=MAIN_MENU_KEY_MARKUP) bot.sendMessage(chat_id=chat_id , message="Сообщения бота будут отображаться на русском языке." , key_markup=key_markup ) elif message == EN_LANG_BUTTON: self.assignBotLanguage(chat_id, 'EN') LS = LanguageSupport(subs.getEntry(chat_id=chat_id, param="lang")) key_markup = LS.languageSupport(message=MAIN_MENU_KEY_MARKUP) bot.sendMessage(chat_id=chat_id , message="Bot messages will be shown in English." , key_markup=key_markup ) # admin tools elif bot.isDocument(u) and self.user_params.getEntry(chat_id, 'admin') == 1: # check if it is a timetable if re.search("^.*{0}$".format(EVENT_TIMETABLE_FILENAME), bot.getDocumentFileName(u)): # It's a text file with timetable full_path = path.join(TEMP_FOLDER, EVENT_TIMETABLE_FILENAME) bot.downloadFile(bot.getFileID(u), full_path) try: with open(full_path, "r") as f: data = f.read() print(data) self.timetable_db.parseTimetable(data) os.remove(full_path) bot.sendMessage(chat_id=chat_id , message="Events added!" , key_markup=MMKM ) except IndexError: bot.sendMessage(chat_id=chat_id , message="Parsing failed! Are all fields present in the file?" , key_markup=MMKM ) if re.search("^.*{0}$".format(EVENT_TIMETABLE_XLS_FILENAME), bot.getDocumentFileName(u)): # It's a XLS sheet with a timetable full_path = path.join(TEMP_FOLDER, EVENT_TIMETABLE_XLS_FILENAME) bot.downloadFile(bot.getFileID(u), full_path) self.timetable_db.parseTimetableXLS(full_path) os.remove(full_path) bot.sendMessage(chat_id=chat_id , message="Events added!" , key_markup=MMKM ) elif re.match("^TZ(\+|-)([0-9]|[0-1][0-9]|2[0-3])$", message) and self.user_params.getEntry(chat_id, 'admin') == 1: # Setting the timezone parameter timezone = int(message[2:]) self.server_params.setParam('timezone', timezone) bot.sendMessage(chat_id=chat_id , message="Timezone set to UTC{0}{1}".format("+" if timezone >= 0 else "", timezone) , key_markup=MMKM ) elif message == "/revoke" and self.user_params.getEntry(chat_id, 'admin') == 1: # revoke admin rights self.user_params.setEntry(chat_id, 'admin', 0) bot.sendMessage(chat_id=chat_id , message="Admin rights revoked" , key_markup=MMKM ) else: bot.sendMessage(chat_id=chat_id , message="Unknown command!" , key_markup=MMKM )
def processUpdate(self, u): def sendParamsToThread(**kwargs): # process photo thread_params = dict(bot=bot, update=u, chat_id=chat_id, message_id=message_id) # save params to file self.queue_saver.append_to_list(thread_params, save=True) # send params to Queue for thread to process self.uploader_queue.put(thread_params) bot = self.bot Message = u.message message = Message.text message_id = Message.message_id chat_id = Message.chat_id subs = self.h_subscribers # try initializing user. If it exists, ignore (no forcing). user_folder_token = hex(getrandbits(128))[2:] while user_folder_token in [subs.subscribers[chatid]['folder_token'] for chatid in subs.subscribers.keys()]: # it is highly improbable, but if suddenly the folder token is generated - try again! user_folder_token = hex(getrandbits(128))[2:] subs.init_user(chat_id, params={"folder_token": user_folder_token}) # language support class for convenience LS = LanguageSupport(subs.get_param(chat_id=chat_id, param="lang")) lS = LS.languageSupport MMKM = lS(MAIN_MENU_KEY_MARKUP) 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).format(MAX_FILE_SIZE/1024**2, ", ".join(SUPPORTED_FILE_FORMATS), lS(DB_STORAGE_LINK_BUTTON), lS(FREE_DB_SPACE_BUTTON)) , key_markup=MMKM , markdown=True ) elif message == "/about" or message == lS(ABOUT_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(ABOUT_MESSAGE) , 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 ) elif message == "/dblink" or message == lS(DB_STORAGE_LINK_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(DB_STORAGE_LINK_MESSAGE) % (DB_STORAGE_PUBLIC_LINK, subs.get_param(chat_id=chat_id, param="folder_token")) , key_markup=MMKM , preview=False ) elif message == "/free" or message == lS(FREE_DB_SPACE_BUTTON): bot.sendMessage(chat_id=chat_id , message=lS(FREE_DB_SPACE_MESSAGE) % self.get_free_dbx_space() , key_markup=MMKM ) elif message == "/set_name" or message == lS(SET_USERNAME_BUTTON): subs.set_param(chat_id=chat_id,param="input_mode", value=1) bot.sendMessage(chat_id=chat_id , message=lS(SET_USERNAME_MESSAGE) , key_markup=MMKM ) elif message == "/set_comment" or message == lS(SET_COMMENT_BUTTON): subs.set_param(chat_id=chat_id,param="input_mode", value=2) bot.sendMessage(chat_id=chat_id , message=lS(SET_COMMENT_MESSAGE) , key_markup=MMKM ) elif message == "/toggle_infofile" or message == lS(TOGGLE_INFOFILE_BUTTON): InfofileThread(bot, self.dbx, chat_id, subs.get_param(chat_id, "folder_token"), subs.get_param(chat_id, "username"), subs.get_param(chat_id, "comment"), subs.get_param(chat_id, "lang")) elif message == RU_LANG_BUTTON: self.assignBotLanguage(chat_id, 'RU') LS = LanguageSupport(subs.get_param(chat_id=chat_id, param="lang")) key_markup = LS.languageSupport(message=MAIN_MENU_KEY_MARKUP) bot.sendMessage(chat_id=chat_id , message="Сообщения бота будут отображаться на русском языке." , key_markup=key_markup ) elif message == EN_LANG_BUTTON: self.assignBotLanguage(chat_id, 'EN') LS = LanguageSupport(subs.get_param(chat_id=chat_id, param="lang")) key_markup = LS.languageSupport(message=MAIN_MENU_KEY_MARKUP) bot.sendMessage(chat_id=chat_id , message="Bot messages will be shown in English." , key_markup=key_markup ) elif bot.isPhoto(u): print("Sending params to thread on message. photo") # debug sendParamsToThread(bot=bot, update=u, chat_id=chat_id, message_id=message_id) elif bot.isDocument(u): try: # check supported file formats if not (bot.getFileExt(u, no_dot=True).lower() in SUPPORTED_FILE_FORMATS): bot.sendMessage(chat_id=chat_id , message=lS(WRONG_FILE_FORMAT_MESSAGE).format(", ".join( SUPPORTED_FILE_FORMATS)) , reply_to=message_id ) # limit filesize elif bot.getFileSize(u) > MAX_FILE_SIZE: bot.sendMessage(chat_id=chat_id , message=lS(FILE_TOO_BIG_MESSAGE).format(MAX_FILE_SIZE / 1024 ** 2) , reply_to=message_id ) else: print("Sending params to thread on message. Document") # debug sendParamsToThread(bot=bot, update=u, chat_id=chat_id, message_id=message_id) except TelegramError: logging.error("Could not process file.\n" + full_traceback()) bot.sendMessage(chat_id=chat_id , message="Failed to process file" , reply_to=message_id ) else: if subs.get_param(chat_id,"input_mode") == 1: # Username input mode subs.set_param(chat_id, param="username", value=message) subs.set_param(chat_id, param="input_mode", value=0) bot.sendMessage(chat_id=chat_id , message="Username set to " + message , key_markup=MMKM ) InfofileThread(bot, self.dbx, chat_id, subs.get_param(chat_id, "folder_token"), subs.get_param(chat_id, "username"), subs.get_param(chat_id, "comment"), subs.get_param(chat_id, "lang"), recreate=True) elif subs.get_param(chat_id,"input_mode") == 2: # Comment input mode subs.set_param(chat_id, param="comment", value=message) subs.set_param(chat_id, param="input_mode", value=0) bot.sendMessage(chat_id=chat_id , message="Comment set!" , key_markup=MMKM ) InfofileThread(bot, self.dbx, chat_id, subs.get_param(chat_id, "folder_token"), subs.get_param(chat_id, "username"), subs.get_param(chat_id, "comment"), subs.get_param(chat_id, "lang"), recreate=True) else: bot.sendMessage(chat_id=chat_id , message="Unknown command!" , key_markup=MMKM )