Merge branch 'develop' into asyncio

This commit is contained in:
Dan 2019-01-07 22:51:57 +01:00
commit 21c301d19d
16 changed files with 405 additions and 23 deletions

View File

@ -84,4 +84,5 @@ PHONE_NUMBER_FLOOD This number has tried to login too many times
TAKEOUT_INVALID The takeout id is invalid TAKEOUT_INVALID The takeout id is invalid
TAKEOUT_REQUIRED The method must be invoked inside a takeout session TAKEOUT_REQUIRED The method must be invoked inside a takeout session
MESSAGE_POLL_CLOSED You can't interact with a closed poll MESSAGE_POLL_CLOSED You can't interact with a closed poll
MEDIA_INVALID The media is invalid MEDIA_INVALID The media is invalid
BOT_SCORE_NOT_MODIFIED The bot score was not modified
1 id message
84 TAKEOUT_INVALID The takeout id is invalid
85 TAKEOUT_REQUIRED The method must be invoked inside a takeout session
86 MESSAGE_POLL_CLOSED You can't interact with a closed poll
87 MEDIA_INVALID The media is invalid
88 BOT_SCORE_NOT_MODIFIED The bot score was not modified

View File

@ -138,6 +138,9 @@ Bots
send_inline_bot_result send_inline_bot_result
answer_callback_query answer_callback_query
request_callback_answer request_callback_answer
send_game
set_game_score
get_game_high_scores
.. autoclass:: pyrogram.Client .. autoclass:: pyrogram.Client

View File

@ -57,6 +57,7 @@ Bots
InlineKeyboardButton InlineKeyboardButton
ForceReply ForceReply
CallbackQuery CallbackQuery
Game
Input Media Input Media
----------- -----------
@ -182,6 +183,15 @@ Input Media
.. autoclass:: CallbackQuery .. autoclass:: CallbackQuery
:members: :members:
.. autoclass:: Game
:members:
.. autoclass:: GameHighScore
:members:
.. autoclass:: GameHighScores
:members:
.. Input Media .. Input Media
----------- -----------

View File

@ -40,7 +40,7 @@ from .client.types import (
Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus, Location, Message, MessageEntity, Dialog, Dialogs, Photo, PhotoSize, Sticker, User, UserStatus,
UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply, UserProfilePhotos, Venue, Animation, Video, VideoNote, Voice, CallbackQuery, Messages, ForceReply,
InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove,
Poll, PollOption, ChatPreview, StopPropagation, Game Poll, PollOption, ChatPreview, StopPropagation, Game, CallbackGame, GameHighScore, GameHighScores
) )
from .client import ( from .client import (
Client, ChatAction, ParseMode, Emoji, Client, ChatAction, ParseMode, Emoji,

View File

@ -172,8 +172,8 @@ class Filters:
pinned_message = create("PinnedMessage", lambda _, m: bool(m.pinned_message)) pinned_message = create("PinnedMessage", lambda _, m: bool(m.pinned_message))
"""Filter service messages for pinned messages.""" """Filter service messages for pinned messages."""
game_score = create("GameScore", lambda _, m: bool(m.game_score)) game_high_score = create("GameHighScore", lambda _, m: bool(m.game_high_score))
"""Filter service messages for game scores.""" """Filter service messages for game high scores."""
reply_keyboard = create("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup)) reply_keyboard = create("ReplyKeyboard", lambda _, m: isinstance(m.reply_markup, ReplyKeyboardMarkup))
"""Filter messages containing reply keyboard markups""" """Filter messages containing reply keyboard markups"""

View File

@ -17,15 +17,21 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .answer_callback_query import AnswerCallbackQuery from .answer_callback_query import AnswerCallbackQuery
from .get_game_high_scores import GetGameHighScores
from .get_inline_bot_results import GetInlineBotResults from .get_inline_bot_results import GetInlineBotResults
from .request_callback_answer import RequestCallbackAnswer from .request_callback_answer import RequestCallbackAnswer
from .send_game import SendGame
from .send_inline_bot_result import SendInlineBotResult from .send_inline_bot_result import SendInlineBotResult
from .set_game_score import SetGameScore
class Bots( class Bots(
AnswerCallbackQuery, AnswerCallbackQuery,
GetInlineBotResults, GetInlineBotResults,
RequestCallbackAnswer, RequestCallbackAnswer,
SendInlineBotResult SendInlineBotResult,
SendGame,
SetGameScore,
GetGameHighScores
): ):
pass pass

View File

@ -0,0 +1,66 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram
from pyrogram.api import functions
from pyrogram.client.ext import BaseClient
class GetGameHighScores(BaseClient):
def get_game_high_scores(self,
user_id: Union[int, str],
chat_id: Union[int, str],
message_id: int = None):
"""Use this method to get data for high score tables.
Args:
user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
chat_id (``int`` | ``str``, *optional*):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
Required if inline_message_id is not specified.
message_id (``int``, *optional*):
Identifier of the sent message.
Required if inline_message_id is not specified.
Returns:
On success, a :obj:`GameHighScores <pyrogram.GameHighScores>` object is returned.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
"""
# TODO: inline_message_id
return pyrogram.GameHighScores._parse(
self,
self.send(
functions.messages.GetGameHighScores(
peer=self.resolve_peer(chat_id),
id=message_id,
user_id=self.resolve_peer(user_id)
)
)
)

View File

@ -0,0 +1,87 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram
from pyrogram.api import functions, types
from pyrogram.client.ext import BaseClient
class SendGame(BaseClient):
def send_game(self,
chat_id: Union[int, str],
game_short_name: str,
disable_notification: bool = None,
reply_to_message_id: int = None,
reply_markup: Union["pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup",
"pyrogram.ReplyKeyboardRemove",
"pyrogram.ForceReply"] = None) -> "pyrogram.Message":
"""Use this method to send a game.
Args:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
game_short_name (``str``):
Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather.
disable_notification (``bool``, *optional*):
Sends the message silently.
Users will receive a notification with no sound.
reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message.
reply_markup (:obj:`InlineKeyboardMarkup`, *optional*):
An object for an inline keyboard. If empty, one Play game_title button will be shown automatically.
If not empty, the first button must launch the game.
Returns:
On success, the sent :obj:`Message` is returned.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
"""
r = self.send(
functions.messages.SendMedia(
peer=self.resolve_peer(chat_id),
media=types.InputMediaGame(
id=types.InputGameShortName(
bot_id=types.InputUserSelf(),
short_name=game_short_name
),
),
message="",
silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(),
reply_markup=reply_markup.write() if reply_markup else None
)
)
for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)):
return pyrogram.Message._parse(
self, i.message,
{i.id: i for i in r.users},
{i.id: i for i in r.chats}
)

View File

@ -0,0 +1,90 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram
from pyrogram.api import functions, types
from pyrogram.client.ext import BaseClient
class SetGameScore(BaseClient):
def set_game_score(self,
user_id: Union[int, str],
score: int,
force: bool = None,
disable_edit_message: bool = None,
chat_id: Union[int, str] = None,
message_id: int = None):
# inline_message_id: str = None): TODO Add inline_message_id
"""Use this method to set the score of the specified user in a game.
Args:
user_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
score (``int``):
New score, must be non-negative.
force (``bool``, *optional*):
Pass True, if the high score is allowed to decrease.
This can be useful when fixing mistakes or banning cheaters.
disable_edit_message (``bool``, *optional*):
Pass True, if the game message should not be automatically edited to include the current scoreboard.
chat_id (``int`` | ``str``, *optional*):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
Required if inline_message_id is not specified.
message_id (``int``, *optional*):
Identifier of the sent message.
Required if inline_message_id is not specified.
Returns:
On success, if the message was sent by the bot, returns the edited :obj:`Message <pyrogram.Message>`,
otherwise returns True.
Raises:
:class:`Error <pyrogram.Error>` in case of a Telegram RPC error.
:class:`BotScoreNotModified` if the new score is not greater than the user's current score in the chat and force is False.
"""
r = self.send(
functions.messages.SetGameScore(
peer=self.resolve_peer(chat_id),
score=score,
id=message_id,
user_id=self.resolve_peer(user_id),
force=force or None,
edit_message=not disable_edit_message or None
)
)
for i in r.updates:
if isinstance(i, (types.UpdateEditMessage, types.UpdateEditChannelMessage)):
return pyrogram.Message._parse(
self, i.message,
{i.id: i for i in r.users},
{i.id: i for i in r.chats}
)
return True

View File

@ -61,7 +61,7 @@ class IterChatMembers(BaseClient):
query (``str``, *optional*): query (``str``, *optional*):
Query string to filter members based on their display names and usernames. Query string to filter members based on their display names and usernames.
Defaults to "" (empty string) [2]_. Defaults to "" (empty string).
filter (``str``, *optional*): filter (``str``, *optional*):
Filter used to select the kind of members you want to retrieve. Only applicable for supergroups Filter used to select the kind of members you want to retrieve. Only applicable for supergroups
@ -74,11 +74,6 @@ class IterChatMembers(BaseClient):
*"administrators"* - chat administrators only. *"administrators"* - chat administrators only.
Defaults to *"all"*. Defaults to *"all"*.
.. [1] Server limit: on supergroups, you can get up to 10,000 members for a single query and up to 200 members
on channels.
.. [2] A query string is applicable only for *"all"*, *"kicked"* and *"restricted"* filters only.
Returns: Returns:
A generator yielding :obj:`ChatMember <pyrogram.ChatMember>` objects. A generator yielding :obj:`ChatMember <pyrogram.ChatMember>` objects.

View File

@ -18,11 +18,8 @@
from .bots import ( from .bots import (
CallbackQuery, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup, CallbackQuery, ForceReply, InlineKeyboardButton, InlineKeyboardMarkup,
KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, CallbackGame,
) GameHighScore, GameHighScores
from .bots import (
ForceReply, InlineKeyboardButton, InlineKeyboardMarkup,
KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
) )
from .input_media import ( from .input_media import (
InputMediaAudio, InputPhoneContact, InputMediaVideo, InputMediaPhoto, InputMediaAudio, InputPhoneContact, InputMediaVideo, InputMediaPhoto,
@ -33,8 +30,8 @@ from .messages_and_media import (
Sticker, Venue, Video, VideoNote, Voice, UserProfilePhotos, Sticker, Venue, Video, VideoNote, Voice, UserProfilePhotos,
Message, Messages, MessageEntity, Poll, PollOption, Game Message, Messages, MessageEntity, Poll, PollOption, Game
) )
from .update import StopPropagation
from .user_and_chats import ( from .user_and_chats import (
Chat, ChatMember, ChatMembers, ChatPhoto, Chat, ChatMember, ChatMembers, ChatPhoto,
Dialog, Dialogs, User, UserStatus, ChatPreview Dialog, Dialogs, User, UserStatus, ChatPreview
) )
from .update import StopPropagation

View File

@ -16,11 +16,13 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .callback_game import CallbackGame
from .callback_query import CallbackQuery from .callback_query import CallbackQuery
from .force_reply import ForceReply from .force_reply import ForceReply
from .game_high_score import GameHighScore
from .game_high_scores import GameHighScores
from .inline_keyboard_button import InlineKeyboardButton from .inline_keyboard_button import InlineKeyboardButton
from .inline_keyboard_markup import InlineKeyboardMarkup from .inline_keyboard_markup import InlineKeyboardMarkup
from .keyboard_button import KeyboardButton from .keyboard_button import KeyboardButton
from .reply_keyboard_markup import ReplyKeyboardMarkup from .reply_keyboard_markup import ReplyKeyboardMarkup
from .reply_keyboard_remove import ReplyKeyboardRemove from .reply_keyboard_remove import ReplyKeyboardRemove
from .callback_game import CallbackGame

View File

@ -0,0 +1,69 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram.api import types
from pyrogram.client.types.pyrogram_type import PyrogramType
from pyrogram.client.types.user_and_chats import User
class GameHighScore(PyrogramType):
"""This object represents one row of the high scores table for a game.
Args:
user (:obj:`User`):
User.
score (``int``):
Score.
position (``position``, *optional*):
Position in high score table for the game.
"""
def __init__(self,
*,
client: "pyrogram.client.ext.BaseClient",
user: User,
score: int,
position: int = None):
super().__init__(client)
self.user = user
self.score = score
self.position = position
@staticmethod
def _parse(client, game_high_score: types.HighScore, users: dict) -> "GameHighScore":
users = {i.id: i for i in users}
return GameHighScore(
user=User._parse(client, users[game_high_score.user_id]),
score=game_high_score.score,
position=game_high_score.pos,
client=client
)
@staticmethod
def _parse_action(client, service: types.MessageService, users: dict):
return GameHighScore(
user=User._parse(client, users[service.from_id]),
score=service.action.score,
client=client
)

View File

@ -0,0 +1,56 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram 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 General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import List
import pyrogram
from pyrogram.api import types
from pyrogram.client.types.pyrogram_type import PyrogramType
from .game_high_score import GameHighScore
class GameHighScores(PyrogramType):
"""This object represents the high scores table for a game.
Args:
total_count (``int``):
Total number of scores the target game has.
game_high_scores (List of :obj:`GameHighScore <pyrogram.GameHighScore>`):
Game scores.
"""
def __init__(self,
*,
client: "pyrogram.client.ext.BaseClient",
total_count: int,
game_high_scores: List[GameHighScore]):
super().__init__(client)
self.total_count = total_count
self.game_high_scores = game_high_scores
@staticmethod
def _parse(client, game_high_scores: types.messages.HighScores) -> "GameHighScores":
return GameHighScores(
total_count=len(game_high_scores.scores),
game_high_scores=[
GameHighScore._parse(client, score, game_high_scores.users)
for score in game_high_scores.scores],
client=client
)

View File

@ -20,6 +20,7 @@ from .animation import Animation
from .audio import Audio from .audio import Audio
from .contact import Contact from .contact import Contact
from .document import Document from .document import Document
from .game import Game
from .location import Location from .location import Location
from .message import Message from .message import Message
from .message_entity import MessageEntity from .message_entity import MessageEntity
@ -34,4 +35,3 @@ from .venue import Venue
from .video import Video from .video import Video
from .video_note import VideoNote from .video_note import VideoNote
from .voice import Voice from .voice import Voice
from .game import Game

View File

@ -202,7 +202,7 @@ class Message(PyrogramType, Update):
Note that the Message object in this field will not contain further reply_to_message fields even if it Note that the Message object in this field will not contain further reply_to_message fields even if it
is itself a reply. is itself a reply.
game_score (``int``, *optional*): game_high_score (:obj:`GameHighScore <pyrogram.GameHighScore>`, *optional*):
The game score for a user. The game score for a user.
The reply_to_message field will contain the game Message. The reply_to_message field will contain the game Message.
@ -283,7 +283,7 @@ class Message(PyrogramType, Update):
migrate_to_chat_id: int = None, migrate_to_chat_id: int = None,
migrate_from_chat_id: int = None, migrate_from_chat_id: int = None,
pinned_message: "Message" = None, pinned_message: "Message" = None,
game_score: int = None, game_high_score: int = None,
views: int = None, views: int = None,
via_bot: User = None, via_bot: User = None,
outgoing: bool = None, outgoing: bool = None,
@ -341,7 +341,7 @@ class Message(PyrogramType, Update):
self.migrate_to_chat_id = migrate_to_chat_id self.migrate_to_chat_id = migrate_to_chat_id
self.migrate_from_chat_id = migrate_from_chat_id self.migrate_from_chat_id = migrate_from_chat_id
self.pinned_message = pinned_message self.pinned_message = pinned_message
self.game_score = game_score self.game_high_score = game_high_score
self.views = views self.views = views
self.via_bot = via_bot self.via_bot = via_bot
self.outgoing = outgoing self.outgoing = outgoing
@ -419,7 +419,7 @@ class Message(PyrogramType, Update):
pass pass
if isinstance(action, types.MessageActionGameScore): if isinstance(action, types.MessageActionGameScore):
parsed_message.game_score = action.score parsed_message.game_high_score = pyrogram.GameHighScore._parse_action(client, message, users)
if message.reply_to_msg_id and replies: if message.reply_to_msg_id and replies:
try: try: