diff --git a/telegram/inline/inlinekeyboardmarkup.py b/telegram/inline/inlinekeyboardmarkup.py index 26f77af0b..d212d896c 100644 --- a/telegram/inline/inlinekeyboardmarkup.py +++ b/telegram/inline/inlinekeyboardmarkup.py @@ -48,3 +48,51 @@ class InlineKeyboardMarkup(ReplyMarkup): data['inline_keyboard'].append([x.to_dict() for x in inline_keyboard]) return data + + @classmethod + def from_button(cls, button, **kwargs): + """Shortcut for:: + + InlineKeyboardMarkup([[button]], **kwargs) + + Return an InlineKeyboardMarkup from a single InlineKeyboardButton + + Args: + button (:class:`telegram.InlineKeyboardButton`): The button to use in the markup + **kwargs (:obj:`dict`): Arbitrary keyword arguments. + + """ + return cls([[button]], **kwargs) + + @classmethod + def from_row(cls, button_row, **kwargs): + """Shortcut for:: + + InlineKeyboardMarkup([button_row], **kwargs) + + Return an InlineKeyboardMarkup from a single row of InlineKeyboardButtons + + Args: + button_row (List[:class:`telegram.InlineKeyboardButton`]): The button to use in the + markup + **kwargs (:obj:`dict`): Arbitrary keyword arguments. + + """ + return cls([button_row], **kwargs) + + @classmethod + def from_column(cls, button_column, **kwargs): + """Shortcut for:: + + InlineKeyboardMarkup([[button] for button in button_column], **kwargs) + + Return an InlineKeyboardMarkup from a single column of InlineKeyboardButtons + + Args: + button_column (List[:class:`telegram.InlineKeyboardButton`]): The button to use in the + markup + **kwargs (:obj:`dict`): Arbitrary keyword arguments. + + """ + button_grid = [[button] for button in button_column] + return cls(button_grid, **kwargs) diff --git a/telegram/replykeyboardmarkup.py b/telegram/replykeyboardmarkup.py index d27572a1a..114e93454 100644 --- a/telegram/replykeyboardmarkup.py +++ b/telegram/replykeyboardmarkup.py @@ -85,3 +85,125 @@ class ReplyKeyboardMarkup(ReplyMarkup): r.append(button) # str data['keyboard'].append(r) return data + + @classmethod + def from_button(cls, + button, + resize_keyboard=False, + one_time_keyboard=False, + selective=False, + **kwargs): + """Shortcut for:: + + ReplyKeyboardMarkup([[button]], **kwargs) + + Return an ReplyKeyboardMarkup from a single KeyboardButton + + Args: + button (:class:`telegram.KeyboardButton` | :obj:`str`): The button to use in the markup + resize_keyboard (:obj:`bool`, optional): Requests clients to resize the keyboard vertically + for optimal fit (e.g., make the keyboard smaller if there are just two rows of + buttons). Defaults to false, in which case the custom keyboard is always of the same + height as the app's standard keyboard. Defaults to ``False`` + one_time_keyboard (:obj:`bool`, optional): Requests clients to hide the keyboard as soon as + it's been used. The keyboard will still be available, but clients will automatically + display the usual letter-keyboard in the chat - the user can press a special button in + the input field to see the custom keyboard again. Defaults to ``False``. + selective (:obj:`bool`, optional): Use this parameter if you want to show the keyboard to + specific users only. Targets: + + 1) users that are @mentioned in the text of the Message object + 2) if the bot's message is a reply (has reply_to_message_id), sender of the original + message. + + Defaults to ``False``. + **kwargs (:obj:`dict`): Arbitrary keyword arguments. + """ + return cls([[button]], + resize_keyboard=resize_keyboard, + one_time_keyboard=one_time_keyboard, + selective=selective, + **kwargs) + + @classmethod + def from_row(cls, + button_row, + resize_keyboard=False, + one_time_keyboard=False, + selective=False, + **kwargs): + """Shortcut for:: + + ReplyKeyboardMarkup([button_row], **kwargs) + + Return an ReplyKeyboardMarkup from a single row of KeyboardButtons + + Args: + button_row (List[:class:`telegram.KeyboardButton` | :obj:`str`]): The button to use in the + markup + resize_keyboard (:obj:`bool`, optional): Requests clients to resize the keyboard vertically + for optimal fit (e.g., make the keyboard smaller if there are just two rows of + buttons). Defaults to false, in which case the custom keyboard is always of the same + height as the app's standard keyboard. Defaults to ``False`` + one_time_keyboard (:obj:`bool`, optional): Requests clients to hide the keyboard as soon as + it's been used. The keyboard will still be available, but clients will automatically + display the usual letter-keyboard in the chat - the user can press a special button in + the input field to see the custom keyboard again. Defaults to ``False``. + selective (:obj:`bool`, optional): Use this parameter if you want to show the keyboard to + specific users only. Targets: + + 1) users that are @mentioned in the text of the Message object + 2) if the bot's message is a reply (has reply_to_message_id), sender of the original + message. + + Defaults to ``False``. + **kwargs (:obj:`dict`): Arbitrary keyword arguments. + + """ + return cls([button_row], + resize_keyboard=resize_keyboard, + one_time_keyboard=one_time_keyboard, + selective=selective, + **kwargs) + + @classmethod + def from_column(cls, + button_column, + resize_keyboard=False, + one_time_keyboard=False, + selective=False, + **kwargs): + """Shortcut for:: + + ReplyKeyboardMarkup([[button] for button in button_column], **kwargs) + + Return an ReplyKeyboardMarkup from a single column of KeyboardButtons + + Args: + button_column (List[:class:`telegram.KeyboardButton` | :obj:`str`]): The button to use in the + markup + resize_keyboard (:obj:`bool`, optional): Requests clients to resize the keyboard vertically + for optimal fit (e.g., make the keyboard smaller if there are just two rows of + buttons). Defaults to false, in which case the custom keyboard is always of the same + height as the app's standard keyboard. Defaults to ``False`` + one_time_keyboard (:obj:`bool`, optional): Requests clients to hide the keyboard as soon as + it's been used. The keyboard will still be available, but clients will automatically + display the usual letter-keyboard in the chat - the user can press a special button in + the input field to see the custom keyboard again. Defaults to ``False``. + selective (:obj:`bool`, optional): Use this parameter if you want to show the keyboard to + specific users only. Targets: + + 1) users that are @mentioned in the text of the Message object + 2) if the bot's message is a reply (has reply_to_message_id), sender of the original + message. + + Defaults to ``False``. + **kwargs (:obj:`dict`): Arbitrary keyword arguments. + + """ + button_grid = [[button] for button in button_column] + return cls(button_grid, + resize_keyboard=resize_keyboard, + one_time_keyboard=one_time_keyboard, + selective=selective, + **kwargs) diff --git a/tests/test_inlinekeyboardmarkup.py b/tests/test_inlinekeyboardmarkup.py index 169c6220c..68da77065 100644 --- a/tests/test_inlinekeyboardmarkup.py +++ b/tests/test_inlinekeyboardmarkup.py @@ -44,6 +44,27 @@ class TestInlineKeyboardMarkup(object): assert message.text == 'Testing InlineKeyboardMarkup' + def test_from_button(self): + inline_keyboard_markup = InlineKeyboardMarkup.from_button( + InlineKeyboardButton(text='button1', callback_data='data1')).inline_keyboard + assert len(inline_keyboard_markup) == 1 + assert len(inline_keyboard_markup[0]) == 1 + + def test_from_row(self): + inline_keyboard_markup = InlineKeyboardMarkup.from_row([ + InlineKeyboardButton(text='button1', callback_data='data1'), + InlineKeyboardButton(text='button1', callback_data='data1')]).inline_keyboard + assert len(inline_keyboard_markup) == 1 + assert len(inline_keyboard_markup[0]) == 2 + + 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 test_expected_values(self, inline_keyboard_markup): assert inline_keyboard_markup.inline_keyboard == self.inline_keyboard diff --git a/tests/test_replykeyboardmarkup.py b/tests/test_replykeyboardmarkup.py index cd0cf3684..91f997f7f 100644 --- a/tests/test_replykeyboardmarkup.py +++ b/tests/test_replykeyboardmarkup.py @@ -51,6 +51,40 @@ class TestReplyKeyboardMarkup(object): assert message.text == 'text 2' + def test_from_button(self): + reply_keyboard_markup = ReplyKeyboardMarkup.from_button( + KeyboardButton(text='button1')).keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 1 + + reply_keyboard_markup = ReplyKeyboardMarkup.from_button('button1').keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 1 + + def test_from_row(self): + reply_keyboard_markup = ReplyKeyboardMarkup.from_row([ + KeyboardButton(text='button1'), + KeyboardButton(text='button2')]).keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 2 + + reply_keyboard_markup = ReplyKeyboardMarkup.from_row(['button1', 'button2']).keyboard + assert len(reply_keyboard_markup) == 1 + assert len(reply_keyboard_markup[0]) == 2 + + def test_from_column(self): + reply_keyboard_markup = ReplyKeyboardMarkup.from_column([ + KeyboardButton(text='button1'), + KeyboardButton(text='button2')]).keyboard + assert len(reply_keyboard_markup) == 2 + assert len(reply_keyboard_markup[0]) == 1 + assert len(reply_keyboard_markup[1]) == 1 + + reply_keyboard_markup = ReplyKeyboardMarkup.from_column(['button1', 'button2']).keyboard + assert len(reply_keyboard_markup) == 2 + assert len(reply_keyboard_markup[0]) == 1 + assert len(reply_keyboard_markup[1]) == 1 + def test_expected_values(self, reply_keyboard_markup): assert isinstance(reply_keyboard_markup.keyboard, list) assert isinstance(reply_keyboard_markup.keyboard[0][0], KeyboardButton)