def add_favorite(bot, update, item: Bot, callback_alert=None):
    user = User.from_update(update)
    uid = util.uid_from_update(update)
    mid = util.mid_from_update(update)
    from components.basic import main_menu_buttons
    main_menu_markup = ReplyKeyboardMarkup(main_menu_buttons(uid in settings.MODERATORS))

    fav, created = Favorite.add(user=user, item=item)
    if created:
        Statistic.of(user, 'add-favorite', item.username)
        text = mdformat.love("{} added to your {}favorites.".format(fav.bot, '' if callback_alert else '/'))
        if callback_alert:
            update.callback_query.answer(text=text, show_alert=False)
        else:
            msg = util.send_md_message(bot, uid, text, to_edit=mid, reply_markup=main_menu_markup)
            mid = msg.message_id
            util.wait(bot, update)
            send_favorites_list(bot, update, to_edit=mid)
    else:
        text = mdformat.none_action(
            "{} is already a favorite of yours.{}".format(fav.bot, '' if callback_alert else ' /favorites'))
        if callback_alert:
            update.callback_query.answer(text=text, show_alert=False)
        else:
            util.send_md_message(bot, uid, text, reply_markup=main_menu_markup)
    return ConversationHandler.END
Esempio n. 2
0
def share_with_moderator(bot, update, bot_in_question, moderator):
    user = User.from_update(update)
    answer_text = mdformat.success(
        "I will ask {} to have a look at this submission.".format(
            moderator.plaintext))
    if update.callback_query:
        update.callback_query.answer(text=answer_text)

    buttons = [[
        InlineKeyboardButton('Yea, let me take this one!',
                             callback_data=util.callback_for_action(
                                 CallbackActions.APPROVE_REJECT_BOTS,
                                 {'id': bot_in_question.id}))
    ]]
    reply_markup = InlineKeyboardMarkup(buttons)
    text = "{} thinks that you have the means to inspect this bot submission:\n▶️ {}".format(
        user.markdown_short, bot_in_question)
    util.send_md_message(bot,
                         moderator.chat_id,
                         text,
                         reply_markup=reply_markup,
                         disable_web_page_preview=True)
    Statistic.of(
        update, 'share',
        'submission {} with {}'.format(bot_in_question.username,
                                       moderator.plaintext))
Esempio n. 3
0
def broadcast_preview(bot, update, user_data):
    uid = update.effective_user.id

    formatted_text = update.message.text_markdown
    for k, v in BROADCAST_REPLACEMENTS.items():
        # replace all occurences but mind escaping with \
        pattern = re.compile(r"(?<!\\){}".format(k), re.IGNORECASE)
        formatted_text = pattern.sub(v, formatted_text)
        formatted_text = re.sub(r"\\({})".format(k), r"\1", formatted_text,
                                re.IGNORECASE)

    user_data['broadcast'] = dict(
        user_data.get('broadcast', dict()),
        **dict(text=formatted_text, target_chat_id=settings.BOTLISTCHAT_ID))
    mode = user_data['broadcast'].get('mode', 'just_send')

    buttons = [
        InlineKeyboardButton(
            "Type again", callback_data=util.callback_for_action('broadcast')),
        InlineKeyboardButton("� Edit my message" if mode == 'editing' else
                             "▶� Send to @BotListChat",
                             callback_data=util.callback_for_action(
                                 'send_broadcast',
                                 {'P4l': settings.BOTLISTCHAT_ID})),
    ]

    reply_markup = InlineKeyboardMarkup(util.build_menu(buttons, 1))
    util.send_md_message(bot, uid, formatted_text, reply_markup=reply_markup)
    return ConversationHandler.END
    def finish(self):
        # set last update
        self.channel.last_update = datetime.date.today()
        self._save_channel()

        new_bots = Bot.select_new_bots()
        if not self.silent and len(new_bots) > 0:
            self.notify_admin("Sending notifications to subscribers...")
            subscribers = Notifications.select().where(Notifications.enabled == True)
            notification_count = 0
            for sub in subscribers:
                try:
                    util.send_md_message(self.bot, sub.chat_id,
                                         messages.BOTLIST_UPDATE_NOTIFICATION.format(
                                             n_bots=len(new_bots),
                                             new_bots=Bot.get_new_bots_markdown()))
                    notification_count += 1
                    sub.last_notification = datetime.date.today()
                    sub.save()
                except TelegramError:
                    pass
            self.sent['notifications'] = "Notifications sent to {} users.".format(
                notification_count)

        changes_made = len(self.sent) > 1 or len(self.sent['category']) > 0
        if changes_made:
            text = util.success('{}{}'.format('BotList updated successfully:\n\n',
                                              mdformat.results_list(self.sent)))
        else:
            text = mdformat.none_action("No changes were necessary.")

        log.info(self.sent)
        self.bot.formatter.send_or_edit(self.chat_id, text, to_edit=self.message_id)
Esempio n. 5
0
def prepare_transmission(bot, update, chat_data):
    chat_id = util.uid_from_update(update)
    text = mdformat.action_hint("Notify subscribers about this update?")
    reply_markup = InlineKeyboardMarkup(
        [[
            InlineKeyboardButton("☑ Notifications",
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SEND_BOTLIST,
                                     {'silent': False})),
            InlineKeyboardButton("Silent",
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SEND_BOTLIST,
                                     {'silent': True}))
        ],
         [
             InlineKeyboardButton("Re-send all Messages",
                                  callback_data=util.callback_for_action(
                                      CallbackActions.SEND_BOTLIST, {
                                          'silent': True,
                                          're': True
                                      }))
         ]])

    # # TODO
    # text = "Temporarily disabled"
    # reply_markup = None

    util.send_md_message(bot, chat_id, text, reply_markup=reply_markup)
def explore(bot, update, chat_data):
    cid = update.effective_chat.id
    uid = update.effective_user.id
    mid = util.mid_from_update(update)
    explorable_bots = Bot.explorable_bots()

    chat_data["explored"] = chat_data.get("explored", list())

    # don't explore twice
    for explored in chat_data["explored"]:
        explorable_bots.remove(explored)

    if len(explorable_bots) == 0:
        util.send_md_message(
            bot,
            cid,
            mdformat.none_action(
                "You have explored all the bots. Congratulations, you might be the first 😜"
            ),
        )
        return

    random_bot = random.choice(explorable_bots)

    buttons = [
        [
            InlineKeyboardButton(
                captions.ADD_TO_FAVORITES,
                callback_data=util.callback_for_action(
                    CallbackActions.ADD_TO_FAVORITES, {"id": random_bot.id}),
            ),
            InlineKeyboardButton(captions.SHARE,
                                 switch_inline_query=random_bot.username),
        ],
        [
            InlineKeyboardButton(
                random_explore_text(),
                callback_data=util.callback_for_action(
                    CallbackActions.EXPLORE_NEXT),
            )
        ],
    ]

    markup = InlineKeyboardMarkup(buttons)

    text = random_bot.detail_text

    if uid in settings.MODERATORS and util.is_private_message(update):
        text += "\n\n🛃 /edit{}".format(random_bot.id)

    msg = bot.formatter.send_or_edit(cid,
                                     text,
                                     to_edit=mid,
                                     reply_markup=markup)
    chat_data["explored"].append(random_bot)
Esempio n. 7
0
def send_next(bot, update, args=None):
    uid = util.uid_from_update(update)
    rows = None
    if args:
        try:
            rows = int(args[0])
        except:
            rows = None
    reply_markup = ReplyKeyboardMarkup(_crapPy_Tr0ll_kbmarkup(rows), one_time_keyboard=True, per_user=True)
    text = 'ɹoʇɐɹǝuǝb ǝɯɐuɹǝsn ɯɐɹbǝןǝʇ'
    util.send_md_message(bot, uid, text, reply_markup=reply_markup)
def _too_many_favorites_handler(bot, update, user):
    uid = util.uid_from_update(update)
    any_removed = False
    while too_many_favorites(user):
        oldest = Favorite.get_oldest(user)
        oldest.delete_instance()
        any_removed = True
        Statistic.of(update, 'had to lose a favorite because HE HAD TOO F****N MANY 😬')
    if any_removed:
        txt = "You have too many favorites, _they do not fit into a single message_. That's why I removed your " \
              "oldest bot, *{}*, from your list of favorites.".format(oldest.bot if oldest.bot else oldest.custom_bot)
        util.send_md_message(bot, uid, txt)
Esempio n. 9
0
def manage_subscription(bot, update):
    chat_id = update.effective_chat.id
    user_id = update.effective_user.id

    if util.is_group_message(update):
        admins = bot.get_chat_administrators(chat_id)
        if user_id not in admins:
            bot.formatter.send_failure(
                chat_id,
                "Sorry, but only Administrators of this group are allowed "
                "to manage subscriptions.")
            return

    text = "Would you like to be notified when new bots arrive at the @BotList?"
    buttons = [[
        InlineKeyboardButton(util.success("Yes"),
                             callback_data=util.callback_for_action(
                                 CallbackActions.SET_NOTIFICATIONS,
                                 {'value': True})),
        InlineKeyboardButton("No",
                             callback_data=util.callback_for_action(
                                 CallbackActions.SET_NOTIFICATIONS,
                                 {'value': False}))
    ]]
    reply_markup = InlineKeyboardMarkup(buttons)
    msg = util.send_md_message(bot, chat_id, text, reply_markup=reply_markup)
    return ConversationHandler.END
Esempio n. 10
0
def send_broadcast(bot, update, user_data):
    uid = update.effective_user.id

    try:
        bc = user_data['broadcast']
        text = bc['text']
        recipient = bc['target_chat_id']
        mode = bc.get('mode', 'just_send')
    except AttributeError:
        bot.formatter.send_failure(
            uid, "Missing attributes for broadcast. Aborting...")
        return ConversationHandler.END

    mid = bc.get('reply_to_message_id')

    if mode == 'replying':
        msg = util.send_md_message(bot,
                                   recipient,
                                   text,
                                   reply_to_message_id=mid)
    elif mode == 'editing':
        msg = bot.formatter.send_or_edit(recipient, text, to_edit=mid)
    else:
        msg = util.send_md_message(bot, recipient, text)

    # Post actions
    buttons = [
        InlineKeyboardButton(captions.PIN,
                             callback_data=util.callback_for_action(
                                 'pin_message', {'mid': msg.message_id})),
        InlineKeyboardButton('Add "Thank You" counter',
                             callback_data=util.callback_for_action(
                                 'add_thank_you', {
                                     'cid': recipient,
                                     'mid': msg.message_id
                                 })),
    ]
    reply_markup = InlineKeyboardMarkup(util.build_menu(buttons, 1))
    mid = util.mid_from_update(update)
    action_taken = "edited" if mode == 'editing' else "broadcasted"
    bot.formatter.send_or_edit(uid,
                               mdformat.success(
                                   "Message {}.".format(action_taken)),
                               mid,
                               reply_markup=reply_markup)
def send_next(bot, update, job_queue: JobQueue, args=None):
    uid = util.uid_from_update(update)
    num_rows = None
    if args:
        try:
            num_rows = int(args[0])
        except:
            num_rows = None

    reply_markup = ReplyKeyboardMarkup(_crapPy_Tr0ll_kbmarkup(num_rows),
                                       one_time_keyboard=False,
                                       per_user=True)
    text = "ɹoʇɐɹǝuǝb ǝɯɐuɹǝsn ɯɐɹbǝןǝʇ"
    util.send_md_message(bot, uid, text, reply_markup=reply_markup)

    if util.is_group_message(update):
        del_msg = bot.formatter.send_message(
            update.effective_chat.id, "Have fun in private ;)\n/easteregg")
        update.effective_message.delete()
        job_queue.run_once(lambda *_: del_msg.delete(safe=True),
                           4,
                           name="delete easteregg hint")
def add_favorite_handler(bot, update, args=None):
    uid = util.uid_from_update(update)
    from components.basic import main_menu_buttons
    main_menu_markup = ReplyKeyboardMarkup(main_menu_buttons(uid in settings.MODERATORS))

    if args:
        query = ' '.join(args) if isinstance(args, list) else args
        try:
            # TODO: add multiple
            username = re.match(settings.REGEX_BOT_IN_TEXT, query).groups()[0]
            try:
                # TODO: get exact database matches for input without `@`
                item = Bot.by_username(username, include_disabled=True)

                return add_favorite(bot, update, item)
            except Bot.DoesNotExist:
                buttons = [
                    InlineKeyboardButton(
                        "Yai!", callback_data=util.callback_for_action(CallbackActions.ADD_ANYWAY, {'u': username})),
                    InlineKeyboardButton("Nay...", callback_data=util.callback_for_action(CallbackActions.ADD_FAVORITE))
                ]
                reply_markup = InlineKeyboardMarkup([buttons])
                util.send_md_message(bot, uid,
                                     "{} is not in the @BotList. Do you want to add it to your {} anyway?".format(
                                         username, captions.FAVORITES),
                                     reply_markup=reply_markup)
        except AttributeError:
            # invalid bot username
            # TODO when does this happen?
            update.message.reply_text(
                util.failure("Sorry, but that is not a valid username. Please try again. /addfav"))
    else:
        buttons = [
            InlineKeyboardButton("Search inline", switch_inline_query_current_chat='')
        ]
        reply_markup = InlineKeyboardMarkup([buttons])

        bot.sendMessage(uid, messages.ADD_FAVORITE, reply_markup=ForceReply(selective=True))
    return ConversationHandler.END
Esempio n. 13
0
def share_with_moderator(bot, update, bot_in_question, moderator):
    user = User.from_update(update)

    buttons = [[
        InlineKeyboardButton(
            "Yea, let me take this one!",
            callback_data=util.callback_for_action(
                CallbackActions.APPROVE_REJECT_BOTS,
                {"id": bot_in_question.id}),
        )
    ]]
    reply_markup = InlineKeyboardMarkup(buttons)
    text = "{} thinks that you have the means to inspect this bot submission:\n▶️ {}".format(
        user.markdown_short, bot_in_question)
    try:
        util.send_md_message(
            bot,
            moderator.chat_id,
            text,
            reply_markup=reply_markup,
            disable_web_page_preview=True,
        )
        answer_text = mdformat.success(
            "I will ask {} to have a look at this submission.".format(
                moderator.plaintext))
    except Exception as e:
        answer_text = mdformat.failure(
            f"Could not contact {moderator.plaintext}: {e}")

    if update.callback_query:
        update.callback_query.answer(text=answer_text)

    Statistic.of(
        update,
        "share",
        "submission {} with {}".format(bot_in_question.username,
                                       moderator.plaintext),
    )
Esempio n. 14
0
 def send_or_edit(self, text, message_id, reply_markup=None):
     text = text[:
                 4096]  # hotfix - we can't send as multiple message because the list expects a unique message id
     sleep(3)
     while True:
         try:
             if self.resend:
                 return util.send_md_message(self.bot,
                                             self.channel.chat_id,
                                             text,
                                             timeout=120,
                                             disable_notification=True,
                                             reply_markup=reply_markup)
             else:
                 if reply_markup:
                     return self.bot.formatter.send_or_edit(
                         self.channel.chat_id,
                         text,
                         to_edit=message_id,
                         timeout=120,
                         disable_web_page_preview=True,
                         disable_notification=True,
                         reply_markup=reply_markup)
                 else:
                     return self.bot.formatter.send_or_edit(
                         self.channel.chat_id,
                         text,
                         to_edit=message_id,
                         timeout=120,
                         disable_web_page_preview=True,
                         disable_notification=True)
         except BadRequest as e:
             if 'chat not found' in e.message.lower():
                 self.notify_admin_err(
                     "I can't reach BotList Bot with chat-id `{}` (CHAT NOT FOUND error). "
                     "There's probably something wrong with the database.".
                     format(self.channel.chat_id))
                 raise e
             if 'message not modified' in e.message.lower():
                 return None
             else:
                 log.error(e)
                 raise e
         except RetryAfter as e:
             log.warning(f"Retrying after {e.retry_after} seconds...")
             sleep(e.retry_after)
             continue
Esempio n. 15
0
 def send_or_edit(self, text, message_id, reply_markup=None):
     sleep(3)
     try:
         if self.resend:
             return util.send_md_message(self.bot,
                                         self.channel.chat_id,
                                         text,
                                         timeout=120,
                                         disable_notification=True,
                                         reply_markup=reply_markup)
         else:
             if reply_markup:
                 return self.bot.formatter.send_or_edit(
                     self.channel.chat_id,
                     text,
                     to_edit=message_id,
                     timeout=120,
                     disable_web_page_preview=True,
                     disable_notification=True,
                     reply_markup=reply_markup)
             else:
                 return self.bot.formatter.send_or_edit(
                     self.channel.chat_id,
                     text,
                     to_edit=message_id,
                     timeout=120,
                     disable_web_page_preview=True,
                     disable_notification=True)
     except BadRequest as e:
         if 'chat not found' in e.message.lower():
             self.notify_admin_err(
                 "I can't reach BotList Bot with chat-id `{}` (CHAT NOT FOUND error). "
                 "There's probably something wrong with the database.".
                 format(self.channel.chat_id))
             raise e
         if 'message not modified' in e.message.lower():
             return None
         else:
             log.error(e)
             raise e
Esempio n. 16
0
def callback_router(bot, update, chat_data, user_data, job_queue):
    obj = json.loads(str(update.callback_query.data))
    user = User.from_update(update)

    try:
        if "a" in obj:
            action = obj["a"]

            # BOTLISTCHAT
            if action == CallbackActions.DELETE_CONVERSATION:
                botlistchat.delete_conversation(bot, update, chat_data)
            # HELP
            elif action == CallbackActions.HELP:
                help.help(bot, update)
            elif action == CallbackActions.CONTRIBUTING:
                help.contributing(bot, update)
            elif action == CallbackActions.EXAMPLES:
                help.examples(bot, update)
            # BASIC QUERYING
            elif action == CallbackActions.SELECT_CATEGORY:
                select_category(bot, update, chat_data)
            elif action == CallbackActions.SELECT_BOT_FROM_CATEGORY:
                category = Category.get(id=obj["id"])
                send_category(bot, update, chat_data, category)
            elif action == CallbackActions.SEND_BOT_DETAILS:
                item = Bot.get(id=obj["id"])
                send_bot_details(bot, update, chat_data, item)
            # FAVORITES
            elif action == CallbackActions.TOGGLE_FAVORITES_LAYOUT:
                value = obj["v"]
                favorites.toggle_favorites_layout(bot, update, value)
            elif action == CallbackActions.ADD_FAVORITE:
                favorites.add_favorite_handler(bot, update)
            elif action == CallbackActions.REMOVE_FAVORITE_MENU:
                favorites.remove_favorite_menu(bot, update)
            elif action == CallbackActions.REMOVE_FAVORITE:
                to_remove = Favorite.get(id=obj["id"])
                bot_details = to_remove.bot
                to_remove.delete_instance()
                if obj.get("details"):
                    send_bot_details(bot, update, chat_data, bot_details)
                else:
                    favorites.remove_favorite_menu(bot, update)
            elif action == CallbackActions.SEND_FAVORITES_LIST:
                favorites.send_favorites_list(bot, update)
            elif action == CallbackActions.ADD_ANYWAY:
                favorites.add_custom(bot, update, obj["u"])
            elif action == CallbackActions.ADD_TO_FAVORITES:
                details = obj.get("details")
                discreet = obj.get("discreet", False) or details
                item = Bot.get(id=obj["id"])
                favorites.add_favorite(bot,
                                       update,
                                       item,
                                       callback_alert=discreet)
                if details:
                    send_bot_details(bot, update, chat_data, item)
            # ACCEPT/REJECT BOT SUBMISSIONS
            elif action == CallbackActions.APPROVE_REJECT_BOTS:
                custom_approve_list = [Bot.get(id=obj["id"])]
                admin.approve_bots(bot,
                                   update,
                                   override_list=custom_approve_list)
            elif action == CallbackActions.ACCEPT_BOT:
                to_accept = Bot.get(id=obj["id"])
                admin.edit_bot_category(bot, update, to_accept,
                                        CallbackActions.BOT_ACCEPTED)
                # Run in x minutes, giving the moderator enough time to edit bot details
                job_queue.run_once(
                    lambda b, job: botlistchat.
                    notify_group_submission_accepted(b, job, to_accept),
                    settings.BOT_ACCEPTED_IDLE_TIME * 60,
                )
            elif action == CallbackActions.RECOMMEND_MODERATOR:
                bot_in_question = Bot.get(id=obj["id"])
                admin.recommend_moderator(bot, update, bot_in_question,
                                          obj["page"])
            elif action == CallbackActions.SELECT_MODERATOR:
                bot_in_question = Bot.get(id=obj["bot_id"])
                moderator = User.get(id=obj["uid"])
                admin.share_with_moderator(bot, update, bot_in_question,
                                           moderator)
                admin.approve_bots(bot, update, obj["page"])
            elif action == CallbackActions.REJECT_BOT:
                to_reject = Bot.get(id=obj["id"])
                notification = obj.get("ntfc", True)
                admin.reject_bot_submission(
                    bot,
                    update,
                    None,
                    to_reject,
                    verbose=False,
                    notify_submittant=notification,
                )
                admin.approve_bots(bot, update, obj["page"])
            elif action == CallbackActions.BOT_ACCEPTED:
                to_accept = Bot.get(id=obj["bid"])
                category = Category.get(id=obj["cid"])
                admin.accept_bot_submission(bot, update, to_accept, category)
            elif action == CallbackActions.COUNT_THANK_YOU:
                new_count = obj.get("count", 1)
                basic.count_thank_you(bot, update, new_count)
            # ADD BOT
            # elif action == CallbackActions.ADD_BOT_SELECT_CAT:
            #     category = Category.get(id=obj['id'])
            #     admin.add_bot(bot, update, chat_data, category)
            # EDIT BOT
            elif action == CallbackActions.EDIT_BOT:
                to_edit = Bot.get(id=obj["id"])
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_SELECT_CAT:
                to_edit = Bot.get(id=obj["id"])
                admin.edit_bot_category(bot, update, to_edit)
            elif action == CallbackActions.EDIT_BOT_CAT_SELECTED:
                to_edit = Bot.get(id=obj["bid"])
                cat = Category.get(id=obj["cid"])
                botproperties.change_category(bot, update, to_edit, cat)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_COUNTRY:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_country_menu(bot, update, to_edit)
            elif action == CallbackActions.SET_COUNTRY:
                to_edit = Bot.get(id=obj["bid"])
                if obj["cid"] == "None":
                    country = None
                else:
                    country = Country.get(id=obj["cid"])
                botproperties.set_country(bot, update, to_edit, country)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_DESCRIPTION:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_text_property(bot, update, chat_data,
                                                "description", to_edit)
            elif action == CallbackActions.EDIT_BOT_EXTRA:
                to_edit = Bot.get(id=obj["id"])
                # SAME IS DONE HERE, but manually
                botproperties.set_text_property(bot, update, chat_data,
                                                "extra", to_edit)
            elif action == CallbackActions.EDIT_BOT_NAME:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_text_property(bot, update, chat_data, "name",
                                                to_edit)
            elif action == CallbackActions.EDIT_BOT_USERNAME:
                to_edit = Bot.get(id=obj["id"])
                botproperties.set_text_property(bot, update, chat_data,
                                                "username", to_edit)
            # elif action == CallbackActions.EDIT_BOT_KEYWORDS:
            #     to_edit = Bot.get(id=obj['id'])
            #     botproperties.set_keywords_init(bot, update, chat_data, to_edit)
            elif action == CallbackActions.APPLY_ALL_CHANGES:
                to_edit = Bot.get(id=obj["id"])
                admin.apply_all_changes(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_INLINEQUERIES:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "inlinequeries",
                                           to_edit, value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_OFFICIAL:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "official", to_edit,
                                           value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_OFFLINE:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "offline", to_edit,
                                           value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.EDIT_BOT_SPAM:
                to_edit = Bot.get(id=obj["id"])
                value = bool(obj["value"])
                botproperties.toggle_value(bot, update, "spam", to_edit, value)
                admin.edit_bot(bot, update, chat_data, to_edit)
            elif action == CallbackActions.CONFIRM_DELETE_BOT:
                to_delete = Bot.get(id=obj["id"])
                botproperties.delete_bot_confirm(bot, update, to_delete)
            elif action == CallbackActions.DELETE_BOT:
                to_edit = Bot.get(id=obj["id"])
                botproperties.delete_bot(bot, update, to_edit)
                # send_category(bot, update, chat_data, to_edit.category)
            elif action == CallbackActions.ACCEPT_SUGGESTION:
                suggestion = Suggestion.get(id=obj["id"])
                components.botproperties.accept_suggestion(
                    bot, update, suggestion)
                admin.approve_suggestions(bot, update, page=obj["page"])
            elif action == CallbackActions.REJECT_SUGGESTION:
                suggestion = Suggestion.get(id=obj["id"])
                suggestion.delete_instance()
                admin.approve_suggestions(bot, update, page=obj["page"])
            elif action == CallbackActions.CHANGE_SUGGESTION:
                suggestion = Suggestion.get(id=obj["id"])
                botproperties.change_suggestion(bot,
                                                update,
                                                suggestion,
                                                page_handover=obj["page"])
            elif action == CallbackActions.SWITCH_SUGGESTIONS_PAGE:
                page = obj["page"]
                admin.approve_suggestions(bot, update, page)
            elif action == CallbackActions.SWITCH_APPROVALS_PAGE:
                admin.approve_bots(bot, update, page=obj["page"])
            elif action == CallbackActions.SET_NOTIFICATIONS:
                set_notifications(bot, update, obj["value"])
            elif action == CallbackActions.NEW_BOTS_SELECTED:
                show_new_bots(bot, update, chat_data, back_button=True)
            elif action == CallbackActions.ABORT_SETTING_KEYWORDS:
                to_edit = Bot.get(id=obj["id"])
                admin.edit_bot(bot, update, chat_data, to_edit)
            # SENDING BOTLIST
            elif action == CallbackActions.SEND_BOTLIST:
                silent = obj.get("silent", False)
                re_send = obj.get("re", False)
                botlist.send_botlist(bot,
                                     update,
                                     resend=re_send,
                                     silent=silent)
            elif action == CallbackActions.RESEND_BOTLIST:
                botlist.send_botlist(bot, update, resend=True)
            # BROADCASTING
            elif action == "send_broadcast":
                broadcasts.send_broadcast(bot, update, user_data)
            elif action == "pin_message":
                broadcasts.pin_message(bot, update, obj["mid"])
            elif action == "add_thank_you":
                basic.add_thank_you_button(bot, update, obj["cid"], obj["mid"])
            # EXPLORING
            elif action == CallbackActions.EXPLORE_NEXT:
                explore.explore(bot, update, chat_data)
    except Exception as e:
        traceback.print_exc()

        # get the callback action in plaintext
        actions = dict(CallbackActions.__dict__)
        a = next(k for k, v in actions.items() if v == obj.get("a"))
        util.send_md_message(
            bot,
            settings.DEVELOPER_ID,
            "Exception in callback query for {}:\n{}\n\nWith CallbackAction {}\n\nWith data:\n{}"
            .format(
                user.markdown_short,
                util.escape_markdown(e),
                util.escape_markdown(a),
                util.escape_markdown(str(obj)),
            ),
        )
    finally:
        bot.answerCallbackQuery(update.callback_query.id)
        return ConversationHandler.END
Esempio n. 17
0
def new_bot_submission(bot, update, chat_data, args=None, bot_checker=None):
    tg_user = update.message.from_user
    user = User.from_telegram_object(tg_user)
    if util.stop_banned(update, user):
        return
    reply_to = util.original_reply_id(update)

    if args:
        text = " ".join(args)
    else:
        text = update.message.text
        command_no_args = (len(re.findall(r"^/new\s*$", text)) > 0
                           or text.lower().strip() == "/new@botlistbot")
        if command_no_args:
            update.message.reply_text(
                util.action_hint(
                    "Please use this command with an argument. For example:\n/new @mybot 🔎"
                ),
                reply_to_message_id=reply_to,
            )
            return

    # `#new` is already checked by handler
    try:
        username = re.match(settings.REGEX_BOT_IN_TEXT, text).groups()[0]
        if username.lower() == "@" + settings.SELF_BOT_NAME.lower():
            log.info("Ignoring {}".format(text))
            return
    except AttributeError:
        if args:
            update.message.reply_text(
                util.failure(
                    "Sorry, but you didn't send me a bot `@username`."),
                quote=True,
                parse_mode=ParseMode.MARKDOWN,
                reply_to_message_id=reply_to,
            )
        log.info("Ignoring {}".format(text))
        # no bot username, ignore update
        return

    try:
        new_bot = Bot.by_username(username, include_disabled=True)
        if new_bot.disabled:
            update.message.reply_text(
                util.failure("{} is banned from the @BotList.".format(
                    new_bot.username)),
                reply_to_message_id=reply_to,
            )
        elif new_bot.approved:
            update.message.reply_text(
                util.action_hint(
                    "Sorry fool, but {} is already in the @BotList 😉".
                    format(new_bot.username)),
                reply_to_message_id=reply_to,
            )
        else:
            update.message.reply_text(
                util.action_hint(
                    "{} has already been submitted. Please have patience...".
                    format(new_bot.username)),
                reply_to_message_id=reply_to,
            )
        return
    except Bot.DoesNotExist:
        new_bot = Bot(
            revision=Revision.get_instance().next,
            approved=False,
            username=username,
            submitted_by=user,
        )

    new_bot.inlinequeries = "🔎" in text
    new_bot.official = "🔹" in text

    # find language
    languages = Country.select().execute()
    for lang in languages:
        if lang.emoji in text:
            new_bot.country = lang

    new_bot.date_added = datetime.date.today()

    description_reg = re.match(settings.REGEX_BOT_IN_TEXT + " -\s?(.*)", text)
    description_notify = ""
    if description_reg:
        description = description_reg.group(2)
        new_bot.description = description
        description_notify = " Your description was included."

    new_bot.save()

    if (util.is_private_message(update)
            and util.uid_from_update(update) in settings.MODERATORS):
        from components.explore import send_bot_details

        send_bot_details(bot, update, chat_data, new_bot)
    else:
        update.message.reply_text(
            util.success("You submitted {} for approval.{}".format(
                new_bot, description_notify)),
            parse_mode=ParseMode.MARKDOWN,
            reply_to_message_id=reply_to,
        )

        # Ask the user to fill in the bot details
        util.send_md_message(
            bot,
            update.effective_user.id,
            "Congratulations, you just submitted a bot to the @BotList. Please help us fill in the details below:",
        )
        edit_bot(bot, update, chat_data, to_edit=new_bot)

    try:
        check_submission(bot, bot_checker, new_bot)
    except Exception as e:
        log.exception(e)

    return ConversationHandler.END