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
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
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
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
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
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
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
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