Esempio n. 1
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
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
Esempio n. 5
0
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
Esempio n. 6
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
Esempio n. 7
0
    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
Esempio n. 8
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