Merge branch 'master' into docs
# Conflicts: # docs/source/pyrogram/index.rst
This commit is contained in:
commit
43292be336
@ -733,7 +733,7 @@ payments.savedInfo#fb8fe43c flags:# has_saved_credentials:flags.1?true saved_inf
|
|||||||
inputPaymentCredentialsSaved#c10eb2cf id:string tmp_password:bytes = InputPaymentCredentials;
|
inputPaymentCredentialsSaved#c10eb2cf id:string tmp_password:bytes = InputPaymentCredentials;
|
||||||
inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;
|
inputPaymentCredentials#3417d728 flags:# save:flags.0?true data:DataJSON = InputPaymentCredentials;
|
||||||
inputPaymentCredentialsApplePay#aa1c39f payment_data:DataJSON = InputPaymentCredentials;
|
inputPaymentCredentialsApplePay#aa1c39f payment_data:DataJSON = InputPaymentCredentials;
|
||||||
inputPaymentCredentialsAndroidPay#795667a6 payment_token:DataJSON = InputPaymentCredentials;
|
inputPaymentCredentialsAndroidPay#ca05d50e payment_token:DataJSON google_transaction_id:string = InputPaymentCredentials;
|
||||||
|
|
||||||
account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
|
account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
|
||||||
|
|
||||||
@ -813,7 +813,7 @@ recentMeUrlStickerSet#bc0a57dc url:string set:StickerSetCovered = RecentMeUrl;
|
|||||||
|
|
||||||
help.recentMeUrls#e0310d7 urls:Vector<RecentMeUrl> chats:Vector<Chat> users:Vector<User> = help.RecentMeUrls;
|
help.recentMeUrls#e0310d7 urls:Vector<RecentMeUrl> chats:Vector<Chat> users:Vector<User> = help.RecentMeUrls;
|
||||||
|
|
||||||
inputSingleMedia#31bc3d25 media:InputMedia flags:# random_id:long message:string entities:flags.0?Vector<MessageEntity> = InputSingleMedia;
|
inputSingleMedia#1cc6e91f flags:# media:InputMedia random_id:long message:string entities:flags.0?Vector<MessageEntity> = InputSingleMedia;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
@ -841,8 +841,8 @@ auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentC
|
|||||||
auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
|
auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
|
||||||
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
||||||
|
|
||||||
account.registerDevice#637ea878 token_type:int token:string = Bool;
|
account.registerDevice#1389cc token_type:int token:string app_sandbox:Bool other_uids:Vector<int> = Bool;
|
||||||
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
|
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
|
||||||
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
||||||
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||||
account.resetNotifySettings#db7e1747 = Bool;
|
account.resetNotifySettings#db7e1747 = Bool;
|
||||||
@ -910,7 +910,6 @@ messages.editChatPhoto#ca4c79d8 chat_id:int photo:InputChatPhoto = Updates;
|
|||||||
messages.addChatUser#f9a0aa09 chat_id:int user_id:InputUser fwd_limit:int = Updates;
|
messages.addChatUser#f9a0aa09 chat_id:int user_id:InputUser fwd_limit:int = Updates;
|
||||||
messages.deleteChatUser#e0611f16 chat_id:int user_id:InputUser = Updates;
|
messages.deleteChatUser#e0611f16 chat_id:int user_id:InputUser = Updates;
|
||||||
messages.createChat#9cb126e users:Vector<InputUser> title:string = Updates;
|
messages.createChat#9cb126e users:Vector<InputUser> title:string = Updates;
|
||||||
messages.forwardMessage#33963bf9 peer:InputPeer id:int random_id:long = Updates;
|
|
||||||
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
|
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
|
||||||
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
|
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
|
||||||
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
|
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
|
||||||
@ -923,6 +922,7 @@ messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long da
|
|||||||
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
||||||
messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool;
|
messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool;
|
||||||
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
||||||
|
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
|
||||||
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
||||||
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||||
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||||
@ -1034,7 +1034,7 @@ channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> =
|
|||||||
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
||||||
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
|
||||||
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleInvites#49609307 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.exportMessageLink#c846d22d channel:InputChannel id:int = ExportedMessageLink;
|
channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink;
|
||||||
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
channels.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||||
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
||||||
|
@ -42,4 +42,5 @@ CDN_METHOD_INVALID The method can't be used on CDN DCs
|
|||||||
VOLUME_LOC_NOT_FOUND The volume location can't be found
|
VOLUME_LOC_NOT_FOUND The volume location can't be found
|
||||||
FILE_ID_INVALID The file id is invalid
|
FILE_ID_INVALID The file id is invalid
|
||||||
LOCATION_INVALID The file location is invalid
|
LOCATION_INVALID The file location is invalid
|
||||||
CHAT_ADMIN_REQUIRED The method requires admin privileges
|
CHAT_ADMIN_REQUIRED The method requires admin privileges
|
||||||
|
PHONE_NUMBER_BANNED The phone number is banned
|
||||||
|
|
6
docs/source/pyrogram/InputMedia.rst
Normal file
6
docs/source/pyrogram/InputMedia.rst
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
InputMedia
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. autoclass:: pyrogram.InputMedia
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
@ -9,8 +9,9 @@ the same parameters as well, thus offering a familiar look to Bot developers.
|
|||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
Client
|
Client
|
||||||
Error
|
|
||||||
ChatAction
|
ChatAction
|
||||||
ParseMode
|
ParseMode
|
||||||
|
InputMedia
|
||||||
|
Error
|
||||||
|
|
||||||
.. _Telegram Bot API: https://core.telegram.org/bots/api#available-methods
|
.. _Telegram Bot API: https://core.telegram.org/bots/api#available-methods
|
||||||
|
@ -23,9 +23,10 @@ __copyright__ = "Copyright (C) 2017-2018 Dan Tès <https://github.com/delivrance
|
|||||||
"e" if sys.getfilesystemencoding() == "ascii" else "\xe8"
|
"e" if sys.getfilesystemencoding() == "ascii" else "\xe8"
|
||||||
)
|
)
|
||||||
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
||||||
__version__ = "0.4.2"
|
__version__ = "0.5.0"
|
||||||
|
|
||||||
from .api.errors import Error
|
from .api.errors import Error
|
||||||
from .client import ChatAction
|
from .client import ChatAction
|
||||||
from .client import Client
|
from .client import Client
|
||||||
from .client import ParseMode
|
from .client import ParseMode
|
||||||
|
from .client.input_media import InputMedia
|
||||||
|
@ -37,7 +37,7 @@ from pyrogram.api.errors import (
|
|||||||
PhoneNumberUnoccupied, PhoneCodeInvalid, PhoneCodeHashEmpty,
|
PhoneNumberUnoccupied, PhoneCodeInvalid, PhoneCodeHashEmpty,
|
||||||
PhoneCodeExpired, PhoneCodeEmpty, SessionPasswordNeeded,
|
PhoneCodeExpired, PhoneCodeEmpty, SessionPasswordNeeded,
|
||||||
PasswordHashInvalid, FloodWait, PeerIdInvalid, FilePartMissing,
|
PasswordHashInvalid, FloodWait, PeerIdInvalid, FilePartMissing,
|
||||||
ChatAdminRequired, FirstnameInvalid
|
ChatAdminRequired, FirstnameInvalid, PhoneNumberBanned
|
||||||
)
|
)
|
||||||
from pyrogram.api.types import (
|
from pyrogram.api.types import (
|
||||||
User, Chat, Channel,
|
User, Chat, Channel,
|
||||||
@ -48,6 +48,7 @@ from pyrogram.api.types import (
|
|||||||
)
|
)
|
||||||
from pyrogram.crypto import CTR
|
from pyrogram.crypto import CTR
|
||||||
from pyrogram.session import Auth, Session
|
from pyrogram.session import Auth, Session
|
||||||
|
from .input_media import InputMedia
|
||||||
from .style import Markdown, HTML
|
from .style import Markdown, HTML
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -274,7 +275,7 @@ class Client:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
except PhoneNumberInvalid as e:
|
except (PhoneNumberInvalid, PhoneNumberBanned) as e:
|
||||||
if phone_number_invalid_raises:
|
if phone_number_invalid_raises:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
@ -494,12 +495,17 @@ class Client:
|
|||||||
log.info("Dialogs count: {}".format(len(peers)))
|
log.info("Dialogs count: {}".format(len(peers)))
|
||||||
|
|
||||||
while len(dialogs.dialogs) == self.DIALOGS_AT_ONCE:
|
while len(dialogs.dialogs) == self.DIALOGS_AT_ONCE:
|
||||||
dialogs = self.send(
|
try:
|
||||||
functions.messages.GetDialogs(
|
dialogs = self.send(
|
||||||
offset_date, 0, types.InputPeerEmpty(),
|
functions.messages.GetDialogs(
|
||||||
self.DIALOGS_AT_ONCE, True
|
offset_date, 0, types.InputPeerEmpty(),
|
||||||
|
self.DIALOGS_AT_ONCE, True
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
except FloodWait as e:
|
||||||
|
log.info("Get dialogs flood wait: {}".format(e.x))
|
||||||
|
time.sleep(e.x)
|
||||||
|
continue
|
||||||
|
|
||||||
offset_date = parse_dialogs(dialogs)
|
offset_date = parse_dialogs(dialogs)
|
||||||
log.info("Dialogs count: {}".format(len(peers)))
|
log.info("Dialogs count: {}".format(len(peers)))
|
||||||
@ -604,7 +610,7 @@ class Client:
|
|||||||
parse_mode: str = "",
|
parse_mode: str = "",
|
||||||
disable_web_page_preview: bool = None,
|
disable_web_page_preview: bool = None,
|
||||||
disable_notification: bool = None,
|
disable_notification: bool = None,
|
||||||
reply_to_msg_id: int = None):
|
reply_to_message_id: int = None):
|
||||||
"""Use this method to send text messages.
|
"""Use this method to send text messages.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -628,7 +634,7 @@ class Client:
|
|||||||
Sends the message silently.
|
Sends the message silently.
|
||||||
Users will receive a notification with no sound.
|
Users will receive a notification with no sound.
|
||||||
|
|
||||||
reply_to_msg_id (:obj:`bool`, optional):
|
reply_to_message_id (:obj:`bool`, optional):
|
||||||
If the message is a reply, ID of the original message.
|
If the message is a reply, ID of the original message.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -644,7 +650,7 @@ class Client:
|
|||||||
peer=self.resolve_peer(chat_id),
|
peer=self.resolve_peer(chat_id),
|
||||||
no_webpage=disable_web_page_preview or None,
|
no_webpage=disable_web_page_preview or None,
|
||||||
silent=disable_notification or None,
|
silent=disable_notification or None,
|
||||||
reply_to_msg_id=reply_to_msg_id,
|
reply_to_msg_id=reply_to_message_id,
|
||||||
random_id=self.rnd_id(),
|
random_id=self.rnd_id(),
|
||||||
**style.parse(text)
|
**style.parse(text)
|
||||||
)
|
)
|
||||||
@ -1941,3 +1947,99 @@ class Client:
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def send_media_group(self,
|
||||||
|
chat_id: int or str,
|
||||||
|
media: list,
|
||||||
|
disable_notification: bool = None,
|
||||||
|
reply_to_message_id: int = None):
|
||||||
|
"""Use this method to send a group of photos or videos as an album.
|
||||||
|
On success, an Update containing the sent Messages is returned.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
chat_id (:obj:`int` | :obj:`str`):
|
||||||
|
Unique identifier for the target chat or username of the target channel/supergroup
|
||||||
|
(in the format @username). For your personal cloud storage (Saved Messages) you can
|
||||||
|
simply use "me" or "self".
|
||||||
|
|
||||||
|
media (:obj:`list`):
|
||||||
|
A list containing either :obj:`pyrogram.InputMedia.Photo` or :obj:`pyrogram.InputMedia.Video` objects
|
||||||
|
describing photos and videos to be sent, must include 2–10 items.
|
||||||
|
|
||||||
|
disable_notification (:obj:`bool`, optional):
|
||||||
|
Sends the message silently.
|
||||||
|
Users will receive a notification with no sound.
|
||||||
|
|
||||||
|
reply_to_message_id (:obj:`int`, optional):
|
||||||
|
If the message is a reply, ID of the original message.
|
||||||
|
"""
|
||||||
|
multi_media = []
|
||||||
|
|
||||||
|
for i in media:
|
||||||
|
if isinstance(i, InputMedia.Photo):
|
||||||
|
style = self.html if i.parse_mode.lower() == "html" else self.markdown
|
||||||
|
media = self.save_file(i.media)
|
||||||
|
|
||||||
|
media = self.send(
|
||||||
|
functions.messages.UploadMedia(
|
||||||
|
peer=self.resolve_peer(chat_id),
|
||||||
|
media=types.InputMediaUploadedPhoto(
|
||||||
|
file=media
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
single_media = types.InputSingleMedia(
|
||||||
|
media=types.InputMediaPhoto(
|
||||||
|
id=types.InputPhoto(
|
||||||
|
id=media.photo.id,
|
||||||
|
access_hash=media.photo.access_hash
|
||||||
|
)
|
||||||
|
),
|
||||||
|
random_id=self.rnd_id(),
|
||||||
|
**style.parse(i.caption)
|
||||||
|
)
|
||||||
|
|
||||||
|
multi_media.append(single_media)
|
||||||
|
elif isinstance(i, InputMedia.Video):
|
||||||
|
style = self.html if i.parse_mode.lower() == "html" else self.markdown
|
||||||
|
media = self.save_file(i.media)
|
||||||
|
|
||||||
|
media = self.send(
|
||||||
|
functions.messages.UploadMedia(
|
||||||
|
peer=self.resolve_peer(chat_id),
|
||||||
|
media=types.InputMediaUploadedDocument(
|
||||||
|
file=media,
|
||||||
|
mime_type=mimetypes.types_map[".mp4"],
|
||||||
|
attributes=[
|
||||||
|
types.DocumentAttributeVideo(
|
||||||
|
duration=i.duration,
|
||||||
|
w=i.width,
|
||||||
|
h=i.height
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
single_media = types.InputSingleMedia(
|
||||||
|
media=types.InputMediaDocument(
|
||||||
|
id=types.InputDocument(
|
||||||
|
id=media.document.id,
|
||||||
|
access_hash=media.document.access_hash
|
||||||
|
)
|
||||||
|
),
|
||||||
|
random_id=self.rnd_id(),
|
||||||
|
**style.parse(i.caption)
|
||||||
|
)
|
||||||
|
|
||||||
|
multi_media.append(single_media)
|
||||||
|
|
||||||
|
return self.send(
|
||||||
|
functions.messages.SendMultiMedia(
|
||||||
|
peer=self.resolve_peer(chat_id),
|
||||||
|
multi_media=multi_media,
|
||||||
|
silent=disable_notification or None,
|
||||||
|
reply_to_msg_id=reply_to_message_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
56
pyrogram/client/input_media.py
Normal file
56
pyrogram/client/input_media.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
class InputMedia:
|
||||||
|
class Photo:
|
||||||
|
"""This object represents a photo to be sent inside an album.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
media (:obj:`str`):
|
||||||
|
File to send.
|
||||||
|
Pass a file path as string to send a photo that exists on your local machine.
|
||||||
|
|
||||||
|
caption (:obj:`str`):
|
||||||
|
Caption of the photo to be sent, 0-200 characters
|
||||||
|
|
||||||
|
parse_mode (:obj:`str`):
|
||||||
|
Use :obj:`pyrogram.ParseMode.MARKDOWN` or :obj:`pyrogram.ParseMode.HTML` if you want Telegram apps
|
||||||
|
to show bold, italic, fixed-width text or inline URLs in your caption.
|
||||||
|
Defaults to Markdown.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
media: str,
|
||||||
|
caption: str = "",
|
||||||
|
parse_mode: str = ""):
|
||||||
|
self.media = media
|
||||||
|
self.caption = caption
|
||||||
|
self.parse_mode = parse_mode
|
||||||
|
|
||||||
|
class Video:
|
||||||
|
"""This object represents a video to be sent inside an album.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
media (:obj:`str`):
|
||||||
|
File to send.
|
||||||
|
Pass a file path as string to send a video that exists on your local machine.
|
||||||
|
|
||||||
|
caption (:obj:`str`):
|
||||||
|
Caption of the video to be sent, 0-200 characters
|
||||||
|
|
||||||
|
parse_mode (:obj:`str`):
|
||||||
|
Use :obj:`pyrogram.ParseMode.MARKDOWN` or :obj:`pyrogram.ParseMode.HTML` if you want Telegram apps
|
||||||
|
to show bold, italic, fixed-width text or inline URLs in your caption.
|
||||||
|
Defaults to Markdown.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
media: str,
|
||||||
|
caption: str = "",
|
||||||
|
parse_mode: str = "",
|
||||||
|
width: int = 0,
|
||||||
|
height: int = 0,
|
||||||
|
duration: int = 0):
|
||||||
|
self.media = media
|
||||||
|
self.caption = caption
|
||||||
|
self.parse_mode = parse_mode
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
self.duration = duration
|
@ -31,7 +31,7 @@ from . import utils
|
|||||||
|
|
||||||
|
|
||||||
class HTML:
|
class HTML:
|
||||||
HTML_RE = re.compile(r"<(\w+)(?: href=\"(.*)\")?>(.*)</\1>")
|
HTML_RE = re.compile(r"<(\w+)(?: href=([\"'])(.*)\2)?>(.*)</\1>")
|
||||||
MENTION_RE = re.compile(r"tg://user\?id=(\d+)")
|
MENTION_RE = re.compile(r"tg://user\?id=(\d+)")
|
||||||
|
|
||||||
def __init__(self, peers_by_id):
|
def __init__(self, peers_by_id):
|
||||||
|
Loading…
Reference in New Issue
Block a user