Merge pull request #127 from python-telegram-bot/chatclass

API updates Oct and Nov
This commit is contained in:
Jannes Höke 2015-12-16 16:32:19 +01:00
commit 37271e4a02
16 changed files with 107 additions and 67 deletions

View file

@ -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** **2015-12-08**
*Released 3.0.0* *Released 3.0.0*

View file

@ -58,9 +58,9 @@ author = u'Leandro Toledo'
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '3.0' version = '3.1'
# The full version, including alpha/beta/rc tags. # 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 # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

View file

@ -1,7 +1,7 @@
telegram.groupchat module telegram.chat module
========================= =========================
.. automodule:: telegram.groupchat .. automodule:: telegram.chat
:members: :members:
:undoc-members: :undoc-members:
:show-inheritance: :show-inheritance:

View file

@ -0,0 +1,7 @@
telegram.dispatcher module
=========================
.. automodule:: telegram.dispatcher
:members:
:undoc-members:
:show-inheritance:

View file

@ -9,13 +9,15 @@ Submodules
telegram.audio telegram.audio
telegram.base telegram.base
telegram.bot telegram.bot
telegram.updater
telegram.dispatcher
telegram.chataction telegram.chataction
telegram.contact telegram.contact
telegram.document telegram.document
telegram.emoji telegram.emoji
telegram.error telegram.error
telegram.forcereply telegram.forcereply
telegram.groupchat telegram.chat
telegram.inputfile telegram.inputfile
telegram.location telegram.location
telegram.message telegram.message

View file

@ -0,0 +1,7 @@
telegram.updater module
=========================
.. automodule:: telegram.updater
:members:
:undoc-members:
:show-inheritance:

View file

@ -26,7 +26,7 @@ def requirements():
setup( setup(
name='python-telegram-bot', name='python-telegram-bot',
version='3.0.0', version='3.1.0',
author='Leandro Toledo', author='Leandro Toledo',
author_email='leandrotoledodesouza@gmail.com', author_email='leandrotoledodesouza@gmail.com',
license='LGPLv3', license='LGPLv3',

View file

@ -19,11 +19,11 @@
"""A library that provides a Python interface to the Telegram Bot API""" """A library that provides a Python interface to the Telegram Bot API"""
__author__ = 'leandrotoledodesouza@gmail.com' __author__ = 'leandrotoledodesouza@gmail.com'
__version__ = '3.0.0' __version__ = '3.1.0'
from .base import TelegramObject from .base import TelegramObject
from .user import User from .user import User
from .groupchat import GroupChat from .chat import Chat
from .photosize import PhotoSize from .photosize import PhotoSize
from .audio import Audio from .audio import Audio
from .voice import Voice from .voice import Voice
@ -54,5 +54,5 @@ __all__ = ['Bot', 'Updater', 'Dispatcher', 'Emoji', 'TelegramError',
'InputFile', 'ReplyMarkup', 'ForceReply', 'ReplyKeyboardHide', 'InputFile', 'ReplyMarkup', 'ForceReply', 'ReplyKeyboardHide',
'ReplyKeyboardMarkup', 'UserProfilePhotos', 'ChatAction', 'ReplyKeyboardMarkup', 'UserProfilePhotos', 'ChatAction',
'Location', 'Contact', 'Video', 'Sticker', 'Document', 'File', 'Location', 'Contact', 'Video', 'Sticker', 'Document', 'File',
'Audio', 'PhotoSize', 'GroupChat', 'Update', 'ParseMode', 'Message', 'Audio', 'PhotoSize', 'Chat', 'Update', 'ParseMode', 'Message',
'User', 'TelegramObject', 'NullHandler', 'Voice'] 'User', 'TelegramObject', 'NullHandler', 'Voice']

View file

@ -191,8 +191,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - telegram.User or Unique identifier for the message recipient - telegram.Chat id.
telegram.GroupChat id.
parse_mode: parse_mode:
Send Markdown, if you want Telegram apps to show bold, italic and Send Markdown, if you want Telegram apps to show bold, italic and
inline URLs in your bot's message. For the moment, only Telegram inline URLs in your bot's message. For the moment, only Telegram
@ -234,10 +233,10 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
from_chat_id: from_chat_id:
Unique identifier for the chat where the original message was sent Unique identifier for the chat where the original message was sent
- User or GroupChat id. - Chat id.
message_id: message_id:
Unique message identifier. Unique message identifier.
@ -268,7 +267,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
photo: photo:
Photo to send. You can either pass a file_id as String to resend a 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 photo that is already on the Telegram servers, or upload a new
@ -319,7 +318,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
audio: audio:
Audio file to send. You can either pass a file_id as String to 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 resend an audio that is already on the Telegram servers, or upload
@ -366,7 +365,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
document: document:
File to send. You can either pass a file_id as String to resend a 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 file that is already on the Telegram servers, or upload a new file
@ -405,7 +404,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
sticker: sticker:
Sticker to send. You can either pass a file_id as String to resend 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 a sticker that is already on the Telegram servers, or upload a new
@ -441,7 +440,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
video: video:
Video to send. You can either pass a file_id as String to resend a 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 video that is already on the Telegram servers, or upload a new
@ -490,7 +489,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
voice: voice:
Audio file to send. You can either pass a file_id as String to 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 resend an audio that is already on the Telegram servers, or upload
@ -529,7 +528,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
latitude: latitude:
Latitude of location. Latitude of location.
longitude: longitude:
@ -565,7 +564,7 @@ class Bot(TelegramObject):
Args: Args:
chat_id: chat_id:
Unique identifier for the message recipient - User or GroupChat id. Unique identifier for the message recipient - Chat id.
action: action:
Type of action to broadcast. Choose one, depending on what the user Type of action to broadcast. Choose one, depending on what the user
is about to receive: is about to receive:

View file

@ -17,22 +17,25 @@
# You should have received a copy of the GNU Lesser Public License # You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # 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 from telegram import TelegramObject
class GroupChat(TelegramObject): class Chat(TelegramObject):
"""This object represents a Telegram GroupChat. """This object represents a Telegram Chat.
Attributes: Attributes:
id (int): id (int):
title (str): type (str): Can be 'private', 'group', 'supergroup' or 'channel'
type (str): 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: Args:
id (int): id (int):
title (str): type (str):
**kwargs: Arbitrary keyword arguments. **kwargs: Arbitrary keyword arguments.
Keyword Args: Keyword Args:
@ -41,24 +44,27 @@ class GroupChat(TelegramObject):
def __init__(self, def __init__(self,
id, id,
title, type,
**kwargs): **kwargs):
# Required # Required
self.id = int(id) self.id = int(id)
self.title = title self.type = type
# Optionals # 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 @staticmethod
def de_json(data): def de_json(data):
""" """
Args: Args:
data (str): data (dict):
Returns: Returns:
telegram.GroupChat: telegram.Chat:
""" """
if not data: if not data:
return None return None
return GroupChat(**data) return Chat(**data)

View file

@ -61,22 +61,29 @@ def run_async(func):
class Dispatcher: class Dispatcher:
""" """
This class dispatches all kinds of updates to its registered handlers. 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:
bot: The telegram.Bot instance that received the message The telegram.Bot instance that received the message
update: The update that should be handled by the handler update:
The update that should be handled by the handler
Error handlers take an additional parameter: Error handlers take an additional parameter
error: The TelegramError instance that was raised during processing the
error:
The TelegramError instance that was raised during processing the
update update
All handlers, except error handlers, can also request more information by All handlers, except error handlers, can also request more information by
appending one or more of the following arguments in their argument list for appending one or more of the following arguments in their argument list for
convenience: convenience
update_queue: The Queue instance which contains all new updates and is
update_queue:
The Queue instance which contains all new updates and is
processed by the Dispatcher. Be careful with this - you might processed by the Dispatcher. Be careful with this - you might
create an infinite loop. 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, a list that contains the content of the message split on spaces,
except the first word (usually the command). except the first word (usually the command).
Example: '/add item1 item2 item3' -> ['item1', 'item2', 'item3'] Example: '/add item1 item2 item3' -> ['item1', 'item2', 'item3']

View file

@ -22,7 +22,7 @@
from datetime import datetime from datetime import datetime
from time import mktime 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) Sticker, TelegramObject, User, Video, Voice)
@ -60,7 +60,7 @@ class Message(TelegramObject):
message_id (int): message_id (int):
from_user (:class:`telegram.User`): from_user (:class:`telegram.User`):
date (:class:`datetime.datetime`): date (:class:`datetime.datetime`):
chat (:class:`telegram.User` or :class:`telegram.GroupChat`): chat (:class:`telegram.User` or :class:`telegram.Chat`):
**kwargs: Arbitrary keyword arguments. **kwargs: Arbitrary keyword arguments.
Keyword Args: Keyword Args:
@ -116,6 +116,12 @@ class Message(TelegramObject):
self.new_chat_photo = kwargs.get('new_chat_photo') self.new_chat_photo = kwargs.get('new_chat_photo')
self.delete_chat_photo = bool(kwargs.get('delete_chat_photo', False)) self.delete_chat_photo = bool(kwargs.get('delete_chat_photo', False))
self.group_chat_created = bool(kwargs.get('group_chat_created', 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 @property
def chat_id(self): def chat_id(self):
@ -126,7 +132,7 @@ class Message(TelegramObject):
def de_json(data): def de_json(data):
""" """
Args: Args:
data (str): data (dict):
Returns: Returns:
telegram.Message: telegram.Message:
@ -136,10 +142,7 @@ class Message(TelegramObject):
data['from_user'] = User.de_json(data.get('from')) data['from_user'] = User.de_json(data.get('from'))
data['date'] = datetime.fromtimestamp(data['date']) data['date'] = datetime.fromtimestamp(data['date'])
if 'first_name' in data.get('chat', ''): data['chat'] = Chat.de_json(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['forward_from'] = \ data['forward_from'] = \
User.de_json(data.get('forward_from')) User.de_json(data.get('forward_from'))
data['forward_date'] = \ data['forward_date'] = \

View file

@ -249,7 +249,8 @@ class Updater:
Args: Args:
stop_signals: Iterable containing signals from the signal module stop_signals: Iterable containing signals from the signal module
that should be subscribed to. Updater.stop() will be called on 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: for sig in stop_signals:
signal(sig, self.signal_handler) signal(sig, self.signal_handler)

View file

@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see [http://www.gnu.org/licenses/]. # 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 os
import unittest import unittest
@ -27,8 +27,8 @@ import telegram
from tests.base import BaseTest from tests.base import BaseTest
class GroupChatTest(BaseTest, unittest.TestCase): class ChatTest(BaseTest, unittest.TestCase):
"""This object represents Tests for Telegram GroupChat.""" """This object represents Tests for Telegram Chat."""
def setUp(self): def setUp(self):
self.id = -28767330 self.id = -28767330
@ -42,36 +42,36 @@ class GroupChatTest(BaseTest, unittest.TestCase):
} }
def test_group_chat_de_json_empty_json(self): def test_group_chat_de_json_empty_json(self):
"""Test GroupChat.de_json() method""" """Test Chat.de_json() method"""
print('Testing GroupChat.de_json() - Empty JSON') print('Testing Chat.de_json() - Empty JSON')
group_chat = telegram.GroupChat.de_json({}) group_chat = telegram.Chat.de_json({})
self.assertEqual(group_chat, None) self.assertEqual(group_chat, None)
def test_group_chat_de_json(self): def test_group_chat_de_json(self):
"""Test GroupChat.de_json() method""" """Test Chat.de_json() method"""
print('Testing GroupChat.de_json()') 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.id, self.id)
self.assertEqual(group_chat.title, self.title) self.assertEqual(group_chat.title, self.title)
self.assertEqual(group_chat.type, self.type) self.assertEqual(group_chat.type, self.type)
def test_group_chat_to_json(self): def test_group_chat_to_json(self):
"""Test GroupChat.to_json() method""" """Test Chat.to_json() method"""
print('Testing GroupChat.to_json()') 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())) self.assertTrue(self.is_json(group_chat.to_json()))
def test_group_chat_to_dict(self): def test_group_chat_to_dict(self):
"""Test GroupChat.to_dict() method""" """Test Chat.to_dict() method"""
print('Testing GroupChat.to_dict()') 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.assertTrue(self.is_dict(group_chat.to_dict()))
self.assertEqual(group_chat['id'], self.id) self.assertEqual(group_chat['id'], self.id)

View file

@ -38,6 +38,7 @@ class UpdateTest(BaseTest, unittest.TestCase):
'last_name': "S.", 'last_name': "S.",
'username': "leandrotoledo"}, 'username': "leandrotoledo"},
'chat': {'id': 12173560, 'chat': {'id': 12173560,
'type': 'private',
'first_name': "Leandro", 'first_name': "Leandro",
'last_name': "S.", 'last_name': "S.",
'username': "leandrotoledo"}, 'username': "leandrotoledo"},

View file

@ -38,7 +38,7 @@ except ImportError:
sys.path.append('.') 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 telegram.dispatcher import run_async
from tests.base import BaseTest from tests.base import BaseTest
from threading import Lock, Thread from threading import Lock, Thread
@ -359,7 +359,7 @@ class UpdaterTest(BaseTest, unittest.TestCase):
# Now, we send an update to the server via urlopen # Now, we send an update to the server via urlopen
message = Message(1, User(1, "Tester"), datetime.now(), message = Message(1, User(1, "Tester"), datetime.now(),
GroupChat(1, "Test Group")) Chat(1, "group", title="Test Group"))
message.text = "Webhook Test" message.text = "Webhook Test"
update = Update(1) update = Update(1)
@ -416,7 +416,7 @@ class UpdaterTest(BaseTest, unittest.TestCase):
# Now, we send an update to the server via urlopen # Now, we send an update to the server via urlopen
message = Message(1, User(1, "Tester 2"), datetime.now(), 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" message.text = "Webhook Test 2"
update = Update(1) update = Update(1)