예제 #1
0
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')
예제 #2
0
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})
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
    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)
            })
예제 #7
0
 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)
         })
예제 #8
0
 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)
예제 #9
0
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
예제 #10
0
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))
예제 #11
0
    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)
            })