def test_equality(self): a = InlineKeyboardMarkup.from_column( [ InlineKeyboardButton(label, callback_data='data') for label in ['button1', 'button2', 'button3'] ] ) b = InlineKeyboardMarkup.from_column( [ InlineKeyboardButton(label, callback_data='data') for label in ['button1', 'button2', 'button3'] ] ) c = InlineKeyboardMarkup.from_column( [InlineKeyboardButton(label, callback_data='data') for label in ['button1', 'button2']] ) d = InlineKeyboardMarkup.from_column( [ InlineKeyboardButton(label, callback_data=label) for label in ['button1', 'button2', 'button3'] ] ) e = InlineKeyboardMarkup.from_column( [InlineKeyboardButton(label, url=label) for label in ['button1', 'button2', 'button3']] ) f = InlineKeyboardMarkup( [ [ InlineKeyboardButton(label, callback_data='data') for label in ['button1', 'button2'] ], [ InlineKeyboardButton(label, callback_data='data') for label in ['button1', 'button2'] ], [ InlineKeyboardButton(label, callback_data='data') for label in ['button1', 'button2'] ], ] ) g = ReplyKeyboardMarkup.from_column(['button1', 'button2', 'button3']) assert a == b assert hash(a) == hash(b) assert a != c assert hash(a) != hash(c) assert a != d assert hash(a) != hash(d) assert a != e assert hash(a) != hash(e) assert a != f assert hash(a) != hash(f) assert a != g assert hash(a) != hash(g)
def callback(update: Update, context: CallbackContext): gpio_number = int(update.callback_query.data[0]) gpio_state = update.callback_query.data[1:] gpio_state = GPIO_State[gpio_state].value btnText, cbData = getTargetState(gpio_number, gpio_state) if gpio_number == 4: self.gpio4_state = gpio_state self.gpio4_button = InlineKeyboardButton(text=btnText, callback_data=cbData) elif gpio_number == 5: self.gpio5_state = gpio_state self.gpio5_button = InlineKeyboardButton(text=btnText, callback_data=cbData) else: context.bot.sendMessage( update.effective_chat.id, 'Unknown GPIO type in callback - doing nothing') return txt = 'GPIO {} set to {}'.format(gpio_number, GPIO_State(gpio_state).name) self.keyboard = InlineKeyboardMarkup.from_column( [self.gpio4_button, self.gpio5_button]) context.bot.sendMessage(update.effective_chat.id, txt, reply_markup=self.keyboard)
def test_from_column(self): inline_keyboard_markup = InlineKeyboardMarkup.from_column([ InlineKeyboardButton(text='button1', callback_data='data1'), InlineKeyboardButton(text='button1', callback_data='data1')]).inline_keyboard assert len(inline_keyboard_markup) == 2 assert len(inline_keyboard_markup[0]) == 1 assert len(inline_keyboard_markup[1]) == 1
def _get_btns(state: ConversationState) -> InlineKeyboardMarkup: """Get an InlineKeyboardMarkup, i.e. buttons, with a list of valid expense account options considering the current state. Returns: InlineKeyboardMarkup: All option's presented to the user. """ btns = [] # Add back button if necessary if state.current_path: callback_path = f"accounts:{state.id}:back" btns.append( InlineKeyboardButton("⬅️ Back", callback_data=callback_path)) # Build up other buttons for i in range(len(state.accounts)): # Our callback path is: # - account redirects to the handler for account selection # - the id of our state # - the index of our state callback_path = f"accounts:{state.id}:{i}" btns.append( InlineKeyboardButton(state.accounts[i], callback_data=callback_path)) return InlineKeyboardMarkup.from_column(btns)
def search_by_name(update: Update, context: CallbackContext): context.user_data["baseMessage"].edit_reply_markup() chat = update.effective_chat query = update.message.text chat.send_action(TYPING) results = context.user_data["results"] = get_books_by_name(query) query = query.replace(" ", "+") buttons = [InlineKeyboardButton(text=Label.BACK, callback_data="suggest")] text_bits = [] for ix, (name, authors, _) in enumerate(results): authors_str = " ,".join(authors) book_dt = Message.BOOK.format(BOOK_NAME=name, AUTHORS=authors_str) text_bits.append(book_dt) button = InlineKeyboardButton(text=name, callback_data=f"suggest_{ix}") buttons.insert(0, button) if results: books_txt = "\n".join(text_bits) text = Message.SEARCH_RESULTS.format(BOOKS=books_txt, QUERY=query) else: text = Message.NO_RESULTS.format(QUERY=query) keyboard = InlineKeyboardMarkup.from_column(buttons) base_msg = chat.send_message(text=text, reply_markup=keyboard, parse_mode=HTML, disable_web_page_preview=True) context.user_data["baseMessage"] = base_msg context.user_data["redirectUpdate"] = search_by_name
def list_subs(self, update: Update, __: CallbackContext) -> None: """Bot function handling displaying of subscriptions.""" try: result = self.database.get_subs_for_user(update.message.chat_id) channel_names = [ self.database.get_channel_name(twitch_id)[0] for twitch_id in result ] if len(result) > 0: keyboard = [ InlineKeyboardButton( str(channel), callback_data=f'CHANNEL_INFO_QUERY {channel}') for channel in channel_names ] keyboard = InlineKeyboardMarkup.from_column(keyboard) update.message.reply_text(_( "List of your subscriptions:\nClick on channel for information" ), reply_markup=keyboard) else: update.message.reply_text( _("You don't have any subscriptions yet!\n" "To subscribe, use the command\n" "/sub <Channel name>")) except Exception as exception: update.message.reply_text( _("An error occured while fetching the list of subscriptions.\n" "Reason: {}").format(exception))
def poll2markup(poll): buttons = [] opt_by_id = dict(enumerate(poll.options)) opt_users = sorted( poll.get_users_by_option_id().items(), key=lambda item: len(item[1]), reverse=True ) i = 0 for option_id, users in opt_users: # make buttons for options with votes opt = opt_by_id[option_id] buttons.append(InlineKeyboardButton( opt, callback_data=",".join([ "vote", str(option_id) ]) )) i += 1 if i > MAX_INLINE_OPTIONS: break return InlineKeyboardMarkup.from_column(buttons)
def on_settings(update: Update, context: CallbackContext): """ Вызов настроек: - /settings - settings или настройки """ query = update.callback_query # Если функция вызвана из CallbackQueryHandler if query: query.answer() message = update.effective_message reply_markup = InlineKeyboardMarkup.from_column([ InlineKeyboardButton(settings_state.title, callback_data=settings_state.get_callback_data()) for settings_state in SettingState if settings_state.is_visible ]) text = 'Выбор настроек:' # Если функция вызвана из CallbackQueryHandler if query: message.edit_text(text, reply_markup=reply_markup) else: message.reply_text(text, reply_markup=reply_markup)
def test_equality(self): a = ReplyKeyboardMarkup.from_column(["button1", "button2", "button3"]) b = ReplyKeyboardMarkup.from_column([ KeyboardButton(text) for text in ["button1", "button2", "button3"] ]) c = ReplyKeyboardMarkup.from_column(["button1", "button2"]) d = ReplyKeyboardMarkup.from_column( ["button1", "button2", "button3.1"]) e = ReplyKeyboardMarkup([["button1", "button1"], ["button2"], ["button3.1"]]) f = InlineKeyboardMarkup.from_column(["button1", "button2", "button3"]) assert a == b assert hash(a) == hash(b) assert a != c assert hash(a) != hash(c) assert a != d assert hash(a) != hash(d) assert a != e assert hash(a) != hash(e) assert a != f assert hash(a) != hash(f)
def _alarm_status(self, update: Update, _context: CallbackContext): statuses = AlarmStatus.objects.all() if len(statuses) == 0: return update.message.reply_text(texts.NO_ALARM) texts_alarm_status = [ texts.alarm_status(status) for status in statuses ] keyboard = [ InlineKeyboardButton(texts.OFF_ALL, callback_data=BotData.OFF.value), InlineKeyboardButton(texts.ON_ALL, callback_data=BotData.ON.value) ] if len(statuses) > 1: keyboard.append( InlineKeyboardButton(texts.CHOOSE, callback_data=BotData.CHOOSE.value)) markup = InlineKeyboardMarkup.from_column(keyboard) update.message.reply_text('\n'.join(texts_alarm_status), reply_markup=markup, parse_mode=telegram_constants.PARSEMODE_HTML)
def language_options_markup(language: Language) -> InlineKeyboardMarkup: return InlineKeyboardMarkup.from_column([ callback_button( language_option.t.LANGUAGE_NAME, ChangeLanguagePayload(language=language, new_language=language_option)) for language_option in Language ])
def feed_setting(update, context): context.dispatcher.run_async( update.callback_query.edit_message_text, text=f"点击修改推送设置:", reply_markup=InlineKeyboardMarkup.from_column([ InlineKeyboardButton("更新频率 60 分钟", callback_data="feed_freq"), InlineKeyboardButton('返回', callback_data="settings") ]))
def _build_inline_keyboard(items: Dict[str, str]) -> InlineKeyboardMarkup: """ Builds an inline button menu :param items: dictionary of "button text" -> "callback data" items :return: reply markup """ keyboard = list(map(lambda x: InlineKeyboardButton(x[0], callback_data=x[1]), items.items())) return InlineKeyboardMarkup.from_column(keyboard)
def host_setting(update, context): context.dispatcher.run_async( update.callback_query.edit_message_text, text=f"*主播设置*", reply_markup=InlineKeyboardMarkup.from_column([ InlineKeyboardButton("申请主播认证", callback_data="request_host"), InlineKeyboardButton('返回', callback_data="settings") ]))
def to_column(self) -> InlineKeyboardMarkup: """Клавиатура в InlineKeyboardMarkup.""" row = [ InlineKeyboardButton( button.description, callback_data=json.dumps(button.callback) ) for button in self.keyboard.buttons ] return InlineKeyboardMarkup.from_column(row)
def vtb_suggestion_markup() -> InlineKeyboardMarkup: return InlineKeyboardMarkup.from_column([ InlineKeyboardButton("神楽めあ", url="https://space.bilibili.com/349991143/"), InlineKeyboardButton("湊あくあ", url="https://space.bilibili.com/375504219/"), InlineKeyboardButton("夏色まつり", url="https://space.bilibili.com/336731767") ])
def show_proxy(update, context): update.message.pin() buttons = [ InlineKeyboardButton(text=f'{manifest.name}专线 {i+1}', url=proxy) for i, proxy in enumerate(proxies.values()) ] update.message.reply_text( text='点击按钮以乘坐专线通往互联网彼岸', reply_markup=InlineKeyboardMarkup.from_column(buttons))
def unsubscribe(self, update: Update, __: CallbackContext) -> None: """Bot function handling unsubscriptions.""" if update.message is not None: channels_to_unsubscribe = update.message.text.split()[1:] chat_id = update.message.chat_id reply_func = update.message.reply_text else: channels_to_unsubscribe = update.callback_query.data.split()[1:] chat_id = update.callback_query.message.chat_id reply_func = update.callback_query.edit_message_text user_subs = self.database.get_subs_for_user(chat_id) if len(channels_to_unsubscribe) >= 1: for channel in channels_to_unsubscribe: try: twitch_id, display_name = self.twitch_api.get_twitch_user_by_name( channel) if twitch_id != -1 and twitch_id in user_subs: self.database.delete_user_sub(chat_id, twitch_id) channel_subs = self.database.get_users_for_sub( twitch_id) if len(channel_subs) == 0: self.database.delete_channel_name(twitch_id) self.twitch_api.unsubscribe_event(twitch_id) # self.twitch_api.unsubscribe(twitch_id) reply_func( _("Successfully unsubscribed from {}!").format( display_name)) else: reply_func( _("You are not subscribed to {}!").format(channel)) except Exception as exception: reply_func( _("An error occurred while unsubscribing from {}.\n" "Reason: {}").format(channel, exception)) else: if len(user_subs) > 0: channel_names = [ self.database.get_channel_name(twitch_id)[0] for twitch_id in user_subs ] keyboard = [ InlineKeyboardButton( str(channel), callback_data=f'UNSUB_QUERY {channel}') for channel in channel_names ] keyboard = InlineKeyboardMarkup.from_column(keyboard) reply_func( _("Select the channel you want to unsubscribe from:"), reply_markup=keyboard) else: reply_func( _("You don't have any subscriptions yet!\n" "To subscribe, use the command\n" "/sub <Channel name>"))
def get_transaction_keyboard(transaction_id): return InlineKeyboardMarkup.from_column([ InlineKeyboardButton(text, callback_data=data) for text, data in ( ("Delete", "transaction:delete:%s" % transaction_id), ( "Add another bottle", "transaction:increment:%s" % transaction_id, ), ) ])
def display_setting(update, context): context.dispatcher.run_async( update.callback_query.edit_message_text, text=f"点击修改外观设置:", reply_markup=InlineKeyboardMarkup.from_column([ InlineKeyboardButton(f"显示时间线 {TICK_MARK}", callback_data="toggle_timeline"), InlineKeyboardButton(f'倒序显示单集 {TICK_MARK}', callback_data="toggle_episodes_order"), InlineKeyboardButton('返回', callback_data="settings"), ]))
def generate_keyboard(subscriptions=set()): keyboard = [] for lecture_id, lecture in config['mirrors'].items(): line = lecture['name'] if lecture_id in subscriptions: line += ' ✅' keyboard.append( InlineKeyboardButton(text=line, callback_data=lecture_id)) return InlineKeyboardMarkup.from_column(keyboard)
def product_price_view(product: Product, cart: Cart) -> dict: action_buttons = [get_back_button(product.id)] for sku in product.stockkeepingunit_set.all(): if cart.contains(sku): price_button = InlineKeyboardButton( text=f'{sku.pack.size}{sku.pack.unit} - {sku.price} грн - В корзине', callback_data='empty') else: callback = str({ID: sku.id, ACTION: 'add_to_cart'}) price_button = InlineKeyboardButton(text=f'{sku.pack.size}{sku.pack.unit} - {sku.price} грн', callback_data=callback) action_buttons.append(price_button) action_markup = InlineKeyboardMarkup.from_column(action_buttons) return {'caption': product.short_caption(), 'reply_markup': action_markup}
def show_episodes(podcasts, podcast_name, current_page): podcast = podcasts[podcast_name] episodes = podcast.episodes episodes_count = len(episodes) results_per_page = constants.MAX_INLINE_QUERY_RESULTS no_more_episodes = episodes_count <= results_per_page * (current_page - 1) if no_more_episodes: listed_results = [ InlineQueryResultArticle( id="-1", title="没有更多的节目了 :(", description="前往订阅列表", input_message_content=InputTextMessageContent("/manage")) ] else: listed_results = [ InlineQueryResultArticle( id=index, title=episode.title, input_message_content=InputTextMessageContent(( f"[📻️]({podcast.logo_url}) *{podcast_name}*\n" f"{episode.title}\n\n" f"{episode.get('subtitle') or ''}" # and then use Telegraph api to generate summary link! )), reply_markup=InlineKeyboardMarkup.from_column([ InlineKeyboardButton( "收 听 本 集", callback_data= f"download_episode_{podcast_name}_{(current_page-1) * results_per_page + index}" ), InlineKeyboardButton( "返 回 单 集 列 表", switch_inline_query_current_chat= f"episodes {podcast_name} page {current_page}"), InlineKeyboardButton( "查 看 订 阅 列 表", switch_inline_query_current_chat="podcasts page 1") ]), description=episode.get('subtitle') or podcast_name, thumb_url=podcast.logo_url, thumb_width=30, thumb_height=30) for index, episode in enumerate(episodes[results_per_page * (current_page - 1):results_per_page * current_page]) ] return listed_results
def remove(update: Update, context: CallbackContext): base_message = context.user_data["baseMessage"] update.callback_query.answer() buttons = [ InlineKeyboardButton(text=name, callback_data=f"remove_{ix}") for ix, (name, _) in enumerate(context.user_data["books"]) ] back = InlineKeyboardButton(text=Label.BACK, callback_data="start") buttons.append(back) keyboard = InlineKeyboardMarkup.from_column(buttons) base_msg = base_message.edit_text( text=Message.REMOVE_BOOKS, reply_markup=keyboard, parse_mode=HTML ) context.user_data["baseMessage"] = base_msg
def search(update, context): chat_id = update.message.chat_id shop_name = update.message.text keyboard = [] try: #shop_name = str(context.args[0]) if shop_name == "": update.message.reply_text('Sorry, use /search <name of shop> !') return for shop_item in findIp.find_shop(shop_name): keyboard.append(InlineKeyboardButton(shop_item[1], callback_data=shop_item[0])) reply_markup = InlineKeyboardMarkup.from_column(keyboard) update.message.reply_text('Please choose:', reply_markup=reply_markup) return ACTIONFORSHOP except (IndexError, ValueError): update.message.reply_text('Sorry, use /search <name of shop> !')
def _set_alarm_status(self, update: Update, _c: CallbackContext): query = update.callback_query status = query.data if status == BotData.ON.value: AlarmChangeStatus().all_change_status(True, force=True) text = texts.ALL_ON return query.edit_message_text(text) if status == BotData.OFF.value: AlarmChangeStatus().all_change_status(False, force=True) text = texts.ALL_OFF return query.edit_message_text(text) if status == BotData.CHOOSE.value: statuses = AlarmStatus.objects.all() keyboard = [ InlineKeyboardButton(texts.change_alarm_status(status), callback_data=status.pk) for status in statuses ] query.answer() # one button per row, only one column. markup = InlineKeyboardMarkup.from_column(keyboard) return query.edit_message_text(texts.CHOOSE_EXPLAIN, reply_markup=markup) if status.isdigit(): status_pk = int(status) """ Why not use an update query like "NOT running"? Because I need to get the running information to display it to the user. 1) telegram bot sends buttons to deactivate/activate a given alarm. 2) the user click. But during the time lapsed the status could have been updated by other process. Thanks to this, the user knows the real updated value, which is important. """ db_status = AlarmChangeStatus().reverse_status(status_pk, force=True) text = texts.alarm_status_changed(db_status) query.edit_message_text(text) return query.edit_message_text(texts.WRONG)
def on_settings_filter(update: Update, context: CallbackContext): query = update.callback_query query.answer() settings = SettingState.FILTER user = db.User.get_from(update.effective_user) # Если значение было передано pattern = settings.get_pattern_with_params() m = pattern.search(query.data) if m: limit = int(m.group(1)) if not limit: limit = None log.debug(f' filter_quote_by_max_length_text = {limit}') user.set_filter_quote_by_max_length_text(limit) # После изменения фильтра нужно перегенерировать кэш years_of_quotes = user.get_years_of_quotes() update_cache(user, years_of_quotes, limit, log, update, context) else: limit = user.get_filter_quote_by_max_length_text() reply_markup = InlineKeyboardMarkup.from_column([ # Пусть без ограничений будет 0, чтобы не переделывать логику с числами выше InlineKeyboardButton( (RADIOBUTTON if not limit else RADIOBUTTON_EMPTY) + ' Без ограничений', callback_data=fill_string_pattern(pattern, 0)), # Возможны будут другие варианты, но пока наличие значения - наличие флага InlineKeyboardButton( (RADIOBUTTON if limit else RADIOBUTTON_EMPTY) + ' Только маленькие', callback_data=fill_string_pattern(pattern, LENGTH_TEXT_OF_SMALL_QUOTE)), INLINE_KEYBOARD_BUTTON_BACK, ]) # Fix error: "telegram.error.BadRequest: Message is not modified" if is_equal_inline_keyboards(reply_markup, query.message.reply_markup): return text = settings.description query.edit_message_text(text, reply_markup=reply_markup)
def export_before_logout(update, context): run_async = context.dispatcher.run_async user = User.validate_user(update.effective_user) message = update.callback_query.message podcasts = Podcast.objects(subscribers__in=[user]) if not podcasts: run_async(message.reply_text, '还没有订阅播客,请先订阅后导出~') return subscribed_podcasts = Podcast.subscribe_by(user) run_async(message.reply_document, filename=f"castpod-{date.today()}.xml", document=generate_opml(user, subscribed_podcasts), reply_markup=InlineKeyboardMarkup.from_column([ InlineKeyboardButton("继续注销账号", callback_data="confirm_delete_account"), InlineKeyboardButton("返回帮助界面", callback_data="back_to_help") ])) message.delete()
def show_subscription(subscription, current_page): subscription_count = len(subscription) results_per_page = constants.MAX_INLINE_QUERY_RESULTS no_more_subscription = subscription_count <= results_per_page * ( current_page - 1) if no_more_subscription: results = [ InlineQueryResultArticle( id="-1", title="没有更多的订阅了 :(", description="前往搜索播客", input_message_content=InputTextMessageContent("/search")) ] else: print(subscription.values()) results = [ InlineQueryResultArticle( id=index, title=feed.podcast.name, input_message_content=InputTextMessageContent( (f"[📻️]({feed.podcast.logo_url}) *{feed.podcast.name}*\n" f"{feed.podcast.host}\n\n" f"{feed.podcast.email}")), reply_markup=InlineKeyboardMarkup.from_column([ InlineKeyboardButton( "查 看 单 集", switch_inline_query_current_chat= f"episodes {feed.podcast.name} page 1"), InlineKeyboardButton("关 于", url=feed.podcast.website) ]), description=feed.podcast.host, thumb_url=feed.podcast.logo_url, thumb_width=30, thumb_height=30) for index, feed in enumerate( list(subscription.values())[results_per_page * (current_page - 1):results_per_page * current_page]) ] return results
def drink(update: Update, context: CallbackContext): api_key = authorize_user(update, context) res = requests.get( "%s/api/v1/crate/?billed=false" % settings.api_host, headers={"Authorization": "Token %s" % api_key}, ) if not res.ok: update.message.reply_text( "Something weird happened whilst attempting to fetch crates") return keyboard = InlineKeyboardMarkup.from_column([ InlineKeyboardButton(obj.get("name"), callback_data="transaction:new:%s" % obj.get("id")) for obj in res.json() ]) update.message.reply_text("Sure, what can I get you?", reply_markup=keyboard)