Пример #1
0
def decrypt(bot, update):
    config = Configuration()
    uid = update.message.from_user.id
    try:
        application_key = update.message.text
        application_key = application_key.strip()
        if not application_key:
            message = "Enter a proper key!\nDo you want to try again? (Yes/No)"
            update.message.reply_text(message, parse_mode="Markdown")
            return ENTERKEY
        else:

            print(uid)
            user_in_db = db_interface.get_user(uid)
            print(user_in_db)
            username = user_in_db.user_name
            decrypted_password = Encrypt(
                user_in_db.encrypted_pass, application_key
            ).decrypt()
            if not decrypted_password:
                message = "A wrong application key has been entered\nDo you want to try again? (Yes/No)"
                update.message.reply_text(message, parse_mode="Markdown")
                return ENTERKEY
            # passes into celery. No longer my problem.
            config = Configuration()
            update_class = config.CELERY_INSTANCE.signature(
                "Controllers.celery_queue.update_user"
            )
            """
            def update_user(
                    telegram_id:str,
                    user_name:str,
                    password:str,
                    bot
                ):
            """
            r = config.REDIS_INSTANCE
            r.set(uid, 1)
            update_class.delay(
                uid, username, decrypted_password, jsonpickle.encode(bot)
            )
            message = "Your details have been enqueued for scraping!\nThis process might take up to 5 minutes, please wait for the results."
            update.message.reply_text(message, parse_mode="Markdown")
            return ConversationHandler.END
    except Exception as e:
        update.message.reply_text("Unknown error occured", parse_mode="Markdown")
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL, text=f"An error occured at {local_time}"
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in get timetable by {uid}.",
        )
        return ConversationHandler.END
Пример #2
0
def megaphone(bot, update):
    uid = update.message.from_user.id
    config = Configuration()
    try:
        message = update.message.text[6:]
        if str(uid) in config.ADMIN_LIST:
            list_of_ids = db_interface.get_all_telegram_ids()
            count = 0
            for id in list_of_ids:
                try:
                    bot.send_message(chat_id=id,
                                     text=message,
                                     parse_mode="HTML")
                    count += 1
                except Unauthorized:
                    pass

            bot.send_message(chat_id=config.ERROR_CHANNEL,
                             text=f"{count} messages megaphoned")
        else:
            update.message.reply_text("You are not an administrator!")
    except Exception as e:
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in megaphone.",
        )
Пример #3
0
def help(bot, update):
    config = Configuration()
    try:
        cid = update.message.chat_id
        message_id = update.message.message_id
        hm = HelpMessage()
        msg = hm.get_help_message()
        print(f"hm:{msg}")
        bot.send_message(
            chat_id=cid,
            text=msg,
            disable_web_page_preview=True,
            reply_to_message_id=message_id,
            parse_mode="Markdown",
        )

    except Exception as e:
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL, text=f"An error occured at {local_time}"
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL, text=f"This message was triggered in help."
        )
Пример #4
0
def morning_alert(bot, update):
    config = Configuration()
    try:
        user_list = db_interface.get_all_users_alert("morning")
        for user in user_list:
            # cur_dt = datetime.now().replace(hour=0, minute=0, second=0)
            list_of_cur_classes = user.get_list_of_class_by_date(
                datetime.now().date())
            rm = ReminderMessage(
                list_of_cur_classes,
                "Morning",
                user.name,
                datetime.strftime(datetime.now(), "%b %d %Y"),
            )
            msg = rm.get_message()
            bot.send_message(chat_id=user.telegram_id,
                             text=msg,
                             parse_mode="Markdown")
    except Exception as e:
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in morning reminder.",
        )
Пример #5
0
def toggle_night(bot, update):
    uid = update.message.from_user.id
    config = Configuration()
    try:
        if db_interface.user_exist(uid):
            if db_interface.toggle_alert(uid, False):
                message = "Nightly alert has been sucessfully *enabled*!"
            else:
                message = "Nightly alert has been sucessfully *disabled*!"
            update.message.reply_text(message, parse_mode="Markdown")
        else:
            message_array = ["You are not registered!\n"]
            message_array.append("Would you like to register using /register?")
            message = "".join(message_array)
            update.message.reply_text(message, parse_mode="Markdown")
    except Exception as e:
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=
            f"This message was triggered in nightly reminder toggle. Triggered by: {uid}",
        )
Пример #6
0
def get_today(bot, update):
    uid = update.message.from_user.id
    config = Configuration()

    try:
        if db_interface.user_exist(uid):
            current_date = datetime.now(pytz.timezone("Asia/Singapore")).date()
            # sets time to midnight.
            current_date = datetime.combine(current_date, time())
            # gets a list of IndividualClassStructure objects.
            classes_list = db_interface.get_current_class(
                uid, current_date, current_date)
            # sorts by start time
            classes_list.sort(key=lambda x: x.start_time)
            lsd = db_interface.get_last_sync_date(uid)

            mt = MessageTimetable(None, lsd)
            for c in classes_list:
                mt.add_class_list(c.class_numeric_day, c)
            formatted_message = mt.get_today()

            update.message.reply_text(
                formatted_message,
                disable_web_page_preview=True,
                quote=True,
                parse_mode="Markdown",
            )

        else:
            message_array = [
                f"Unable to find telegram ID {uid} in our database\n"
            ]
            message_array.append(
                "Kindly register using /register before attempting to retrieve a timetable."
            )
            message = "".join(message_array)
            update.message.reply_text(message, parse_mode="Markdown")

    except Exception as e:
        print(str(e))
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in get today timetable by {uid}.",
        )
Пример #7
0
def start_register(bot, update):
    """
    Kickstarts registeration process. Gets name and 
    subsequently passes it to the next handler in process.
    """
    try:
        config = Configuration()
        # gets the telegram ID
        tg_id = update.message.from_user.id
        # Checks the database for the user ID
        message_array = []
        if not db_interface.user_exist(tg_id):
            r = config.REDIS_INSTANCE
            if not r.get(tg_id):
                message_array.append(
                    "Hi! Let's get started by registering with this bot\n"
                )
                message_array.append(
                    "❇️By using this bot, you hereby declare that you have read the documentation and disclaimer on github.\n"
                )
                message_array.append(
                    "❇️*As such, you release the author from any responsibilities of events incurred by the usage of this bot*\n"
                )
                message_array.append(
                    "❇️At any point of time during this process, you can stop the bot by typing /cancel\n"
                )
                message_array.append("Now, can I have your *name*?")
                message = "".join(message_array)
                update.message.reply_text(message, parse_mode="Markdown")
                # instructs the chatbox to move to the next method.
                return NAME
            else:
                message_array.append("You are already enqueued!\n")
                message_array.append(
                    "If you are encountering issues, please pm @fatalityx directly."
                )
                message = "".join(message_array)
                update.message.reply_text(message, parse_mode="Markdown")
                return ConversationHandler.END
        else:
            message_array.append("You are already registered!\n")
            message_array.append(
                "If you have forgotten your application key, please use /forget to clear your information and re-register."
            )
            message = "".join(message_array)
            update.message.reply_text(message, parse_mode="Markdown")
            return ConversationHandler.END

    except Exception as e:
        print(str(e))  # To be changed.
        return ConversationHandler.END
Пример #8
0
def get_ics(bot, update):
    print("Get ICS method called")
    config = Configuration()
    is_callback = False
    if not update.message:
        uid = update.callback_query.from_user.id
        is_callback = True
    else:
        uid = update.message.from_user.id
    try:
        if db_interface.user_exist(uid):
            print("DB Interface exists")
            filepath = f"./ics/{uid}.ics"
            # Gets a list of classes
            classes_list = db_interface.get_all_classes(uid)
            print(classes_list)
            ics_model = ICSParser(classes_list)
            ics_model.convert_to_event()
            with open(filepath, "w") as f:
                f.writelines(ics_model.calendar)

            # sends the message
            bot.send_document(chat_id=uid, document=open(filepath, "rb"))
        else:
            message_array = [
                f"Unable to find telegram ID {uid} in our database\n"
            ]
            message_array.append(
                "Kindly register using /register before attempting to retrieve a timetable."
            )
            message = "".join(message_array)
            update.message.reply_text(message, parse_mode="Markdown")

    except Exception as e:
        print(str(e))
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in get timetable by {uid}.",
        )
Пример #9
0
def application_key(bot, update, user_data):
    try:
        user_input_application_key = update.message.text
        user_input_application_key = user_input_application_key.strip()
        if len(user_input_application_key) <= 16:
            user_data["application_key"] = user_input_application_key

            config = Configuration()
            """ci = Celery(
                            'queue',
                            broker='amqp://',
                            backend='rpc://',
                            include=['Controllers.celery_queue']
                        )"""
            cel_reg = config.CELERY_INSTANCE.signature(
                "Controllers.celery_queue.register_user"
            )
            # marks the user as already using the queue in redis.
            r = config.REDIS_INSTANCE
            r.set(user_data["user_id"], 1)
            # Starts a celery task
            cel_reg.delay(user_data, jsonpickle.encode(bot))

            message_array = ["Your details have been enqueued for scraping!\n"]
            message_array.append(
                f"You are currently position {len(r.keys())} in the queue.\n"
            )
            message_array.append(
                "This process might take up to 5 minutes, please wait for the results."
            )
            message = "".join(message_array)
            update.message.reply_text(message, parse_mode="Markdown")
            return ConversationHandler.END
        else:
            if not user_input_application_key:
                message = "Please enter an application key"
            else:
                message = "Please enter an encryption key that is under 17 characters."
            update.message.reply_text(message, parse_mode="Markdown")
            return KEY

    except Exception as e:

        print(str(e))
        return ConversationHandler.END
Пример #10
0
def update_user(telegram_id: str, user_name: str, password: str, bot):

    config = Configuration()
    r = config.REDIS_INSTANCE
    bot = jsonpickle.decode(bot)
    try:

        list_of_classes = get_timetable(user_name, password, telegram_id, bot)
        dbInterface.update_classes(list_of_classes, telegram_id)
        message = (
            f"A total of *{len(list_of_classes)}* records were resynced to the database"
        )
        r.delete(telegram_id)
        bot.send_message(chat_id=telegram_id,
                         text=message,
                         parse_mode="Markdown")
    except UnableToLogin:
        # Unable to login with given credentials.
        # new_ripper attempts to login and raises an UnableToLogin exception
        # if it cant be logged in.
        error_message = ["Unable to login with your credentials!\n"]
        error_message.append(
            "Please try to wipe your details and register again using /register"
        )
        err = "".join(error_message)
        r.delete(telegram_id)
        bot.send_message(chat_id=telegram_id, text=err, parse_mode="Markdown")
    except Exception as e:
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=
            f"This message was triggered in celery. Triggered by: {telegram_id}",
        )
        r.delete(telegram_id)
        pass
Пример #11
0
def enter_key(bot, update):
    config = Configuration()
    try:
        message = "Please enter your decryption key\n"
        update.message.reply_text(message, parse_mode="Markdown")
        return DECRYPT

    except Exception as e:
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL, text=f"An error occured at {local_time}"
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in enter your decryption key.",
        )
        return ConversationHandler.END
Пример #12
0
def update(bot, update):
    """
    confirms that the update is meant to be handled.
    """
    config = Configuration()
    try:
        uid = update.message.from_user.id
        if not db_interface.user_exist(uid):
            update.message.reply_text("You are not registered! Please register first")
            return ConversationHandler.END
        r = config.REDIS_INSTANCE
        if r.get(uid):
            update.message.reply_text("You are already enqueued in the queue!")
            return ConversationHandler.END
        message_array = ["Do you want to update your timetable?\n"]
        message_array.append("❇️This will erase *all* previous timetable schedules\n")
        message_array.append("❇️Please reply with a yes or no\n")
        message_array.append("❇️To exit this state, please use /cancel\n")
        message = "".join(message_array)
        update.message.reply_text(message, parse_mode="Markdown")
        return ENTERKEY

    except Exception as e:
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL, text=f"An error occured at {local_time}"
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in get timetable by {uid}.",
        )
        return ConversationHandler.END
Пример #13
0
 def __init__(self):
     self.__config = Configuration()
     self.__flush_redis_cache()
     q = mq.MessageQueue(
         all_burst_limit=30,
         all_time_limit_ms=1000,
         group_burst_limit=20,
         group_time_limit_ms=60000,
         exc_route=None,
         autostart=True,
     )
     # set connection pool size for bot
     request = Request(con_pool_size=8)
     self.__queue_bot = MQBot(self.__config.BOT_API_KEY,
                              request=request,
                              mqueue=q)
     self.__updater = Updater(bot=self.__queue_bot)
     self.__dp = self.__updater.dispatcher
     self.__jq = self.__updater.job_queue
     self.__reg()
     self.__update()
     self.__forget()
     self.__timetable()
     self.__ics()
     self.__fuck()
     self.__cbq()
     self.__mega()
     self.__alert()
     self.__nightly()
     self.__toggles()
     self.__help()
     self.__today()
     self.__test_alert()
     self.start_webhooks()  # must always come last.
     print("Bot online")
     print(f"Current Time: {datetime.now()}")
Пример #14
0
def register_user(user_data: Dict, bot):
    config = Configuration()
    r = config.REDIS_INSTANCE
    user_id = user_data["user_id"]
    try:
        bot = jsonpickle.decode(bot)

        username = user_data["username"]
        password = user_data["password"]
        name = user_data["name"]
        user_input_application_key = user_data["application_key"]
        encrypted_password = Encrypt(user_data["password"],
                                     user_input_application_key).encrypt()
        try:
            timetable_result = get_timetable(username, password, user_id, bot)
            print(f"Classes retrieved: {len(timetable_result)}")
            # Now, let us begin constructing our database insertion object.
            obj_to_insert = UserObject(user_id, username, name,
                                       encrypted_password)
            obj_to_insert.add_classes(timetable_result)
            dbInterface.insert_new_user(obj_to_insert)
            success_message = [
                f"A total of {obj_to_insert.get_class_leng()} records have been synced to the database\n"
            ]
            success_message.append(
                "You can now use /timetable to retrieve your timetable\n")
            success_message.append(
                "In addition, please take note of the following handlers:\n")
            success_message.append(
                "```Daily reminder at 7am in the morning - /alert ```\n")
            success_message.append(
                "```Nightly reminder at 10pm at night - /nightly ```\n")

            success_message.append("Both of these handlers act as a toggle.")
            message = "".join(success_message)
            r.delete(user_id)
            bot.send_message(chat_id=user_id,
                             text=message,
                             parse_mode="Markdown")

        except UnableToLogin:
            # Unable to login with given credentials.
            # new_ripper attempts to login and raises an UnableToLogin exception
            # if it cant be logged in.
            error_message = ["Unable to login with your credentials!\n"]
            error_message.append(
                "Please try to register again using /register")
            err = "".join(error_message)
            r.delete(user_id)
            bot.send_message(chat_id=user_id, text=err, parse_mode="Markdown")
    except Exception as e:
        # to send to github
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=
            f"This message was triggered in celery. User data: {str(user_data)}",
        )
        r.delete(user_id)
        pass
Пример #15
0
def get_timetable(bot, update):
    config = Configuration()
    is_callback = False
    if not update.message:
        uid = update.callback_query.from_user.id
        is_callback = True
    else:
        uid = update.message.from_user.id
    try:
        if db_interface.user_exist(uid):
            # if its not a callback type:
            if not is_callback:
                current_date = date.today()
                # sets time to midnight.
                current_date = datetime.combine(current_date, time())
            else:  # if it is a callback
                query = update.callback_query
                current_date = datetime.strptime(query.data[2:], "%b%d%Y")

            start_date = current_date - timedelta(days=current_date.weekday())
            end_date = start_date + timedelta(days=6)

            # gets a list of IndividualClassStructure objects.
            classes_list = db_interface.get_current_class(
                uid, start_date, end_date)
            # sorts by start time
            classes_list.sort(key=lambda x: x.start_time)
            lsd = db_interface.get_last_sync_date(uid)

            # prepares the message timetable object
            cur_week = datetime.strftime(
                (current_date - timedelta(days=current_date.weekday())),
                "%b %d %Y")
            print(cur_week)
            mt = MessageTimetable(cur_week, lsd)
            for c in classes_list:
                mt.add_class_list(c.class_numeric_day, c)
            formatted_message = mt.get_message()

            # prepares the keyboard.
            reply_kb = get_keyboard(uid, current_date, start_date, end_date)
            reply_markup = InlineKeyboardMarkup(reply_kb)
            # sends the message
            if is_callback:
                bot.edit_message_text(
                    text=formatted_message,
                    chat_id=update.callback_query.message.chat_id,
                    message_id=update.callback_query.message.message_id,
                    disable_web_page_preview=True,
                    reply_markup=reply_markup,
                    parse_mode="Markdown",
                )
            else:
                update.message.reply_text(
                    formatted_message,
                    reply_markup=reply_markup,
                    disable_web_page_preview=True,
                    quote=True,
                    parse_mode="Markdown",
                )
        else:
            message_array = [
                f"Unable to find telegram ID {uid} in our database\n"
            ]
            message_array.append(
                "Kindly register using /register before attempting to retrieve a timetable."
            )
            message = "".join(message_array)
            update.message.reply_text(message, parse_mode="Markdown")

    except Exception as e:
        print(str(e))
        local = arrow.utcnow().to("Asia/Singapore")
        local_time = local.format("YYYY-MM-DD HH:mm:ss ZZ")
        bot.send_message(chat_id=config.ERROR_CHANNEL,
                         text=f"An error occured at {local_time}")
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"The error was: {traceback.format_exc()}",
        )
        bot.send_message(
            chat_id=config.ERROR_CHANNEL,
            text=f"This message was triggered in get timetable by {uid}.",
        )
Пример #16
0
 def __init__(self):
     self.__cfg = Configuration()
     # Instantiated only ONCE will reuse throughout connection
     self.__mongo = MongoClient(self.__cfg.MONGOURI)
     self.__db = self.__mongo.timetable
Пример #17
0
 def __init__(self):
     self.__cfg = Configuration()