コード例 #1
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)
    return ConversationHandler.END
コード例 #2
0
ファイル: general.py プロジェクト: rookie2410/MIS-Bot
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')
    return ConversationHandler.END
コード例 #3
0
ファイル: admin.py プロジェクト: giftbalogun/MIS-Bot
def confirm_otp(bot, update, user_data):
    reply_markup = ReplyKeyboardRemove()
    admin_response = update.message.text
    if admin_response == "Confirm":
        pass
    elif admin_response == "Abort":
        bot.sendMessage(chat_id=update.message.chat_id,
                        text="Operation Aborted!",
                        reply_markup=reply_markup)
        return ConversationHandler.END
    else:
        bot.sendMessage(chat_id=update.message.chat_id,
                        text="Choose one of the two options.")
        return

    misc_record = get_misc_record(user_data['user_record'].chatID)
    misc_record.premium_user = True
    misc_record.premium_tier = user_data['tier']
    misc_record.premium_till = datetime.now() + timedelta(
        days=user_data['validity_days'])
    db_session.commit()

    date_beautified = misc_record.premium_till.strftime("%B %d, %Y")

    message_content = "Your premium subscription is active and valid till: {}!".format(
        date_beautified)
    bot.sendMessage(chat_id=user_data['user_record'].chatID,
                    text=message_content)

    admin_message = "{} has been elevated to premium!\n Valid till: {}".format(
        user_data['username'], date_beautified)
    bot.sendMessage(chat_id=update.message.chat_id,
                    text=admin_message,
                    reply_markup=reply_markup)
    return ConversationHandler.END
コード例 #4
0
ファイル: admin.py プロジェクト: giftbalogun/MIS-Bot
def confirm_revert(bot, update, user_data):
    """If Yes, revert the specified message for all
    users and send a summary of the operation to admin.
    
    :param bot: Telegram Bot object
    :type bot: telegram.bot.Bot
    :param update: Telegram Update object
    :type update: telegram.update.Update
    :param user_data: Conversation data
    :type user_data: dict
    """
    reply_markup = ReplyKeyboardRemove()

    if update.message.text == "Yes":
        try:
            notification_message = PushMessage.query.filter(
                PushMessage.uuid == user_data['uuid']).first().text
        except AttributeError:
            bot.sendMessage(chat_id=update.message.chat_id,
                            text="Unknown UUID. Try again.",
                            reply_markup=reply_markup)
            return ConversationHandler.END
        notifications = PushNotification.query.filter(and_(PushNotification.message_uuid == user_data['uuid'],\
                                                           PushNotification.sent == True))
        user_list = [notification.chatID for notification in notifications]
        message_ids = [
            notification.message_id for notification in notifications
        ]

        time_taken = delete_threaded(message_ids, user_list)

        notification_message_short = textwrap.shorten(notification_message,
                                                      width=20,
                                                      placeholder='...')

        stats_message = textwrap.dedent("""
        Deleted the notification:
        ```
        {}
        ```
        {} messages deleted in {:.2f}secs.
        """.format(notification_message_short, len(message_ids), time_taken))

        bot.sendMessage(chat_id=update.message.chat_id,
                        text=stats_message,
                        parse_mode='markdown',
                        reply_markup=reply_markup)

        db_session.query(PushMessage).filter(
            PushMessage.uuid == user_data['uuid']).update({'deleted': True})
        db_session.commit()
        return ConversationHandler.END
    elif update.message.text == "No" or update.message.text == "/cancel":
        bot.sendMessage(chat_id=update.message.chat_id,
                        text="Revert Aborted!",
                        reply_markup=reply_markup)
        return ConversationHandler.END
    return
コード例 #5
0
ファイル: general.py プロジェクト: rookie2410/MIS-Bot
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
    user_details = db_session.query(Chat).filter(Chat.chatID == chatID).first() #Pull user's username from the DB
    username = user_details.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
    db_session.commit() #Save changes
    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)
コード例 #6
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 = Misc.query.filter(
        Misc.chatID == update.message.chat_id).first()

    if student_misc is None:
        new_misc_record = Misc(chatID=update.message.chat_id)
        db_session.add(new_misc_record)
        db_session.commit()
        username = get_user_info(update.message.chat_id)['PID']
        logger.info("Created new Misc record for {}".format(username))
        student_misc = Misc.query.filter(
            Misc.chatID == update.message.chat_id).first()

    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)
    return ConversationHandler.END
コード例 #7
0
ファイル: mis_utils.py プロジェクト: rookie2410/MIS-Bot
def rate_limited(bot, chat_id, command):
    """Checks if user has made a request in the past 5 minutes.
    
    :param bot: Telegram Bot object
    :type bot: telegram.bot.Bot
    :param chat_id: 9-Digit unique user ID
    :type chat_id: str
    :param command: Telegram command
    :type command: str
    :return: True if user has made a request in past 5 mins, else False
    :rtype: bool
    """
    rate_limit = RateLimit.query.filter(
        and_(RateLimit.chatID == chat_id,
             RateLimit.command == command)).first()

    if rate_limit is None:
        new_rate_limit_record = RateLimit(chatID=chat_id,
                                          status='new',
                                          command=command,
                                          count=0)
        db_session.add(new_rate_limit_record)
        db_session.commit()
        rate_limit = RateLimit.query.filter(
            and_(RateLimit.chatID == chat_id,
                 RateLimit.command == command)).first()

    if abs(datetime.now() - rate_limit.requested_at) < timedelta(minutes=5):
        if rate_limit.count < 1:
            RateLimit.query.filter(and_(RateLimit.chatID == chat_id, RateLimit.command == command))\
                           .update({'count': rate_limit.count + 1})
            db_session.commit()
            return False
        elif rate_limit.count < 2:
            RateLimit.query.filter(and_(RateLimit.chatID == chat_id, RateLimit.command == command))\
                           .update({'count': rate_limit.count + 1})
            db_session.commit()
            message_content = "You've already used this command in the past 5 minutes. Please wait 5 minutes before sending another request."
            bot.send_message(chat_id=chat_id, text=message_content)
            return True

        elif rate_limit.count in range(2, 1000):
            RateLimit.query.filter(and_(RateLimit.chatID == chat_id, RateLimit.command == command))\
                           .update({'count': rate_limit.count + 1})
            db_session.commit()
            bot.send_animation(chat_id=chat_id,
                               animation=random.choice(list_of_gifs))
            return True
    else:
        RateLimit.query.filter(and_(RateLimit.chatID == chat_id, RateLimit.command == command))\
                       .update({'count': 1, 'requested_at': datetime.now()})
        db_session.commit()
        return False
コード例 #8
0
ファイル: mis_utils.py プロジェクト: rookie2410/MIS-Bot
def clean_attendance_records():
    """Delete all lectures and practical records from the DB.
    To be used at the beginning of a new semester so that ``/bunk`` command
    doesn't display lectures of previous semester(s).
    
    :return: Number of records deleted from Lecture and Practical tables.
    :rtype: tuple
    """
    lecture_records = db_session.query(Lecture).delete()
    practical_records = db_session.query(Practical).delete()
    db_session.commit()
    return lecture_records, practical_records
コード例 #9
0
def get_misc_record(chat_id):
    """Returns Misc record for a user
    
    :param chat_id: 9-Digit unique user ID
    :type chat_id: str
    """
    misc_record = Misc.query.filter(Misc.chatID == chat_id).first()
    
    if misc_record is None:
        new_misc_record = Misc(chatID=chat_id)
        db_session.add(new_misc_record)
        db_session.commit()
        misc_record = Misc.query.filter(Misc.chatID == chat_id).first()
    return misc_record
コード例 #10
0
ファイル: general.py プロジェクト: giftbalogun/MIS-Bot
def credentials(bot, update, user_data):
    """
    Store user credentials in a database.
    Takes student info (PID & password) from ``update.message.text`` and splits it into Student_ID &
    Password and checks if they are correct with :py:func:`misbot.mis_utils.check_login` and stores them in the ``Chat`` table.
    Finally, sends message asking users to enter DOB and gives control to :func:`parent_login` after
    storing ``Student_ID`` (PID) in user_data dict.
    """
    chat_id = update.message.chat_id
    # If message contains less or more than 2 arguments, send message and stop.
    try:
        Student_ID, password = update.message.text.split()
    except ValueError:
        messageContent = textwrap.dedent("""
        Oops, you made a mistake! 
        You must send the Student_ID and password in a single line, separated by a space.
        This is what valid login credentials look like:
        `123name4567 password`
        """)
        bot.send_chat_action(chat_id=chat_id, action='typing')
        bot.sendMessage(chat_id=update.message.chat_id,
                        text=messageContent,
                        parse_mode='markdown')
        return

    if not check_login(Student_ID, password):
        messageContent = textwrap.dedent("""
        Looks like your credentials are incorrect! Give it one more shot.
        This is what valid login credentials look like:
        `123name4567 password`
        """)
        bot.sendMessage(chat_id=update.message.chat_id,
                        text=messageContent,
                        parse_mode='markdown')
        return

    # Create an object of Class <Chat> and store Student_ID, password, and Telegram
    # User ID, Add it to the database, commit it to the database.

    userChat = Chat(PID=Student_ID, password=password, chatID=chat_id)
    db_session.add(userChat)
    db_session.commit()

    messageContent = textwrap.dedent("""
        Now enter your Date of Birth (DOB) in the following format:
        `DD/MM/YYYY`
        """)
    update.message.reply_text(messageContent, parse_mode='markdown')
    user_data['Student_ID'] = Student_ID
    return PARENT_LGN
コード例 #11
0
ファイル: telegram_bot.py プロジェクト: pjha1994/MIS-Bot
def credentials(bot, update):
    """Store user credentials in a database."""
    user = update.message.from_user
    chatID = update.message.chat_id
    #If message contains less or more than 2 arguments, send message and stop.
    try:
        Student_ID, passwd = update.message.text.split()
    except ValueError:
        messageContent = textwrap.dedent("""
        Oops, you made a mistake! 
        You must send the Student_ID and password in a single line, separated by a space.
        This is what valid login credentials look like:
        `123name4567 password`
        """)
        bot.send_chat_action(chat_id=update.message.chat_id, action='typing')
        bot.sendMessage(chat_id=update.message.chat_id,
                        text=messageContent,
                        parse_mode='markdown')
        return

    if Chat.query.filter(Chat.chatID == chatID).first():
        bot.sendMessage(chat_id=update.message.chat_id,
                        text="Already Registered!")
        return ConversationHandler.END

    if check_login(Student_ID, passwd) == False:
        messageContent = textwrap.dedent("""
        Looks like your credentials are incorrect! Give it one more shot.
        This is what valid login credentials look like:
        `123name4567 password`
        """)
        bot.sendMessage(chat_id=update.message.chat_id,
                        text=messageContent,
                        parse_mode='markdown')
        return

    logger.info("New Registration! Username: %s" % (Student_ID))

    # Create an object of Class <Chat> and store Student_ID, password, and Telegeram
    # User ID, Add it to the database, commit it to the database.

    userChat = Chat(PID=Student_ID, password=passwd, chatID=chatID)
    db_session.add(userChat)
    db_session.commit()

    new_user = Student_ID[3:-4].title()
    update.message.reply_text(
        "Welcome {}!\nStart by checking your /attendance".format(new_user))
    return ConversationHandler.END
コード例 #12
0
ファイル: general.py プロジェクト: giftbalogun/MIS-Bot
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})
コード例 #13
0
ファイル: telegram_bot.py プロジェクト: pjha1994/MIS-Bot
def delete(bot, update):
    """Delete a user's credentials if they wish to stop using the bot."""
    chatID = update.message.chat_id
    if not Chat.query.filter(Chat.chatID == chatID).first():
        bot.sendMessage(chat_id=update.message.chat_id, text="Unregistered!")
        return
    user_details = db_session.query(Chat).filter(
        Chat.chatID == chatID).first()  #Pull user's username from the DB
    username = user_details.PID
    logger.info("Deleting user credentials for %s!" % (username))
    Chat.query.filter(Chat.chatID == chatID).delete(
    )  #Delete the user's record referenced by their ChatID
    db_session.commit()  #Save changes
    bot.sendMessage(chat_id=update.message.chat_id, text="Your credentials have been deleted, %s\nHope to see you back soon." \
        % (username[3:-4].title()))
コード例 #14
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
コード例 #15
0
    def process_item(self, item, spider):
        #Initiate DB
        init_db()

        if not Attendance.query.filter(
                Attendance.chatID == spider.chatID).first():
            record = Attendance(
                total_lec_attended=item['total_lec_attended'],
                total_lec_conducted=item['total_lec_conducted'],
                chatID=spider.chatID)
            db_session.add(record)
            db_session.commit()
        else:
            db_session.query(Attendance).filter(Attendance.chatID == spider.chatID).\
            update({'total_lec_attended': item['total_lec_attended'],
                    'total_lec_conducted':item['total_lec_conducted']})
            db_session.commit()

        return item
コード例 #16
0
ファイル: pipelines.py プロジェクト: giftbalogun/MIS-Bot
    def process_item(self, item, spider):
        if not isinstance(item, Practicals):
            return item  #Do nothing for Lectures Items (NOT Practicals)

        if not Practical.query.filter(
                and_(Practical.chatID == spider.chatID, Practical.name
                     == item['subject'])).first():
            record = Practical(name=item['subject'],
                               chatID=spider.chatID,
                               attended=item['attended'],
                               conducted=item['conducted'])
            db_session.add(record)
            db_session.commit()

        else:
            db_session.query(Practical).filter(and_(Practical.chatID == spider.chatID, Practical.name == item['subject'])).\
            update({'attended': item['attended'],
                    'conducted':item['conducted']})
            db_session.commit()
        return item
コード例 #17
0
        def command_func(bot, update, *args, **kwargs):
            chat_id = update.message.chat_id
            misc_record = get_misc_record(chat_id)

            if misc_record.premium_user is False:
                messageContent = "You must upgrade to premium to use this feature. See /subscription"
                bot.sendMessage(chat_id=chat_id, text=messageContent)
                return

            if misc_record.premium_tier < tier:
                messageContent = "This feature is not included in your subscription plan."
                bot.sendMessage(chat_id=chat_id, text=messageContent)
                return

            if datetime.now() > misc_record.premium_till:
                misc_record.premium_user = False
                db_session.commit()
                messageContent = "Your /premium subscription has expired! Kindly renew your subscription."
                bot.sendMessage(chat_id=chat_id, text=messageContent)
                return
            return func(bot, update, *args, **kwargs)
コード例 #18
0
ファイル: admin.py プロジェクト: giftbalogun/MIS-Bot
def extend_input_days(bot, update, user_data):
    try:
        user_data['extension_period'] = int(update.message.text)
    except ValueError:
        bot.sendMessage(chat_id=update.message.chat_id,
                        text="Please send a number.")
        return
    user_record = Chat.query.filter(
        Chat.PID == user_data['username'])[user_data['index']]
    misc_record = get_misc_record(user_record.chatID)
    misc_record.premium_till += timedelta(days=user_data['extension_period'])
    db_session.commit()

    date_beautified = misc_record.premium_till.strftime("%B %d, %Y")
    message_content = "Your subscription has been extended till {}. Cheers!".format(
        date_beautified)
    bot.sendMessage(chat_id=user_record.chatID, text=message_content)
    admin_message = "Subscription for {} extended by {} day(s) ({})".format(
        user_record.PID, user_data['extension_period'], date_beautified)
    bot.sendMessage(chat_id=update.message.chat_id, text=admin_message)
    return ConversationHandler.END
コード例 #19
0
    def __parse_html__(self, html):
        rows = BeautifulSoup(html) \
            .find('table', {'class': 'tablesorter'}) \
            .find('tbody') \
            .find_all('tr')

        endpoint = rows[0].find_all('a')[0]['href']
        profile_html = BeautifulSoup(self.__get_profile__(endpoint))

        profile_data = [td.text for td in profile_html.find_all('table', {'id': 'general-info'})[0].find_all('td')]


        for row in rows:
            column_data = [ele.text.strip() for ele in row.find_all('td')]

            try:
                athlete = Athlete(
                    name=column_data[0],
                    country=column_data[1],
                    div_rank=column_data[2],
                    gender_rank=column_data[3],
                    overall_rank=column_data[4],
                    swim_time=column_data[5],
                    bike_time=column_data[6],
                    run_time=column_data[7],
                    finish_time=column_data[8],
                    points=column_data[9],
                    bib_id=profile_data[2],
                    age=profile_data[6],
                    state=profile_data[8],
                    profession=profile_data[12]
                )
                db_session.add(athlete)
                db_session.commit()
                yield athlete

            except ValueError as e:
                self.invalid_athlete_count += 1
                print('Invalid atheletes: {0}'.format(str(self.invalid_athlete_count)))
                continue