From 6e158042e1d069f8058e63cad3c69dad3ccb6fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Wed, 16 Dec 2015 15:31:02 +0100 Subject: [PATCH 1/4] API updates Oct and Nov --- telegram/__init__.py | 4 +-- telegram/bot.py | 23 +++++++++-------- telegram/{groupchat.py => chat.py} | 30 ++++++++++++++--------- telegram/message.py | 17 +++++++------ tests/{test_groupchat.py => test_chat.py} | 30 +++++++++++------------ tests/test_update.py | 1 + tests/test_updater.py | 6 ++--- 7 files changed, 60 insertions(+), 51 deletions(-) rename telegram/{groupchat.py => chat.py} (61%) rename tests/{test_groupchat.py => test_chat.py} (72%) diff --git a/telegram/__init__.py b/telegram/__init__.py index 021301570..f5a4e5533 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -23,7 +23,7 @@ __version__ = '3.0.0' from .base import TelegramObject from .user import User -from .groupchat import GroupChat +from .chat import Chat from .photosize import PhotoSize from .audio import Audio from .voice import Voice @@ -54,5 +54,5 @@ __all__ = ['Bot', 'Updater', 'Dispatcher', 'Emoji', 'TelegramError', 'InputFile', 'ReplyMarkup', 'ForceReply', 'ReplyKeyboardHide', 'ReplyKeyboardMarkup', 'UserProfilePhotos', 'ChatAction', 'Location', 'Contact', 'Video', 'Sticker', 'Document', 'File', - 'Audio', 'PhotoSize', 'GroupChat', 'Update', 'ParseMode', 'Message', + 'Audio', 'PhotoSize', 'Chat', 'Update', 'ParseMode', 'Message', 'User', 'TelegramObject', 'NullHandler', 'Voice'] diff --git a/telegram/bot.py b/telegram/bot.py index 2d6ebbe58..0330676d9 100644 --- a/telegram/bot.py +++ b/telegram/bot.py @@ -191,8 +191,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - telegram.User or - telegram.GroupChat id. + Unique identifier for the message recipient - telegram.Chat id. parse_mode: Send Markdown, if you want Telegram apps to show bold, italic and inline URLs in your bot's message. For the moment, only Telegram @@ -234,10 +233,10 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. from_chat_id: Unique identifier for the chat where the original message was sent - - User or GroupChat id. + - Chat id. message_id: Unique message identifier. @@ -268,7 +267,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. photo: Photo to send. You can either pass a file_id as String to resend a photo that is already on the Telegram servers, or upload a new @@ -319,7 +318,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. audio: Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload @@ -366,7 +365,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. document: File to send. You can either pass a file_id as String to resend a file that is already on the Telegram servers, or upload a new file @@ -405,7 +404,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. sticker: Sticker to send. You can either pass a file_id as String to resend a sticker that is already on the Telegram servers, or upload a new @@ -441,7 +440,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. video: Video to send. You can either pass a file_id as String to resend a video that is already on the Telegram servers, or upload a new @@ -490,7 +489,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. voice: Audio file to send. You can either pass a file_id as String to resend an audio that is already on the Telegram servers, or upload @@ -529,7 +528,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. latitude: Latitude of location. longitude: @@ -565,7 +564,7 @@ class Bot(TelegramObject): Args: chat_id: - Unique identifier for the message recipient - User or GroupChat id. + Unique identifier for the message recipient - Chat id. action: Type of action to broadcast. Choose one, depending on what the user is about to receive: diff --git a/telegram/groupchat.py b/telegram/chat.py similarity index 61% rename from telegram/groupchat.py rename to telegram/chat.py index f4d59723c..259d80d48 100644 --- a/telegram/groupchat.py +++ b/telegram/chat.py @@ -17,22 +17,25 @@ # You should have received a copy of the GNU Lesser Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. -"""This module contains a object that represents a Telegram GroupChat""" +"""This module contains a object that represents a Telegram Chat""" from telegram import TelegramObject -class GroupChat(TelegramObject): - """This object represents a Telegram GroupChat. +class Chat(TelegramObject): + """This object represents a Telegram Chat. Attributes: id (int): - title (str): - type (str): + type (str): Can be 'private', 'group', 'supergroup' or 'channel' + title (str): Title, for channels and group chats + username (str): Username, for private chats and channels if available + first_name (str): First name of the other party in a private chat + last_name (str): Last name of the other party in a private chat Args: id (int): - title (str): + type (str): **kwargs: Arbitrary keyword arguments. Keyword Args: @@ -41,24 +44,27 @@ class GroupChat(TelegramObject): def __init__(self, id, - title, + type, **kwargs): # Required self.id = int(id) - self.title = title + self.type = type # Optionals - self.type = kwargs.get('type', '') + self.title = kwargs.get('title', '') + self.username = kwargs.get('username', '') + self.first_name = kwargs.get('first_name', '') + self.last_name = kwargs.get('last_name', '') @staticmethod def de_json(data): """ Args: - data (str): + data (dict): Returns: - telegram.GroupChat: + telegram.Chat: """ if not data: return None - return GroupChat(**data) + return Chat(**data) diff --git a/telegram/message.py b/telegram/message.py index d427ac69e..f02042426 100644 --- a/telegram/message.py +++ b/telegram/message.py @@ -22,7 +22,7 @@ from datetime import datetime from time import mktime -from telegram import (Audio, Contact, Document, GroupChat, Location, PhotoSize, +from telegram import (Audio, Contact, Document, Chat, Location, PhotoSize, Sticker, TelegramObject, User, Video, Voice) @@ -60,7 +60,7 @@ class Message(TelegramObject): message_id (int): from_user (:class:`telegram.User`): date (:class:`datetime.datetime`): - chat (:class:`telegram.User` or :class:`telegram.GroupChat`): + chat (:class:`telegram.User` or :class:`telegram.Chat`): **kwargs: Arbitrary keyword arguments. Keyword Args: @@ -116,6 +116,12 @@ class Message(TelegramObject): self.new_chat_photo = kwargs.get('new_chat_photo') self.delete_chat_photo = bool(kwargs.get('delete_chat_photo', False)) self.group_chat_created = bool(kwargs.get('group_chat_created', False)) + self.supergroup_chat_created = bool(kwargs.get( + 'supergroup_chat_created', False)) + self.migrate_to_chat_id = int(kwargs.get('migrate_to_chat_id', 0)) + self.migrate_from_chat_id = int(kwargs.get('migrate_from_chat_id', 0)) + self.channel_chat_created = bool(kwargs.get('channel_chat_created', + False)) @property def chat_id(self): @@ -126,7 +132,7 @@ class Message(TelegramObject): def de_json(data): """ Args: - data (str): + data (dict): Returns: telegram.Message: @@ -136,10 +142,7 @@ class Message(TelegramObject): data['from_user'] = User.de_json(data.get('from')) data['date'] = datetime.fromtimestamp(data['date']) - if 'first_name' in data.get('chat', ''): - data['chat'] = User.de_json(data.get('chat')) - elif 'title' in data.get('chat', ''): - data['chat'] = GroupChat.de_json(data.get('chat')) + data['chat'] = Chat.de_json(data.get('chat')) data['forward_from'] = \ User.de_json(data.get('forward_from')) data['forward_date'] = \ diff --git a/tests/test_groupchat.py b/tests/test_chat.py similarity index 72% rename from tests/test_groupchat.py rename to tests/test_chat.py index 2bde9700a..2e64389e9 100644 --- a/tests/test_groupchat.py +++ b/tests/test_chat.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see [http://www.gnu.org/licenses/]. -"""This module contains a object that represents Tests for Telegram GroupChat""" +"""This module contains a object that represents Tests for Telegram Chat""" import os import unittest @@ -27,8 +27,8 @@ import telegram from tests.base import BaseTest -class GroupChatTest(BaseTest, unittest.TestCase): - """This object represents Tests for Telegram GroupChat.""" +class ChatTest(BaseTest, unittest.TestCase): + """This object represents Tests for Telegram Chat.""" def setUp(self): self.id = -28767330 @@ -42,36 +42,36 @@ class GroupChatTest(BaseTest, unittest.TestCase): } def test_group_chat_de_json_empty_json(self): - """Test GroupChat.de_json() method""" - print('Testing GroupChat.de_json() - Empty JSON') + """Test Chat.de_json() method""" + print('Testing Chat.de_json() - Empty JSON') - group_chat = telegram.GroupChat.de_json({}) + group_chat = telegram.Chat.de_json({}) self.assertEqual(group_chat, None) def test_group_chat_de_json(self): - """Test GroupChat.de_json() method""" - print('Testing GroupChat.de_json()') + """Test Chat.de_json() method""" + print('Testing Chat.de_json()') - group_chat = telegram.GroupChat.de_json(self.json_dict) + group_chat = telegram.Chat.de_json(self.json_dict) self.assertEqual(group_chat.id, self.id) self.assertEqual(group_chat.title, self.title) self.assertEqual(group_chat.type, self.type) def test_group_chat_to_json(self): - """Test GroupChat.to_json() method""" - print('Testing GroupChat.to_json()') + """Test Chat.to_json() method""" + print('Testing Chat.to_json()') - group_chat = telegram.GroupChat.de_json(self.json_dict) + group_chat = telegram.Chat.de_json(self.json_dict) self.assertTrue(self.is_json(group_chat.to_json())) def test_group_chat_to_dict(self): - """Test GroupChat.to_dict() method""" - print('Testing GroupChat.to_dict()') + """Test Chat.to_dict() method""" + print('Testing Chat.to_dict()') - group_chat = telegram.GroupChat.de_json(self.json_dict) + group_chat = telegram.Chat.de_json(self.json_dict) self.assertTrue(self.is_dict(group_chat.to_dict())) self.assertEqual(group_chat['id'], self.id) diff --git a/tests/test_update.py b/tests/test_update.py index da50e7ad3..ec45692eb 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -38,6 +38,7 @@ class UpdateTest(BaseTest, unittest.TestCase): 'last_name': "S.", 'username': "leandrotoledo"}, 'chat': {'id': 12173560, + 'type': 'private', 'first_name': "Leandro", 'last_name': "S.", 'username': "leandrotoledo"}, diff --git a/tests/test_updater.py b/tests/test_updater.py index 98610506f..02dce2237 100644 --- a/tests/test_updater.py +++ b/tests/test_updater.py @@ -38,7 +38,7 @@ except ImportError: sys.path.append('.') -from telegram import Update, Message, TelegramError, User, GroupChat, Updater +from telegram import Update, Message, TelegramError, User, Chat, Updater from telegram.dispatcher import run_async from tests.base import BaseTest from threading import Lock, Thread @@ -359,7 +359,7 @@ class UpdaterTest(BaseTest, unittest.TestCase): # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester"), datetime.now(), - GroupChat(1, "Test Group")) + Chat(1, "group", title="Test Group")) message.text = "Webhook Test" update = Update(1) @@ -416,7 +416,7 @@ class UpdaterTest(BaseTest, unittest.TestCase): # Now, we send an update to the server via urlopen message = Message(1, User(1, "Tester 2"), datetime.now(), - GroupChat(1, "Test Group 2")) + Chat(1, 'group', title="Test Group 2")) message.text = "Webhook Test 2" update = Update(1) From e0233a59a05939b4d12d027f9d6e4af3a5c74b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Wed, 16 Dec 2015 16:18:48 +0100 Subject: [PATCH 2/4] fix docstrings for sphinx --- telegram/dispatcher.py | 23 +++++++++++++++-------- telegram/updater.py | 3 ++- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/telegram/dispatcher.py b/telegram/dispatcher.py index 2355d87a8..07d38ea53 100644 --- a/telegram/dispatcher.py +++ b/telegram/dispatcher.py @@ -61,22 +61,29 @@ def run_async(func): class Dispatcher: """ This class dispatches all kinds of updates to its registered handlers. + A handler is a function that usually takes the following parameters - A handler is a function that usually takes the following parameters: - bot: The telegram.Bot instance that received the message - update: The update that should be handled by the handler + bot: + The telegram.Bot instance that received the message + update: + The update that should be handled by the handler - Error handlers take an additional parameter: - error: The TelegramError instance that was raised during processing the + Error handlers take an additional parameter + + error: + The TelegramError instance that was raised during processing the update All handlers, except error handlers, can also request more information by appending one or more of the following arguments in their argument list for - convenience: - update_queue: The Queue instance which contains all new updates and is + convenience + + update_queue: + The Queue instance which contains all new updates and is processed by the Dispatcher. Be careful with this - you might create an infinite loop. - args: If the update is an instance str or telegram.Update, this will be + args: + If the update is an instance str or telegram.Update, this will be a list that contains the content of the message split on spaces, except the first word (usually the command). Example: '/add item1 item2 item3' -> ['item1', 'item2', 'item3'] diff --git a/telegram/updater.py b/telegram/updater.py index 79688edd3..d57414f0f 100644 --- a/telegram/updater.py +++ b/telegram/updater.py @@ -249,7 +249,8 @@ class Updater: Args: stop_signals: Iterable containing signals from the signal module that should be subscribed to. Updater.stop() will be called on - receiving one of those signals. + receiving one of those signals. Defaults to (SIGINT, SIGTERM, + SIGABRT) """ for sig in stop_signals: signal(sig, self.signal_handler) From cb0736fb3df60b861df4da5b4eb19112cc869619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Wed, 16 Dec 2015 16:23:18 +0100 Subject: [PATCH 3/4] update sphinx docs --- docs/source/{telegram.groupchat.rst => telegram.chat.rst} | 4 ++-- docs/source/telegram.dispatcher.rst | 7 +++++++ docs/source/telegram.rst | 4 +++- docs/source/telegram.updater.rst | 7 +++++++ 4 files changed, 19 insertions(+), 3 deletions(-) rename docs/source/{telegram.groupchat.rst => telegram.chat.rst} (57%) create mode 100644 docs/source/telegram.dispatcher.rst create mode 100644 docs/source/telegram.updater.rst diff --git a/docs/source/telegram.groupchat.rst b/docs/source/telegram.chat.rst similarity index 57% rename from docs/source/telegram.groupchat.rst rename to docs/source/telegram.chat.rst index f493f6263..a0d379a58 100644 --- a/docs/source/telegram.groupchat.rst +++ b/docs/source/telegram.chat.rst @@ -1,7 +1,7 @@ -telegram.groupchat module +telegram.chat module ========================= -.. automodule:: telegram.groupchat +.. automodule:: telegram.chat :members: :undoc-members: :show-inheritance: diff --git a/docs/source/telegram.dispatcher.rst b/docs/source/telegram.dispatcher.rst new file mode 100644 index 000000000..5b0b5f5ea --- /dev/null +++ b/docs/source/telegram.dispatcher.rst @@ -0,0 +1,7 @@ +telegram.dispatcher module +========================= + +.. automodule:: telegram.dispatcher + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/telegram.rst b/docs/source/telegram.rst index 6f5a1941e..8f93811ee 100644 --- a/docs/source/telegram.rst +++ b/docs/source/telegram.rst @@ -9,13 +9,15 @@ Submodules telegram.audio telegram.base telegram.bot + telegram.updater + telegram.dispatcher telegram.chataction telegram.contact telegram.document telegram.emoji telegram.error telegram.forcereply - telegram.groupchat + telegram.chat telegram.inputfile telegram.location telegram.message diff --git a/docs/source/telegram.updater.rst b/docs/source/telegram.updater.rst new file mode 100644 index 000000000..2bdcbd393 --- /dev/null +++ b/docs/source/telegram.updater.rst @@ -0,0 +1,7 @@ +telegram.updater module +========================= + +.. automodule:: telegram.updater + :members: + :undoc-members: + :show-inheritance: From 0e78606d377d3e86891704f4f408f02158d9a9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= Date: Wed, 16 Dec 2015 16:25:14 +0100 Subject: [PATCH 4/4] Release v3.1 --- CHANGES.rst | 7 +++++++ docs/source/conf.py | 4 ++-- setup.py | 2 +- telegram/__init__.py | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f0768fbe6..0c5a034d0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,10 @@ +**2015-12-16** + +*Released 3.1.0* + +- The ``chat``-field in ``Message`` is now of type ``Chat``. (API update Oct 8 2015) +- ``Message`` now contains the optional fields ``supergroup_chat_created``, ``migrate_to_chat_id``, ``migrate_from_chat_id`` and ``channel_chat_created``. (API update Nov 2015) + **2015-12-08** *Released 3.0.0* diff --git a/docs/source/conf.py b/docs/source/conf.py index 08d56b930..c750a5f7f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -58,9 +58,9 @@ author = u'Leandro Toledo' # built documents. # # The short X.Y version. -version = '3.0' +version = '3.1' # The full version, including alpha/beta/rc tags. -release = '3.0.0' +release = '3.1.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/setup.py b/setup.py index bac9cdffd..007868239 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ def requirements(): setup( name='python-telegram-bot', - version='3.0.0', + version='3.1.0', author='Leandro Toledo', author_email='leandrotoledodesouza@gmail.com', license='LGPLv3', diff --git a/telegram/__init__.py b/telegram/__init__.py index f5a4e5533..551c65bec 100644 --- a/telegram/__init__.py +++ b/telegram/__init__.py @@ -19,7 +19,7 @@ """A library that provides a Python interface to the Telegram Bot API""" __author__ = 'leandrotoledodesouza@gmail.com' -__version__ = '3.0.0' +__version__ = '3.1.0' from .base import TelegramObject from .user import User