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;
|
||||
inputPaymentCredentials#3417d728 flags:# save:flags.0?true 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;
|
||||
|
||||
@ -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;
|
||||
|
||||
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---
|
||||
|
||||
@ -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.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
||||
|
||||
account.registerDevice#637ea878 token_type:int token:string = Bool;
|
||||
account.unregisterDevice#65c55b40 token_type:int token:string = Bool;
|
||||
account.registerDevice#1389cc token_type:int token:string app_sandbox:Bool other_uids:Vector<int> = Bool;
|
||||
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
|
||||
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
||||
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||
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.deleteChatUser#e0611f16 chat_id:int user_id:InputUser = 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.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = 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.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool;
|
||||
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.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||
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.deleteChannel#c0111fe3 channel:InputChannel = 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.updatePinnedMessage#a72ded52 flags:# silent:flags.0?true channel:InputChannel id:int = Updates;
|
||||
channels.getAdminedPublicChannels#8d8d82d7 = messages.Chats;
|
||||
|
@ -43,3 +43,4 @@ VOLUME_LOC_NOT_FOUND The volume location can't be found
|
||||
FILE_ID_INVALID The file id is invalid
|
||||
LOCATION_INVALID The file location is invalid
|
||||
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::
|
||||
Client
|
||||
Error
|
||||
ChatAction
|
||||
ParseMode
|
||||
InputMedia
|
||||
Error
|
||||
|
||||
.. _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"
|
||||
)
|
||||
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
||||
__version__ = "0.4.2"
|
||||
__version__ = "0.5.0"
|
||||
|
||||
from .api.errors import Error
|
||||
from .client import ChatAction
|
||||
from .client import Client
|
||||
from .client import ParseMode
|
||||
from .client.input_media import InputMedia
|
||||
|
@ -37,7 +37,7 @@ from pyrogram.api.errors import (
|
||||
PhoneNumberUnoccupied, PhoneCodeInvalid, PhoneCodeHashEmpty,
|
||||
PhoneCodeExpired, PhoneCodeEmpty, SessionPasswordNeeded,
|
||||
PasswordHashInvalid, FloodWait, PeerIdInvalid, FilePartMissing,
|
||||
ChatAdminRequired, FirstnameInvalid
|
||||
ChatAdminRequired, FirstnameInvalid, PhoneNumberBanned
|
||||
)
|
||||
from pyrogram.api.types import (
|
||||
User, Chat, Channel,
|
||||
@ -48,6 +48,7 @@ from pyrogram.api.types import (
|
||||
)
|
||||
from pyrogram.crypto import CTR
|
||||
from pyrogram.session import Auth, Session
|
||||
from .input_media import InputMedia
|
||||
from .style import Markdown, HTML
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -274,7 +275,7 @@ class Client:
|
||||
)
|
||||
)
|
||||
break
|
||||
except PhoneNumberInvalid as e:
|
||||
except (PhoneNumberInvalid, PhoneNumberBanned) as e:
|
||||
if phone_number_invalid_raises:
|
||||
raise
|
||||
else:
|
||||
@ -494,12 +495,17 @@ class Client:
|
||||
log.info("Dialogs count: {}".format(len(peers)))
|
||||
|
||||
while len(dialogs.dialogs) == self.DIALOGS_AT_ONCE:
|
||||
try:
|
||||
dialogs = self.send(
|
||||
functions.messages.GetDialogs(
|
||||
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)
|
||||
log.info("Dialogs count: {}".format(len(peers)))
|
||||
@ -604,7 +610,7 @@ class Client:
|
||||
parse_mode: str = "",
|
||||
disable_web_page_preview: 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.
|
||||
|
||||
Args:
|
||||
@ -628,7 +634,7 @@ class Client:
|
||||
Sends the message silently.
|
||||
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.
|
||||
|
||||
Returns:
|
||||
@ -644,7 +650,7 @@ class Client:
|
||||
peer=self.resolve_peer(chat_id),
|
||||
no_webpage=disable_web_page_preview 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(),
|
||||
**style.parse(text)
|
||||
)
|
||||
@ -1941,3 +1947,99 @@ class Client:
|
||||
)
|
||||
else:
|
||||
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:
|
||||
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+)")
|
||||
|
||||
def __init__(self, peers_by_id):
|
||||
|
Loading…
Reference in New Issue
Block a user