Beispiel #1
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)
Beispiel #2
0
def set_country_menu(bot, update, to_edit):
    uid = util.uid_from_update(update)
    countries = Country.select().order_by(Country.name).execute()

    buttons = util.build_menu([
        InlineKeyboardButton('{} {}'.format(c.emojized, c.name),
                             callback_data=util.callback_for_action(
                                 CallbackActions.SET_COUNTRY, {
                                     'cid': c.id,
                                     'bid': to_edit.id
                                 })) for c in countries
    ], 3)
    buttons.insert(0, [
        InlineKeyboardButton(captions.BACK,
                             callback_data=util.callback_for_action(
                                 CallbackActions.EDIT_BOT,
                                 {'id': to_edit.id})),
        InlineKeyboardButton("None",
                             callback_data=util.callback_for_action(
                                 CallbackActions.SET_COUNTRY, {
                                     'cid': 'None',
                                     'bid': to_edit.id
                                 })),
    ])
    return bot.formatter.send_or_edit(
        uid,
        util.action_hint(
            "Please select a country/language for {}".format(to_edit)),
        to_edit=util.mid_from_update(update),
        reply_markup=InlineKeyboardMarkup(buttons))
Beispiel #3
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
Beispiel #4
0
def recommend_moderator(bot, update, bot_in_question, page):
    uid = update.effective_user.id
    mid = util.mid_from_update(update)
    moderators = User.select().where((User.chat_id << settings.MODERATORS)
                                     & (User.chat_id != uid))
    buttons = [
        InlineKeyboardButton(u.first_name,
                             callback_data=util.callback_for_action(
                                 CallbackActions.SELECT_MODERATOR, {
                                     'bot_id': bot_in_question.id,
                                     'uid': u.id,
                                     'page': page
                                 })) for u in moderators
    ]
    buttons.insert(
        0,
        InlineKeyboardButton(captions.BACK,
                             callback_data=util.callback_for_action(
                                 CallbackActions.SWITCH_APPROVALS_PAGE,
                                 {'page': page})))
    reply_markup = InlineKeyboardMarkup(util.build_menu(buttons, 1))
    text = mdformat.action_hint(
        "Select a moderator you think is better suited to evaluate the submission of {}."
        .format(str(bot_in_question)))
    bot.formatter.send_or_edit(uid,
                               text,
                               to_edit=mid,
                               reply_markup=reply_markup)
Beispiel #5
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 send_category(bot, update, chat_data, category):
    uid = util.uid_from_update(update)
    cid = update.effective_chat.id
    bots = Bot.of_category_without_new(
        category)[:settings.MAX_BOTS_PER_MESSAGE]
    bots_with_description = [b for b in bots if b.description is not None]
    detailed_buttons_enabled = len(
        bots_with_description) > 0 and util.is_private_message(update)

    callback = CallbackActions.SEND_BOT_DETAILS

    if detailed_buttons_enabled:
        buttons = [
            InlineKeyboardButton(
                x.username,
                callback_data=util.callback_for_action(callback, {"id": x.id}),
            ) for x in bots_with_description
        ]
    else:
        buttons = []
    menu = util.build_menu(buttons, 2)
    menu.insert(
        0,
        [
            InlineKeyboardButton(
                captions.BACK,
                callback_data=util.callback_for_action(
                    CallbackActions.SELECT_CATEGORY),
            ),
            InlineKeyboardButton(
                "Show in BotList",
                url="http://t.me/botlist/{}".format(
                    category.current_message_id),
            ),
            InlineKeyboardButton("Share", switch_inline_query=category.name),
        ],
    )
    txt = "There are *{}* bots in the category *{}*:\n\n".format(
        len(bots), str(category))

    if uid in settings.MODERATORS and util.is_private_message(update):
        # append admin edit buttons
        txt += "\n".join(["{} — /edit{} 🛃".format(b, b.id) for b in bots])
    else:
        txt += "\n".join([str(b) for b in bots])

    if detailed_buttons_enabled:
        txt += "\n\n" + util.action_hint(
            "Press a button below to get a detailed description.")

    reply_markup = InlineKeyboardMarkup(menu)
    reply_markup, callback = botlistchat.append_restricted_delete_button(
        update, chat_data, reply_markup)
    msg = bot.formatter.send_or_edit(cid,
                                     txt,
                                     to_edit=util.mid_from_update(update),
                                     reply_markup=reply_markup)
    callback(msg)
    Statistic.of(update, "menu", "of category {}".format(str(category)),
                 Statistic.ANALYSIS)
def _select_category_buttons(callback_action=None):
    if callback_action is None:
        # set default
        callback_action = CallbackActions.SELECT_BOT_FROM_CATEGORY
    categories = Category.select().order_by(Category.name.asc()).execute()

    buttons = util.build_menu(
        [
            InlineKeyboardButton(
                "{}{}".format(emoji.emojize(c.emojis, use_aliases=True),
                              c.name),
                callback_data=util.callback_for_action(callback_action,
                                                       {"id": c.id}),
            ) for c in categories
        ],
        2,
    )
    buttons.insert(
        0,
        [
            InlineKeyboardButton(
                "🆕 New Bots",
                callback_data=util.callback_for_action(
                    CallbackActions.NEW_BOTS_SELECTED),
            )
        ],
    )
    return buttons
Beispiel #8
0
def set_keywords(bot, update, chat_data, to_edit):
    chat_id = util.uid_from_update(update)
    keywords = Keyword.select().where(Keyword.entity == to_edit)
    chat_data['edit_bot'] = to_edit
    set_keywords_msgid = chat_data.get('set_keywords_msg')

    kw_remove_buttons = [
        InlineKeyboardButton('{} ✖️'.format(x),
                             callback_data=util.callback_for_action(
                                 CallbackActions.REMOVE_KEYWORD, {
                                     'id': to_edit.id,
                                     'kwid': x.id
                                 })) for x in keywords
    ]
    buttons = util.build_menu(
        kw_remove_buttons,
        2,
        header_buttons=[
            InlineKeyboardButton(captions.DONE,
                                 callback_data=util.callback_for_action(
                                     CallbackActions.ABORT_SETTING_KEYWORDS,
                                     {'id': to_edit.id}))
        ])
    reply_markup = InlineKeyboardMarkup(buttons)
    msg = util.send_or_edit_md_message(
        bot,
        chat_id,
        util.action_hint(
            'Send me the keywords for {} one by one...\n\n{}'.format(
                util.escape_markdown(to_edit.username),
                messages.KEYWORD_BEST_PRACTICES)),
        to_edit=set_keywords_msgid,
        reply_markup=reply_markup)
    chat_data['set_keywords_msg'] = msg.message_id
    return BotStates.SENDING_KEYWORDS
def _help_markup():
    buttons = [[
        InlineKeyboardButton(captions.HELP, callback_data=util.callback_for_action(const.CallbackActions.HELP)),
        InlineKeyboardButton(captions.CONTRIBUTING,
                             callback_data=util.callback_for_action(const.CallbackActions.CONTRIBUTING)),
        InlineKeyboardButton(captions.EXAMPLES, callback_data=util.callback_for_action(const.CallbackActions.EXAMPLES)),
    ], [
        InlineKeyboardButton('Try me inline!', switch_inline_query_current_chat='')
    ]]
    return InlineKeyboardMarkup(buttons)
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)
def change_suggestion(bot, update, suggestion, page_handover):
    cid = update.effective_chat.id
    mid = update.effective_message.message_id

    text = '{}:\n\n{}'.format(str(suggestion), suggestion.value)
    if suggestion.action == 'description':
        callback_action = CallbackActions.EDIT_BOT_DESCRIPTION
    elif suggestion.action == 'extra':
        callback_action = CallbackActions.EDIT_BOT_EXTRA
    elif suggestion.action == 'name':
        callback_action = CallbackActions.EDIT_BOT_NAME
    elif suggestion.action == 'username':
        callback_action = CallbackActions.EDIT_BOT_USERNAME
    else:
        return  # should not happen

    buttons = [[
        InlineKeyboardButton(captions.BACK,
                             callback_data=util.callback_for_action(
                                 CallbackActions.SWITCH_SUGGESTIONS_PAGE,
                                 {'page': page_handover}))
    ],
               [
                   InlineKeyboardButton(
                       "{} Accept".format(Emoji.WHITE_HEAVY_CHECK_MARK),
                       callback_data=util.callback_for_action(
                           CallbackActions.ACCEPT_SUGGESTION, {
                               'id': suggestion.id,
                               'page': page_handover
                           })),
                   InlineKeyboardButton(captions.CHANGE_SUGGESTION,
                                        callback_data=util.callback_for_action(
                                            callback_action, {
                                                'id': suggestion.id,
                                                'page': page_handover
                                            })),
                   InlineKeyboardButton(Emoji.CROSS_MARK,
                                        callback_data=util.callback_for_action(
                                            CallbackActions.REJECT_SUGGESTION,
                                            {
                                                'id': suggestion.id,
                                                'page': page_handover
                                            }))
               ]]

    reply_markup = InlineKeyboardMarkup(buttons)
    bot.formatter.send_or_edit(cid,
                               text,
                               to_edit=mid,
                               disable_web_page_preview=True,
                               reply_markup=reply_markup)
Beispiel #12
0
def delete_bot_confirm(bot, update, to_edit):
    chat_id = util.uid_from_update(update)
    reply_markup = InlineKeyboardMarkup([[
        InlineKeyboardButton("Yes, delete it!",
                             callback_data=util.callback_for_action(
                                 CallbackActions.DELETE_BOT,
                                 {'id': to_edit.id})),
        InlineKeyboardButton(captions.BACK,
                             callback_data=util.callback_for_action(
                                 CallbackActions.EDIT_BOT, {'id': to_edit.id}))
    ]])
    bot.formatter.send_or_edit(chat_id,
                               "Are you sure?",
                               to_edit=util.mid_from_update(update),
                               reply_markup=reply_markup)
Beispiel #13
0
def append_restricted_delete_button(
        update, chat_data, reply_markup
) -> Tuple[Optional[ReplyMarkup], Callable[[Message], None]]:
    uid = update.effective_user.id
    command_mid = update.effective_message.message_id

    if not util.is_group_message(update) or not isinstance(
            reply_markup, InlineKeyboardMarkup):
        return reply_markup, lambda _: None

    def append_callback(message):
        if message is None:  # No message was saved
            return
        if isinstance(message, Message):
            mid = message.message_id
        else:
            mid = message
        deletions_pending = chat_data.get("deletions_pending", dict())
        if not deletions_pending.get(mid):
            deletions_pending[mid] = dict(user_id=uid, command_id=command_mid)
            chat_data["deletions_pending"] = deletions_pending

    buttons = reply_markup.inline_keyboard
    buttons.append([
        InlineKeyboardButton(
            captions.random_done_delete(),
            callback_data=util.callback_for_action(
                CallbackActions.DELETE_CONVERSATION),
        )
    ])
    reply_markup.inline_keyboard = buttons
    return reply_markup, append_callback
Beispiel #14
0
def show_new_bots(bot, update, chat_data, back_button=False):
    chat_id = update.effective_chat.id
    channel = helpers.get_channel()
    buttons = [[
        InlineKeyboardButton("Show in BotList",
                             url="http://t.me/{}/{}".format(
                                 channel.username, channel.new_bots_mid)),
        InlineKeyboardButton("Share",
                             switch_inline_query=messages.NEW_BOTS_INLINEQUERY)
    ]]
    if back_button:
        buttons[0].insert(
            0,
            InlineKeyboardButton(captions.BACK,
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SELECT_CATEGORY)))
    reply_markup = InlineKeyboardMarkup(buttons)
    reply_markup, callback = botlistchat.append_delete_button(
        update, chat_data, reply_markup)
    msg = bot.formatter.send_or_edit(
        chat_id,
        _new_bots_text(),
        to_edit=util.mid_from_update(update),
        reply_markup=reply_markup,
        reply_to_message_id=util.mid_from_update(update))
    callback(msg)
    return ConversationHandler.END
Beispiel #15
0
def edit_bot_category(bot, update, for_bot, callback_action=None):
    if callback_action is None:
        callback_action = CallbackActions.EDIT_BOT_CAT_SELECTED
    uid = util.uid_from_update(update)
    categories = Category.select().order_by(Category.name.asc()).execute()

    buttons = util.build_menu(
        [
            InlineKeyboardButton(
                "{}{}".format(emoji.emojize(c.emojis, use_aliases=True),
                              c.name),
                callback_data=util.callback_for_action(callback_action, {
                    "cid": c.id,
                    "bid": for_bot.id
                }),
            ) for c in categories
        ],
        2,
    )
    return bot.formatter.send_or_edit(
        uid,
        util.action_hint("Please select a category" +
                         (" for {}".format(for_bot) if for_bot else "")),
        to_edit=util.mid_from_update(update),
        reply_markup=InlineKeyboardMarkup(buttons),
    )
Beispiel #16
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))
Beispiel #17
0
def append_delete_button(update, chat_data, reply_markup):
    uid = update.effective_user.id
    cid = update.effective_chat.id
    command_mid = update.effective_message.message_id
    if not isinstance(reply_markup, InlineKeyboardMarkup):
        return reply_markup, callable
    if cid != settings.BOTLISTCHAT_ID:
        return reply_markup, callable

    def append_callback(message):
        if message is None:
            return
        if isinstance(message, Message):
            mid = message.message_id
        else:
            mid = message
        deletions_pending = chat_data.get('deletions_pending', dict())
        if not deletions_pending.get(mid):
            deletions_pending[mid] = dict(user_id=uid, command_id=command_mid)
            chat_data['deletions_pending'] = deletions_pending

    buttons = reply_markup.inline_keyboard
    buttons.append([
        InlineKeyboardButton(captions.random_done_delete(),
                             callback_data=util.callback_for_action(
                                 CallbackActions.DELETE_CONVERSATION))
    ])
    reply_markup.inline_keyboard = buttons
    return reply_markup, append_callback
def remove_favorite_menu(bot, update):
    uid = util.uid_from_update(update)
    user = User.from_update(update)
    favorites = Favorite.select_all(user)

    fav_remove_buttons = [InlineKeyboardButton(
        '✖️ {}'.format(str(f.bot.username)),
        callback_data=util.callback_for_action(CallbackActions.REMOVE_FAVORITE, {'id': f.id}))
                          for f in favorites]
    buttons = util.build_menu(fav_remove_buttons, 2, header_buttons=[
        InlineKeyboardButton(captions.DONE,
                             callback_data=util.callback_for_action(CallbackActions.SEND_FAVORITES_LIST))
    ])
    reply_markup = InlineKeyboardMarkup(buttons)
    bot.formatter.send_or_edit(uid, util.action_hint("Select favorites to remove"),
                                 to_edit=util.mid_from_update(update),
                                 reply_markup=reply_markup)
Beispiel #19
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)
Beispiel #20
0
def thank_you_markup(count=0):
    assert isinstance(count, int)
    count_caption = "" if count == 0 else mdformat.number_as_emoji(count)
    button = InlineKeyboardButton(
        "{} {}".format(messages.rand_thank_you_slang(), count_caption),
        callback_data=util.callback_for_action(
            const.CallbackActions.COUNT_THANK_YOU, {"count": count + 1}),
    )
    return InlineKeyboardMarkup([[button]])
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
def send_favorites_list(bot, update, to_edit=None):
    uid = util.uid_from_update(update)
    user = User.from_update(update)

    t = threading.Thread(target=_too_many_favorites_handler, args=(bot, update, user))
    t.start()

    favorites = Favorite.select_all(user)

    buttons = [
        [
            InlineKeyboardButton(captions.ADD_FAVORITE,
                                 callback_data=util.callback_for_action(CallbackActions.ADD_FAVORITE)),
            InlineKeyboardButton(captions.REMOVE_FAVORITE,
                                 callback_data=util.callback_for_action(CallbackActions.REMOVE_FAVORITE_MENU))
        ],
        [
            InlineKeyboardButton('Layout: ' + Layouts.get_caption(user.favorites_layout),
                                 callback_data=util.callback_for_action(
                                     CallbackActions.TOGGLE_FAVORITES_LAYOUT,
                                     {'v': Layouts.get_next(user.favorites_layout)})),
        ],
        [
            InlineKeyboardButton(captions.SHARE, switch_inline_query=DeepLinkingActions.FAVORITES),
        ]
    ]
    reply_markup = InlineKeyboardMarkup(buttons)

    if to_edit is None:
        to_edit = util.mid_from_update(update)

    if len(favorites) == 0:
        text = "You have no favorites yet."
    else:
        text = _favorites_categories_md(favorites, user.favorites_layout)

    bot.formatter.send_or_edit(uid, text,
                                 to_edit=to_edit, reply_markup=reply_markup)
Beispiel #23
0
 def toggle_button(property_name, emoji, callback_action):
     is_pending = property_name in pending_suggestions.keys()
     pending_emoji = captions.SUGGESTION_PENDING_EMOJI + ' ' if is_pending else ''
     active = bool(
         pending_suggestions[property_name]) if is_pending else bool(
             getattr(to_edit, property_name))
     active_emoji = '✔️' if active else Emoji.HEAVY_MULTIPLICATION_X
     caption = '{}{} {}'.format(pending_emoji, emoji, active_emoji)
     return InlineKeyboardButton(caption,
                                 callback_data=util.callback_for_action(
                                     callback_action, {
                                         'id': to_edit.id,
                                         'value': not active
                                     }))
Beispiel #24
0
 def toggle_button(property_name, emoji, callback_action):
     is_pending = property_name in pending_suggestions.keys()
     pending_emoji = captions.SUGGESTION_PENDING_EMOJI + " " if is_pending else ""
     active = (bool(pending_suggestions[property_name])
               if is_pending else bool(getattr(to_edit, property_name)))
     active_emoji = "✔️" if active else Emoji.HEAVY_MULTIPLICATION_X
     caption = "{}{} {}".format(pending_emoji, emoji, active_emoji)
     return InlineKeyboardButton(
         caption,
         callback_data=util.callback_for_action(callback_action, {
             "id": to_edit.id,
             "value": not active
         }),
     )
Beispiel #25
0
def accept_bot_submission(bot, update, of_bot: Bot, category):
    uid = util.uid_from_update(update)
    message_id = util.mid_from_update(update)
    user = User.from_update(update)

    try:
        of_bot.category = category
        of_bot.date_added = datetime.date.today()
        of_bot.approved = True
        of_bot.approved_by = user
        of_bot.save()

        buttons = [[
            InlineKeyboardButton(
                "Edit {} details".format(of_bot.username),
                callback_data=util.callback_for_action(
                    CallbackActions.EDIT_BOT, {"id": of_bot.id}),
            )
        ]]
        reply_markup = InlineKeyboardMarkup(buttons)

        bot.formatter.send_or_edit(
            uid,
            "{} has been accepted to the Botlist. ".format(
                of_bot, settings.BOT_ACCEPTED_IDLE_TIME),
            to_edit=message_id,
            reply_markup=reply_markup,
        )

        log_msg = "{} accepted by {}.".format(of_bot.username, uid)

        # notify submittant
        if of_bot.submitted_by != user:
            try:
                bot.sendMessage(
                    of_bot.submitted_by.chat_id,
                    util.success(
                        messages.ACCEPTANCE_PRIVATE_MESSAGE.format(
                            of_bot.username, of_bot.category)),
                )
                log_msg += "\nUser {} was notified.".format(
                    str(of_bot.submitted_by))
            except TelegramError:
                log_msg += "\nUser {} could NOT be contacted/notified in private.".format(
                    str(of_bot.submitted_by))

        log.info(log_msg)
    except:
        bot.formatter.send_failure(uid, "An error has occured. Bot not added.")
Beispiel #26
0
def append_free_delete_button(update, reply_markup) -> Optional[ReplyMarkup]:
    if not util.is_group_message(update) or not isinstance(
            reply_markup, InlineKeyboardMarkup):
        return reply_markup

    buttons = reply_markup.inline_keyboard
    buttons.append([
        InlineKeyboardButton(
            captions.random_done_delete(),
            callback_data=util.callback_for_action(
                CallbackActions.DELETE_CONVERSATION),
        )
    ])

    reply_markup.inline_keyboard = buttons
    return reply_markup
Beispiel #27
0
def bot_article(b):
    txt = '{} ➡️ {}'.format(messages.rand_call_to_action(), b.detail_text)
    txt += '\n\n' + messages.PROMOTION_MESSAGE
    buttons = [[
        InlineKeyboardButton(captions.ADD_TO_FAVORITES,
                             callback_data=util.callback_for_action(
                                 const.CallbackActions.ADD_TO_FAVORITES, {
                                     'id': b.id,
                                     'discreet': True
                                 }))
    ]]
    reply_markup = InlineKeyboardMarkup(buttons)
    return InlineQueryResultArticle(
        id=uuid4(),
        title=b.str_no_md,
        input_message_content=InputTextMessageContent(
            message_text=txt, parse_mode=ParseMode.MARKDOWN),
        description=b.description
        if b.description else b.name if b.name else None,
        reply_markup=reply_markup
        # thumb_url='http://www.colorcombos.com/images/colors/FF0000.png'
    )
Beispiel #28
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),
    )
Beispiel #29
0
def send_bot_details(bot, update, chat_data, item=None):
    is_group = util.is_group_message(update)
    cid = update.effective_chat.id
    user = User.from_update(update)
    first_row = list()

    if item is None:
        if is_group:
            return

        try:
            text = update.message.text
            bot_in_text = re.findall(settings.REGEX_BOT_IN_TEXT, text)[0]
            item = Bot.by_username(bot_in_text)

        except Bot.DoesNotExist:
            update.message.reply_text(
                util.failure(
                    "This bot is not in the @BotList. If you think this is a mistake, see the /examples for /contributing."
                ))
            return

    if item.approved:
        # bot is already in the botlist => show information
        txt = item.detail_text
        if item.description is None and not Keyword.select().where(
                Keyword.entity == item).exists():
            txt += ' is in the @BotList.'
        btn = InlineCallbackButton(captions.BACK_TO_CATEGORY,
                                   CallbackActions.SELECT_BOT_FROM_CATEGORY,
                                   {'id': item.category.id})
        first_row.insert(0, btn)
        first_row.append(
            InlineKeyboardButton(captions.SHARE,
                                 switch_inline_query=item.username))

        # if cid in settings.MODERATORS:
        first_row.append(
            InlineKeyboardButton("📝 Edit",
                                 callback_data=util.callback_for_action(
                                     CallbackActions.EDIT_BOT,
                                     {'id': item.id})))
    else:
        txt = '{} is currently pending to be accepted for the @BotList.'.format(
            item)
        if cid in settings.MODERATORS:
            first_row.append(
                InlineKeyboardButton("🛃 Accept / Reject",
                                     callback_data=util.callback_for_action(
                                         CallbackActions.APPROVE_REJECT_BOTS,
                                         {'id': item.id})))

    if is_group:
        reply_markup = InlineKeyboardMarkup([])
    else:
        buttons = [first_row]
        favorite_found = Favorite.search_by_bot(user, item)
        if favorite_found:
            buttons.append([
                InlineKeyboardButton(captions.REMOVE_FAVORITE_VERBOSE,
                                     callback_data=util.callback_for_action(
                                         CallbackActions.REMOVE_FAVORITE, {
                                             'id': favorite_found.id,
                                             'details': True
                                         }))
            ])
        else:
            buttons.append([
                InlineKeyboardButton(captions.ADD_TO_FAVORITES,
                                     callback_data=util.callback_for_action(
                                         CallbackActions.ADD_TO_FAVORITES, {
                                             'id': item.id,
                                             'details': True
                                         }))
            ])
        reply_markup = InlineKeyboardMarkup(buttons)
    reply_markup, callback = botlistchat.append_delete_button(
        update, chat_data, reply_markup)

    # Should we ever decide to show thumbnails *shrug*
    # if os.path.exists(item.thumbnail_file):
    #     preview = True
    #     photo = '[\xad]({})'.format('{}/thumbnail/{}.jpeg'.format(
    #         settings.API_URL,
    #         item.username[1:]
    #     ))
    #     log.info(photo)
    #     txt = photo + txt
    # else:
    #     preview = False

    msg = bot.formatter.send_or_edit(cid,
                                     txt,
                                     to_edit=util.mid_from_update(update),
                                     reply_markup=reply_markup)
    callback(msg)
    Statistic.of(update, 'view-details', item.username, Statistic.ANALYSIS)
    return CallbackStates.SHOWING_BOT_DETAILS
Beispiel #30
0
def approve_bots(bot, update, page=0, override_list=None):
    chat_id = util.uid_from_update(update)

    if override_list:
        unapproved = override_list
    else:
        unapproved = Bot.select().where(Bot.approved == False).order_by(
            Bot.date_added)

    if page < 0:
        page = 0

    last_page = int((len(unapproved) - 1) / settings.PAGE_SIZE_BOT_APPROVAL)

    if page * settings.PAGE_SIZE_BOT_APPROVAL >= len(unapproved):
        # old item deleted, list now too small
        page = last_page
    start = page * settings.PAGE_SIZE_BOT_APPROVAL
    end = start + settings.PAGE_SIZE_BOT_APPROVAL

    has_prev_page = page > 0
    has_next_page = (page +
                     1) * settings.PAGE_SIZE_BOT_APPROVAL < len(unapproved)
    unapproved = unapproved[start:end]

    if len(unapproved) == 0:
        bot.formatter.send_or_edit(chat_id,
                                   "No more unapproved bots available. "
                                   "Good job! (Is this the first time? 😂)",
                                   to_edit=util.mid_from_update(update))
        return

    buttons = list()
    for x in unapproved:
        first_row = [
            InlineKeyboardButton(x.username,
                                 url="http://t.me/{}".format(x.username[1:]))
        ]
        second_row = [
            InlineKeyboardButton('👍',
                                 callback_data=util.callback_for_action(
                                     CallbackActions.ACCEPT_BOT,
                                     {'id': x.id})),
            InlineKeyboardButton('👎',
                                 callback_data=util.callback_for_action(
                                     CallbackActions.REJECT_BOT, {
                                         'id': x.id,
                                         'page': page,
                                         'ntfc': True
                                     })),
            InlineKeyboardButton('🗑',
                                 callback_data=util.callback_for_action(
                                     CallbackActions.REJECT_BOT, {
                                         'id': x.id,
                                         'page': page,
                                         'ntfc': False
                                     })),
            InlineKeyboardButton('👥🔀',
                                 callback_data=util.callback_for_action(
                                     CallbackActions.RECOMMEND_MODERATOR, {
                                         'id': x.id,
                                         'page': page
                                     }))
        ]
        if len(unapproved) > 1:
            buttons.append(first_row)
        buttons.append(second_row)

    page_arrows = list()
    if has_prev_page:
        page_arrows.append(
            InlineKeyboardButton('⏮',
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SWITCH_APPROVALS_PAGE,
                                     {'page': -1})))
        page_arrows.append(
            InlineKeyboardButton(Emoji.LEFTWARDS_BLACK_ARROW,
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SWITCH_APPROVALS_PAGE,
                                     {'page': page - 1})))

    if has_prev_page or has_next_page:
        page_arrows.append(
            InlineKeyboardButton('·{}·'.format(page + 1),
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SWITCH_APPROVALS_PAGE,
                                     {'page': page})))

    if has_next_page:
        page_arrows.append(
            InlineKeyboardButton(Emoji.BLACK_RIGHTWARDS_ARROW,
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SWITCH_APPROVALS_PAGE,
                                     {'page': page + 1})))
        page_arrows.append(
            InlineKeyboardButton('⏭',
                                 callback_data=util.callback_for_action(
                                     CallbackActions.SWITCH_APPROVALS_PAGE,
                                     {'page': last_page})))
    buttons.append(page_arrows)

    reply_markup = InlineKeyboardMarkup(buttons)
    text = "What to do with {}?".format(
        util.escape_markdown(unapproved[0].username)) if len(
            unapproved
        ) == 1 else "Please select a bot you want to accept for the BotList"
    bot.formatter.send_or_edit(chat_id,
                               util.action_hint(text),
                               reply_markup=reply_markup,
                               to_edit=util.mid_from_update(update))
    return CallbackStates.APPROVING_BOTS