def subscription(bot, update): """Sends text detailing the subscription model""" chat_id = update.message.chat_id bot.sendMessage(chat_id=chat_id, text=SUBSCRIPTION_MSG, parse_mode='markdown', disable_web_page_preview=True) mp.track(get_user_info(chat_id)['PID'], 'Checked Subscription')
def delete(bot, update): """Delete a user's credentials if they wish to stop using the bot or update them.""" chatID = update.message.chat_id username = get_user_info(chatID)['PID'] logger.info("Deleting user credentials for {}!".format(username)) Chat.query.filter(Chat.chatID == chatID).delete( ) # Delete the user's record referenced by their ChatID Misc.query.filter(Misc.chatID == chatID).delete() db_session.commit() messageContent = "Your credentials have been deleted, {}\nHope to see you back soon!".format( username[3:-4].title()) bot.sendMessage(chat_id=update.message.chat_id, text=messageContent) mp.track(username, 'User Left') mp.people_set(username, {'active': False})
def update_target(bot, update): """Takes the sent figure and sets it as new attendance target. :param bot: Telegram Bot object :type bot: telegram.bot.Bot :param update: Telegram Update object :type update: telegram.update.Update :return: ConversationHandler.END :rtype: int """ user_reply = update.message.text if user_reply == '/cancel': bot.sendMessage(chat_id=update.message.chat_id, text="As you wish! The operation is cancelled!") return ConversationHandler.END try: new_target = int(user_reply) except ValueError: bot.sendMessage(chat_id=update.message.chat_id, text="You must send a number between 1-99.") return if not 1 <= new_target <= 99: bot.sendMessage(chat_id=update.message.chat_id, text="You must send a number between 1-99.") return old_target = get_misc_record(update.message.chat_id).attendance_target db_session.query(Misc).filter( Misc.chatID == update.message.chat_id).update( {'attendance_target': new_target}) db_session.commit() username = get_user_info(update.message.chat_id)['PID'] logger.info("Modified attendance target for {} to {}%".format( username, new_target)) new_target_message = "Your attendance target has been updated to {}%!".format( new_target) bot.sendMessage(chat_id=update.message.chat_id, text=new_target_message) mp.track(username, 'Edit Attendance Target', { 'new_target': new_target, 'old_target': old_target }) return ConversationHandler.END
def attendance_target(bot, update): """Like :func:`until_eighty`, but with user specified target attendance percentage which is stored in the ``Misc`` table. If target isn't set, asks users whether they'd like to and passes control to :py:func:`select_yn` :param bot: Telegram Bot object :type bot: telegram.bot.Bot :param update: Telegram Update object :type update: telegram.update.Update :return: SELECT_YN :rtype: int """ bot.send_chat_action(chat_id=update.message.chat_id, action='typing') student_misc = get_misc_record(update.message.chat_id) target = student_misc.attendance_target if target is None: messageContent = textwrap.dedent(""" You have not set a target yet. Would you like to set it now? You can change it anytime using /edit_target """) keyboard = [['Yes'], ['No']] reply_markup = ReplyKeyboardMarkup(keyboard) bot.sendMessage(chat_id=update.message.chat_id, text=messageContent, reply_markup=reply_markup) return SELECT_YN no_of_lectures = int(until_x(update.message.chat_id, target)) if no_of_lectures < 0: messageContent = "Your attendance is already over {}%. Maybe set it higher? Use /edit_target to change it.".format( target) bot.sendMessage(chat_id=update.message.chat_id, text=messageContent) return ConversationHandler.END messageContent = "You need to attend {} lectures to meet your target of {}%".format( no_of_lectures, target) bot.sendMessage(chat_id=update.message.chat_id, text=messageContent) username = get_user_info(update.message.chat_id)['PID'] mp.track(username, 'Check Attendance Target') return ConversationHandler.END
def parent_login(bot, update, user_data): """ user_data dict contains ``Student_ID`` key from :py:func:`credentials`. Extracts DOB from ``update.message.text`` and checks validity using :py:func:`misbot.mis_utils.check_parent_login` before adding it to database. Finally, sends a message to the user requesting them to start using ``/attendance`` or ``/itinerary`` commands. """ DOB = update.message.text Student_ID = user_data['Student_ID'] chatID = update.message.chat_id if not check_parent_login(Student_ID, DOB): messageContent = textwrap.dedent(""" Looks like your Date of Birth details are incorrect! Give it one more shot. Send DOB in the below format: `DD/MM/YYYY` """) bot.sendMessage(chat_id=update.message.chat_id, text=messageContent, parse_mode='markdown') return new_user = Student_ID[3:-4].title() db_session.query(Chat).filter(Chat.chatID == chatID).update({'DOB': DOB}) db_session.commit() logger.info("New Registration! Username: {}".format((Student_ID))) messageContent = "Welcome {}!\nStart by checking your /attendance or /itinerary".format( new_user) bot.sendMessage(chat_id=update.message.chat_id, text=messageContent, parse_mode='markdown') mp.track(Student_ID, 'New User') mp.people_set( Student_ID, { 'pid': Student_ID, 'first_name': update.message.from_user.first_name, 'last_name': update.message.from_user.last_name, 'username': update.message.from_user.username, 'link': update.message.from_user.link, 'active': True, }) return ConversationHandler.END
def close_spider(self, spider): student_misc = Misc.query.filter(Misc.chatID == spider.chatID).first() try: bot.send_photo( chat_id=spider.chatID, photo=open("files/{}_attendance.png".format(spider.username), 'rb'), caption='Attendance Report for {}'.format(spider.username)) if student_misc is not None and student_misc.attendance_target is not None: target = student_misc.attendance_target no_of_lectures = int(until_x(spider.chatID, target)) if no_of_lectures > 0: messageContent = "You need to attend {} lectures to meet your target of {}%".format( no_of_lectures, target) bot.sendMessage(chat_id=spider.chatID, text=messageContent) remove('files/{}_attendance.png'.format( spider.username)) #Delete saved image mp.track(spider.username, 'Attendance') except IOError: bot.sendMessage( chat_id=spider.chatID, text= 'The bot is experiencing some issues. Please try again later.') logger.warning( "Attendance screenshot failed! Check if site is blocking us or if Splash is up." ) mp.track(spider.username, 'Error', {'type': 'Site down?'}) except TelegramError as te: logger.warning("TelegramError: {}".format(str(te))) mp.track(spider.username, 'Error', { 'type': 'TelegramError', 'error': str(te) })
def close_spider(self, spider): try: bot.send_document( chat_id=spider.chatID, document=open("files/{}_profile.png".format(spider.username), 'rb'), caption='Student profile for {}'.format(spider.username)) remove('files/{}_profile.png'.format( spider.username)) #Delete saved image mp.track(spider.username, 'Profile') except IOError: bot.sendMessage( chat_id=spider.chatID, text= 'The bot is experiencing some issues. Please try again later.') logger.warning( "Profile screenshot failed! Check if site is blocking us or if Splash is up." ) mp.track(spider.username, 'Error', {'type': 'Site down?'}) except TelegramError as te: logger.warning("TelegramError: {}".format(str(te))) mp.track(spider.username, 'Error', { 'type': 'TelegramError', 'error': str(te) })
def wrapped(bot, update, *args, **kwargs): chatID = update.message.chat_id if not str(chatID) == os.environ['ADMIN_CHAT_ID']: messageContent = "You are not authorized to use this command. This incident has been reported." bot.sendMessage(chat_id=chatID, text=messageContent) user = get_user_info(chatID) if user: mp.track(user['PID'], 'Admin Function Access Attempt', { 'pid': user['PID'], 'link': update.message.from_user.link, }) logger.warning("Unauthorized Access attempt by {}".format( user['PID'])) else: mp.track(user['PID'], 'Admin Function Access Attempt', { 'chat_id': chatID, 'link': update.message.from_user.link, }) logger.warning( "Unauthorized Access attempt by {}".format(chatID)) return return func(bot, update, *args, **kwargs)
def input_target(bot, update): """If the user reply is a int/float and between 1-99, stores the figure as the new attendance target. :param bot: Telegram Bot object :type bot: telegram.bot.Bot :param update: Telegram Update object :type update: telegram.update.Update :return: ConversationHandler.END :rtype: int """ try: target_figure = float(update.message.text) except ValueError: bot.sendMessage(chat_id=update.message.chat_id, text="You must send a number between 1-99.") return if not 1 <= target_figure <= 99: bot.sendMessage(chat_id=update.message.chat_id, text="You must send a number between 1-99.") return db_session.query(Misc).filter( Misc.chatID == update.message.chat_id).update( {'attendance_target': target_figure}) db_session.commit() messageContent = "Your attendance target has been set to {}%.".format( target_figure) username = get_user_info(update.message.chat_id)['PID'] logger.info("Set attendance target for {} to {}%".format( username, target_figure)) bot.sendMessage(chat_id=update.message.chat_id, text=messageContent) mp.track(username, 'Set Attendance Target', {'target': target_figure}) return ConversationHandler.END
def error_callback(bot, update, error): """Simple error handling function. Handles PTB lib errors""" user = get_user_info(update.message.chat_id) username = update.message.chat_id if user is None else user['PID'] try: raise error except Unauthorized: # remove update.message.chat_id from conversation list mp.track(username, 'Error', {'type': 'Unauthorized'}) logger.warning( "TelegramError: Unauthorized user. User probably blocked the bot.") except BadRequest as br: # handle malformed requests mp.track(username, 'Error', { 'type': 'BadRequest', 'text': update.message.text, 'error': str(br) }) logger.warning("TelegramError: {} | Text: {} | From: {}".format( str(br), update.message.text, update.message.from_user)) except TimedOut as time_out: # handle slow connection problems mp.track( username, 'Error', { 'type': 'TimedOut', 'text': update.message.text, 'error': str(time_out) }) logger.warning("TelegramError: {} | Text: {} | From: {}".format( str(time_out), update.message.text, update.message.from_user)) except NetworkError as ne: # handle other connection problems mp.track(username, 'Error', { 'type': 'NetworkError', 'text': update.message.text, 'error': str(ne) }) logger.warning("TelegramError: {} | Text: {} | From: {}".format( str(ne), update.message.text, update.message.from_user)) except ChatMigrated as cm: # the chat_id of a group has changed, use e.new_chat_id instead mp.track(username, 'Error', {'type': 'ChatMigrated'}) logger.warning("TelegramError: {} | Text: {} | From: {}".format( str(cm), update.message.text, update.message.from_user)) except TelegramError as e: # handle all other telegram related errors mp.track(username, 'Error', { 'type': 'TelegramError', 'text': update.message.text, 'error': str(e) }) logger.warning("TelegramError: {} | Text: {} | From: {}".format( str(e), update.message.text, update.message.from_user))
def close_spider(self, spider): try: with open("files/{}_itinerary.png".format(spider.username), "rb") as f: pass except IOError: bot.sendMessage( chat_id=spider.chatID, text= 'The bot is experiencing some issues. Please try again later.') logger.warning( "Itinerary screenshot failed! Check if site is blocking us or if Splash is up." ) mp.track(spider.username, 'Error', {'type': 'Site down?'}) return except TelegramError as te: logger.warning("TelegramError: {}".format(str(te))) mp.track(spider.username, 'Error', { 'type': 'TelegramError', 'error': str(te) }) return if spider.uncropped: try: # arguments supplied, sending full screenshot bot.send_document( chat_id=spider.chatID, document=open( "files/{}_itinerary.png".format(spider.username), 'rb'), caption='Full Itinerary Report for {}'.format( spider.username)) remove('files/{}_itinerary.png'.format( spider.username)) #Delete original downloaded image mp.track(spider.username, 'Itinerary', {'cropped': False}) return except TelegramError as te: logger.warning("TelegramError: {}".format(str(te))) mp.track(spider.username, 'Error', { 'type': 'TelegramError', 'error': str(te) }) return try: if crop_image("files/{}_itinerary.png".format(spider.username)): # greater than 800px. cropping and sending.. bot.send_photo(chat_id=spider.chatID, photo=open( "files/{}_itinerary_cropped.png".format( spider.username), 'rb'), caption='Itinerary Report for {}'.format( spider.username)) remove('files/{}_itinerary_cropped.png'.format( spider.username)) #Delete cropped image remove('files/{}_itinerary.png'.format( spider.username)) #Delete original downloaded image else: # less than 800px, sending as it is.. bot.send_photo( chat_id=spider.chatID, photo=open( "files/{}_itinerary.png".format(spider.username), 'rb'), caption='Itinerary Report for {}'.format(spider.username)) remove('files/{}_itinerary.png'.format( spider.username)) #Delete original downloaded image mp.track(spider.username, 'Itinerary', {'cropped': True}) except TelegramError as te: logger.warning("TelegramError: {}".format(str(te))) mp.track(spider.username, 'Error', { 'type': 'TelegramError', 'error': str(te) })