Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
Changes
=======

**DATE TBD**
*WIP 6.2.0*
- Improved filters for user_id/username/chat.
- Internal restructure of files.
- Improved unitests.
- Fully support Bot API 3.1.

**2017-06-18**

*Released 6.1.0*
Expand Down
3 changes: 2 additions & 1 deletion telegram/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from .base import TelegramObject
from .user import User
from .files.chatphoto import ChatPhoto
from .chat import Chat
from .chatmember import ChatMember
from .files.photosize import PhotoSize
Expand Down Expand Up @@ -119,5 +120,5 @@
'MAX_FILESIZE_DOWNLOAD', 'MAX_FILESIZE_UPLOAD', 'MAX_MESSAGES_PER_SECOND_PER_CHAT',
'MAX_MESSAGES_PER_SECOND', 'MAX_MESSAGES_PER_MINUTE_PER_GROUP', 'WebhookInfo', 'Animation',
'Game', 'GameHighScore', 'VideoNote', 'LabeledPrice', 'SuccessfulPayment', 'ShippingOption',
'ShippingAddress', 'PreCheckoutQuery', 'OrderInfo', 'Invoice', 'ShippingQuery'
'ShippingAddress', 'PreCheckoutQuery', 'OrderInfo', 'Invoice', 'ShippingQuery', 'ChatPhoto'
]
395 changes: 390 additions & 5 deletions telegram/bot.py

Large diffs are not rendered by default.

21 changes: 14 additions & 7 deletions telegram/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Chat."""

from telegram import TelegramObject
from telegram import TelegramObject, ChatPhoto


class Chat(TelegramObject):
Expand All @@ -33,14 +33,13 @@ class Chat(TelegramObject):
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
all_members_are_administrators (bool): True if group has 'All Members Are Administrators'
photo (Optional[`telegram.ChatPhoto`]): Chat photo. Returned only in getChat.
description (str): Description, for supergroups and channel chats. Returned
only in getChat.
invite_link (str): Chat invite link, for supergroups and channel chats. Returned
only in getChat.

Args:
id (int):
type (str):
title (Optional[str]):
username(Optional[str]):
first_name(Optional[str]):
last_name(Optional[str]):
bot (Optional[telegram.Bot]): The Bot to use for instance methods
**kwargs (dict): Arbitrary keyword arguments.

Expand All @@ -59,6 +58,9 @@ def __init__(self,
last_name=None,
all_members_are_administrators=None,
bot=None,
photo=None,
description=None,
invite_link=None,
**kwargs):
# Required
self.id = int(id)
Expand All @@ -69,6 +71,9 @@ def __init__(self,
self.first_name = first_name
self.last_name = last_name
self.all_members_are_administrators = all_members_are_administrators
self.photo = photo
self.description = description
self.invite_link = invite_link

self.bot = bot
self._id_attrs = (self.id,)
Expand All @@ -86,6 +91,8 @@ def de_json(data, bot):
if not data:
return None

data['photo'] = ChatPhoto.de_json(data.get('photo'), bot)

return Chat(bot=bot, **data)

def send_action(self, *args, **kwargs):
Expand Down
68 changes: 65 additions & 3 deletions telegram/chatmember.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"""This module contains an object that represents a Telegram ChatMember."""

from telegram import User, TelegramObject
from telegram.utils.helpers import to_timestamp, from_timestamp


class ChatMember(TelegramObject):
Expand All @@ -28,10 +29,39 @@ class ChatMember(TelegramObject):
user (:class:`telegram.User`): Information about the user.
status (str): The member's status in the chat. Can be 'creator', 'administrator', 'member',
'left' or 'kicked'.
until_date (Optional[:class:`datetime.datetime`]): Restricted and kicked only. Date when
restrictions will be lifted for this user.
can_be_edited (Optional[boolean]): Administrators only. True, if the bot is allowed to
edit administrator privileges of that user
can_change_info (Optional[boolean]): Administrators only. True, if the administrator can
change the chat title, photo and other settings
can_post_messages (Optional[boolean]): Administrators only. True, if the administrator can
post in the channel, channels only
can_edit_messages (Optional[boolean]): Administrators only. True, if the administrator can
edit messages of other users, channels only
can_delete_messages (Optional[boolean]): Administrators only. True, if the administrator
can delete messages of other user
can_invite_users (Optional[boolean]): Administrators only. True, if the administrator can
invite new users to the chat
can_restrict_members (Optional[boolean]): Administrators only. True, if the administrator
can restrict, ban or unban chat members
can_pin_messages (Optional[boolean]): Administrators only. True, if the administrator can
pin messages, supergroups only
can_promote_members (Optional[boolean]): Administrators only. True, if the administrator
can add new administrators with a subset of his own privileges or demote administrators
that he has promoted, directly or indirectly (promoted by administrators that were
appointed by the user)
can_send_messages (Optional[boolean]): Restricted only. True, if the user can send text
messages, contacts, locations and venues
can_send_media_messages (Optional[boolean]): Restricted only. True, if the user can send
audios, documents, photos, videos, video notes and voice notes,
implies can_send_messages
can_send_other_messages (Optional[boolean]): Restricted only. True, if the user can send
animations, games, stickers and use inline bots, implies can_send_media_messages
can_add_web_page_previews (Optional[boolean]): Restricted only. True, if user may add
web page previews to his messages, implies can_send_media_messages

Args:
user (:class:`telegram.User`):
status (str):
**kwargs (dict): Arbitrary keyword arguments.

"""
Expand All @@ -41,10 +71,30 @@ class ChatMember(TelegramObject):
LEFT = 'left'
KICKED = 'kicked'

def __init__(self, user, status, **kwargs):
def __init__(self, user, status, until_date=None, can_be_edited=None,
can_change_info=None, can_post_messages=None, can_edit_messages=None,
can_delete_messages=None, can_invite_users=None,
can_restrict_members=None, can_pin_messages=None,
can_promote_members=None, can_send_messages=None,
can_send_media_messages=None, can_send_other_messages=None,
can_add_web_page_previews=None, **kwargs):
# Required
self.user = user
self.status = status
self.until_date = until_date
self.can_be_edited = can_be_edited
self.can_change_info = can_change_info
self.can_post_messages = can_post_messages
self.can_edit_messages = can_edit_messages
self.can_delete_messages = can_delete_messages
self.can_invite_users = can_invite_users
self.can_restrict_members = can_restrict_members
self.can_pin_messages = can_pin_messages
self.can_promote_members = can_promote_members
self.can_send_messages = can_send_messages
self.can_send_media_messages = can_send_media_messages
self.can_send_other_messages = can_send_other_messages
self.can_add_web_page_previews = can_add_web_page_previews

self._id_attrs = (self.user, self.status)

Expand All @@ -64,5 +114,17 @@ def de_json(data, bot):
data = super(ChatMember, ChatMember).de_json(data, bot)

data['user'] = User.de_json(data.get('user'), bot)
data['until_date'] = from_timestamp(data.get('until_date', None))

return ChatMember(**data)

def to_dict(self):
"""
Returns:
dict:
"""
data = super(ChatMember, self).to_dict()

data['until_date'] = to_timestamp(self.until_date)

return data
8 changes: 3 additions & 5 deletions telegram/ext/commandhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
""" This module contains the CommandHandler class """
import warnings

from future.utils import string_types

from .handler import Handler
from telegram import Update

Expand Down Expand Up @@ -80,12 +82,8 @@ def __init__(self,
pass_job_queue=pass_job_queue,
pass_user_data=pass_user_data,
pass_chat_data=pass_chat_data)
try:
_str = basestring # Python 2
except NameError:
_str = str # Python 3

if isinstance(command, _str):
if isinstance(command, string_types):
self.command = [command.lower()]
else:
self.command = [x.lower() for x in command]
Expand Down
12 changes: 4 additions & 8 deletions telegram/ext/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
""" This module contains the Filters for use with the MessageHandler class """
from telegram import Chat

try:
str_type = base_string
except NameError:
str_type = str
from future.utils import string_types


class BaseFilter(object):
Expand Down Expand Up @@ -383,7 +379,7 @@ def __init__(self, user_id=None, username=None):
self.user_ids = user_id
if username is None:
self.usernames = username
elif isinstance(username, str_type):
elif isinstance(username, string_types):
self.usernames = [username.replace('@', '')]
else:
self.usernames = [user.replace('@', '') for user in username]
Expand Down Expand Up @@ -420,7 +416,7 @@ def __init__(self, chat_id=None, username=None):
self.chat_ids = chat_id
if username is None:
self.usernames = username
elif isinstance(username, str_type):
elif isinstance(username, string_types):
self.usernames = [username.replace('@', '')]
else:
self.usernames = [chat.replace('@', '') for chat in username]
Expand Down Expand Up @@ -460,7 +456,7 @@ class language(BaseFilter):
"""

def __init__(self, lang):
if isinstance(lang, str_type):
if isinstance(lang, string_types):
self.lang = [lang]
else:
self.lang = lang
Expand Down
55 changes: 55 additions & 0 deletions telegram/files/chatphoto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python
#
# A library that provides a Python interface to the Telegram Bot API
# Copyright (C) 2015-2017
# Leandro Toledo de Souza <devs@python-telegram-bot.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser Public License for more details.
#
# 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 an object that represents a Telegram ChatPhoto."""

from telegram import TelegramObject


class ChatPhoto(TelegramObject):
""" This object represents a Telegram ChatPhoto

Attributes:
small_file_id (str): Unique file identifier of small (160x160) chat photo. This file_id
can be used only for photo download.
big_file_id (str): Unique file identifier of big (640x640) chat photo. This file_id
can be used only for photo download.

Args:
bot (Optional[telegram.Bot]): The Bot to use for instance methods
**kwargs (dict): Arbitrary keyword arguments.

"""
def __init__(self, small_file_id, big_file_id, bot=None, **kwargs):
self.small_file_id = small_file_id
self.big_file_id = big_file_id

@staticmethod
def de_json(data, bot):
"""
Args:
data (dict):
bot (telegram.Bot):

Returns:
telegram.ChatPhoto:
"""
if not data:
return None

return ChatPhoto(bot=bot, **data)
49 changes: 7 additions & 42 deletions telegram/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@
# along with this program. If not, see [http://www.gnu.org/licenses/].
"""This module contains an object that represents a Telegram Message."""
import sys
from datetime import datetime
from time import mktime

from telegram import (Audio, Contact, Document, Chat, Location, PhotoSize, Sticker, TelegramObject,
User, Video, Voice, Venue, MessageEntity, Game, Invoice, SuccessfulPayment,
VideoNote)
from telegram.utils.deprecate import warn_deprecate_obj
from telegram.utils.helpers import escape_html, escape_markdown
from telegram.utils.helpers import escape_html, escape_markdown, to_timestamp, from_timestamp


class Message(TelegramObject):
Expand Down Expand Up @@ -215,14 +213,14 @@ def de_json(data, bot):
data = super(Message, Message).de_json(data, bot)

data['from_user'] = User.de_json(data.get('from'), bot)
data['date'] = Message._fromtimestamp(data['date'])
data['date'] = from_timestamp(data['date'])
data['chat'] = Chat.de_json(data.get('chat'), bot)
data['entities'] = MessageEntity.de_list(data.get('entities'), bot)
data['forward_from'] = User.de_json(data.get('forward_from'), bot)
data['forward_from_chat'] = Chat.de_json(data.get('forward_from_chat'), bot)
data['forward_date'] = Message._fromtimestamp(data.get('forward_date'))
data['forward_date'] = from_timestamp(data.get('forward_date'))
data['reply_to_message'] = Message.de_json(data.get('reply_to_message'), bot)
data['edit_date'] = Message._fromtimestamp(data.get('edit_date'))
data['edit_date'] = from_timestamp(data.get('edit_date'))
data['audio'] = Audio.de_json(data.get('audio'), bot)
data['document'] = Document.de_json(data.get('document'), bot)
data['game'] = Game.de_json(data.get('game'), bot)
Expand Down Expand Up @@ -259,12 +257,12 @@ def to_dict(self):

# Required
data['from'] = data.pop('from_user', None)
data['date'] = self._totimestamp(self.date)
data['date'] = to_timestamp(self.date)
# Optionals
if self.forward_date:
data['forward_date'] = self._totimestamp(self.forward_date)
data['forward_date'] = to_timestamp(self.forward_date)
if self.edit_date:
data['edit_date'] = self._totimestamp(self.edit_date)
data['edit_date'] = to_timestamp(self.edit_date)
if self.photo:
data['photo'] = [p.to_dict() for p in self.photo]
if self.entities:
Expand All @@ -277,39 +275,6 @@ def to_dict(self):

return data

@staticmethod
def _fromtimestamp(unixtime):
"""
Args:
unixtime (int):

Returns:
datetime.datetime:
"""
if not unixtime:
return None

return datetime.fromtimestamp(unixtime)

@staticmethod
def _totimestamp(dt_obj):
"""
Args:
dt_obj (:class:`datetime.datetime`):

Returns:
int:
"""
if not dt_obj:
return None

try:
# Python 3.3+
return int(dt_obj.timestamp())
except AttributeError:
# Python 3 (< 3.3) and Python 2
return int(mktime(dt_obj.timetuple()))

def _quote(self, kwargs):
"""Modify kwargs for replying with or without quoting"""

Expand Down
Loading