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(bot, update, chat_data, callback_action=None): chat_id = update.effective_chat.id reply_markup = InlineKeyboardMarkup( _select_category_buttons(callback_action)) reply_markup, callback = botlistchat.append_restricted_delete_button( update, chat_data, reply_markup) msg = bot.formatter.send_or_edit( chat_id, util.action_hint(messages.SELECT_CATEGORY), to_edit=util.mid_from_update(update), reply_markup=reply_markup, ) callback(msg) return ConversationHandler.END
def show_new_bots(bot, update, chat_data, back_button=False): chat_id = update.effective_chat.id channel = helpers.get_channel() buttons = [] if channel: buttons.append([ InlineKeyboardButton( "Show in BotList", url="http://t.me/{}/{}".format(channel.username, channel.new_bots_mid), ) ]) buttons.append([ 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_restricted_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
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) 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() header = f"{user.markdown_short} 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 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
def send_bot_details(bot, update, chat_data, item=None, header_msg: Optional[str] = None): is_group = util.is_group_message(update) cid = update.effective_chat.id user = User.from_update(update) 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, include_disabled=True) 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 header_buttons = [] buttons = [] if item.disabled: txt = "{} {} and thus removed from the @BotList.".format( item, Bot.DisabledReason.to_str(item.disabled_reason)) elif item.approved: # bot is already in the botlist => show information txt = f"{header_msg}\n\n{item.detail_text}" if header_msg else item.detail_text if (item.description is None and not Keyword.select().where(Keyword.entity == item).exists()): txt += " is in the @BotList, but has no description or keywords yet." btn = InlineCallbackButton( captions.BACK_TO_CATEGORY, CallbackActions.SELECT_BOT_FROM_CATEGORY, {"id": item.category.id}, ) header_buttons.insert(0, btn) header_buttons.append( InlineKeyboardButton(captions.SHARE, switch_inline_query=item.username)) # if cid in settings.MODERATORS: header_buttons.append( InlineKeyboardButton( "📝 Edit", callback_data=util.callback_for_action( CallbackActions.EDIT_BOT, {"id": item.id}), )) # Add favorite button 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 }, ), )) else: txt = "{} is currently pending to be accepted for the @BotList.".format( item) if cid in settings.MODERATORS: header_buttons.append( InlineKeyboardButton( "🛃 Accept / Reject", callback_data=util.callback_for_action( CallbackActions.APPROVE_REJECT_BOTS, {"id": item.id}), )) if buttons or header_buttons: reply_markup = InlineKeyboardMarkup( util.build_menu(buttons, n_cols=3, header_buttons=header_buttons)) else: reply_markup = None reply_markup, callback = botlistchat.append_restricted_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