コード例 #1
0
ファイル: bot.py プロジェクト: Rodolinux/BotListBot
 def detail_text(self):
     from botlistbot.models import Keyword
     keywords = Keyword.select().where(Keyword.entity == self)
     txt = '{}'.format(self.__str__())
     txt += '\n_{}_'.format(util.escape_markdown(
         self.name)) if self.name else ''
     txt += '\n\n{}'.format(self.description) if self.description else ''
     txt += util.escape_markdown('\n\nKeywords: {}'.format(', '.join(
         [str(k) for k in keywords])) if keywords else '')
     return txt
コード例 #2
0
 def markdown_short(self):
     displayname = ''
     if self.first_name:
         displayname = util.escape_markdown(
             self.first_name.encode('utf-8').decode('utf-8'))
     if self.username:
         text = '[👤 {}](https://t.me/{})'.format(
             displayname, util.escape_markdown(self.username))
     else:
         text = displayname
     return text.encode('utf-8').decode('utf-8')
コード例 #3
0
 def send_notification(self, message, **kwargs):
     self.send_message(
         settings.BOTLIST_NOTIFICATIONS_ID,
         util.escape_markdown(message),
         parse_mode="markdown",
         timeout=20,
         **kwargs,
     )
     log.info(message)
コード例 #4
0
    def value(self):
        # cast types
        from botlistbot.models import Category
        from botlistbot.models import Country

        if self._value == 'None':
            return None

        if self.action in self.BOOLEAN_ACTIONS:
            return bool(self._value)
        elif self.action == 'category':
            return Category.get(id=self._value)
        elif self.action == 'country':
            if self._value is None:
                return None
            return Country.get(id=self._value)
        else:
            return util.escape_markdown(str(self._value)) if self._value else None
コード例 #5
0
    def _md_plaintext(self):
        uname = util.escape_markdown(self.subject.username)
        value = self.value

        text = ''
        if self.action == 'category':
            from botlistbot.models import Category
            try:
                cat = Category.get(id=self.value)
                text += "move {} ➜ {}".format(uname, cat.name)
            except Category.DoesNotExist:
                raise AttributeError("Category to change to does not exist.")
        elif self.action == 'name':
            text += "set name {} ➜ {}".format(uname, str(value))
        elif self.action == 'username':
            text += "set username {} ➜ {}".format(uname, str(value))
        elif self.action == 'description':
            text += "change description text of {}".format(uname)
        elif self.action == 'extra':
            text += "change extra text {}".format(uname)
        elif self.action == 'country':
            text += "change country {} ➜ ".format(uname)
            if self._value == 'None' or self._value is None:
                text += "None"
            else:
                from botlistbot.models import Country
                try:
                    con = Country.get(id=self._value)
                    text += str(con)
                except Country.DoesNotExist:
                    raise AttributeError("Country to change to does not exist.")
        elif self.action == 'inlinequeries':
            text += "toggle inlinequeries {} ➜ {}".format(uname, str(value))
        elif self.action == 'official':
            text += "toggle official {} ➜ {}".format(uname, str(value))
        elif self.action == 'offline':
            text += "set {} {}".format('💤' if bool(value) else 'online', uname)
        elif self.action == 'spam':
            text += "mark {} as spammy".format(uname)
        elif self.action == 'add_keyword':
            text += "add keyword #{} to {}".format(str(value), uname)
        elif self.action == 'remove_keyword':
            text += "remove keyword #{} from {}".format(str(value), uname)
        return text
コード例 #6
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, Bot.disabled == 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(
                emojis.RECOMMEND_MODERATOR,
                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 messages.SELECT_BOT_TO_ACCEPT
    )
    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
コード例 #7
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, silent=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
コード例 #8
0
ファイル: bot.py プロジェクト: Rodolinux/BotListBot
 def __str__(self):
     return util.escape_markdown(
         self.str_no_md).encode('utf-8').decode('utf-8')
コード例 #9
0
ファイル: search.py プロジェクト: Rodolinux/BotListBot
def search_query(bot, update: Update, chat_data, query, send_errors=True):
    cid: int = update.effective_chat.id
    user: User = User.from_update(update)
    is_admin: bool = cid in settings.MODERATORS
    replied_to_message_id: Optional[int] = util.original_reply_id(update)
    is_suggestion_by_other: bool = (update.effective_chat
                                    and update.effective_chat.id
                                    == settings.BOTLISTCHAT_ID)

    results = search.search_bots(query)

    reply_markup = (ReplyKeyboardMarkup(basic.main_menu_buttons(is_admin),
                                        resize_keyboard=True)
                    if util.is_private_message(update) else None)
    if results:
        if len(results) == 1:
            update.effective_message.delete()
            if is_suggestion_by_other:
                header = f"{user.markdown_short} found the following bot for you:"
            else:
                header = "I found the following bot for you:"
            return send_bot_details(bot,
                                    update,
                                    chat_data,
                                    results[0],
                                    header_msg=header)
        too_many_results = len(results) > settings.MAX_SEARCH_RESULTS

        bots_list = ""
        if cid in settings.MODERATORS:  # private chat with moderator
            # append edit buttons
            bots_list += "\n".join([
                "{} — /edit{} 🛃".format(b, b.id)
                for b in list(results)[:100]
            ])
        else:
            bots_list += "\n".join(
                [str(b) for b in list(results)[:settings.MAX_SEARCH_RESULTS]])
        bots_list += "\n…" if too_many_results else ""
        bots_list = messages.SEARCH_RESULTS.format(
            bots=bots_list,
            num_results=len(results),
            plural="s" if len(results) > 1 else "",
            query=query,
        )

        if util.is_group_message(
                update) and not update.message.reply_to_message:
            try:
                bot.formatter.send_message(
                    update.effective_user.id,
                    bots_list,
                    reply_markup=reply_markup,
                    disable_web_page_preview=True,
                )
                reply_markup, callback = botlistchat.append_restricted_delete_button(
                    update, chat_data, InlineKeyboardMarkup([[]]))
                msg = bot.formatter.send_message(
                    update.effective_chat.id,
                    f"Hey {user.plaintext}, let's not annoy the others. I sent you the search results "
                    f"[in private chat](https://t.me/{settings.SELF_BOT_NAME}).",
                    disable_web_page_preview=True,
                    reply_markup=reply_markup,
                )
                callback(msg)
                update.effective_message.delete()
            except TelegramError:
                hint_msg, hint_reply_markup, _ = get_hint_data("#private")
                bot.formatter.send_message(
                    update.effective_chat.id,
                    hint_msg,
                    reply_markup=hint_reply_markup,
                    reply_to_message_id=update.effective_message.id,
                    disable_web_page_preview=True,
                )
            return ConversationHandler.END

        if is_suggestion_by_other and replied_to_message_id:
            bots_list = f"{user.markdown_short} suggests to search and {bots_list}"

        bot.formatter.send_message(
            update.effective_chat.id,
            bots_list,
            parse_mode=ParseMode.MARKDOWN,
            reply_markup=reply_markup,
            disable_web_page_preview=True,
            reply_to_message_id=replied_to_message_id,
        )
        update.effective_message.delete()
    else:
        if send_errors:
            callback = None
            if util.is_group_message(update):
                reply_markup, callback = botlistchat.append_restricted_delete_button(
                    update, chat_data, InlineKeyboardMarkup([[]]))
            msg = update.message.reply_text(
                util.failure("Sorry, I couldn't find anything related "
                             "to *{}* in the @BotList. /search".format(
                                 util.escape_markdown(query))),
                parse_mode=ParseMode.MARKDOWN,
                reply_markup=reply_markup,
            )
            if callback:
                callback(msg)

    return ConversationHandler.END
コード例 #10
0
ファイル: statistic.py プロジェクト: Rodolinux/BotListBot
 def __format_entity(self):
     if self.action == 'command':
         return '/' + self.entity
     if self.action == 'menu':
         return util.escape_markdown(self.entity.title())
     return util.escape_markdown(self.entity)