mirror of
https://github.com/pyrogram/pyrogram
synced 2025-08-29 13:27:47 +00:00
Merge develop -> asyncio
This commit is contained in:
commit
7badcd38b4
4
.gitignore
vendored
4
.gitignore
vendored
@ -11,6 +11,9 @@ pyrogram/api/all.py
|
|||||||
# PyCharm stuff
|
# PyCharm stuff
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
.vscode/
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
@ -78,6 +81,7 @@ instance/
|
|||||||
|
|
||||||
# Sphinx documentation
|
# Sphinx documentation
|
||||||
docs/_build/
|
docs/_build/
|
||||||
|
docs/source/_build
|
||||||
|
|
||||||
# PyBuilder
|
# PyBuilder
|
||||||
target/
|
target/
|
||||||
|
@ -478,7 +478,6 @@ def start():
|
|||||||
|
|
||||||
f.write("\n 0xbc799737: \"pyrogram.api.core.BoolFalse\",")
|
f.write("\n 0xbc799737: \"pyrogram.api.core.BoolFalse\",")
|
||||||
f.write("\n 0x997275b5: \"pyrogram.api.core.BoolTrue\",")
|
f.write("\n 0x997275b5: \"pyrogram.api.core.BoolTrue\",")
|
||||||
f.write("\n 0x56730bcc: \"pyrogram.api.core.Null\",")
|
|
||||||
f.write("\n 0x1cb5c415: \"pyrogram.api.core.Vector\",")
|
f.write("\n 0x1cb5c415: \"pyrogram.api.core.Vector\",")
|
||||||
f.write("\n 0x73f1f8dc: \"pyrogram.api.core.MsgContainer\",")
|
f.write("\n 0x73f1f8dc: \"pyrogram.api.core.MsgContainer\",")
|
||||||
f.write("\n 0xae500895: \"pyrogram.api.core.FutureSalts\",")
|
f.write("\n 0xae500895: \"pyrogram.api.core.FutureSalts\",")
|
||||||
|
@ -192,7 +192,6 @@ dismissed and their IP addresses are now kept as aliases to the nearest one.
|
|||||||
|
|
||||||
Thanks to `@FrayxRulez <https://t.me/tgbetachat/104921>`_ for telling about alias DCs.
|
Thanks to `@FrayxRulez <https://t.me/tgbetachat/104921>`_ for telling about alias DCs.
|
||||||
|
|
||||||
|
|
||||||
I want to migrate my account from DCX to DCY.
|
I want to migrate my account from DCX to DCY.
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
@ -246,9 +245,13 @@ The error in question is ``[400 PEER_ID_INVALID]``, and could mean several thing
|
|||||||
|
|
||||||
- The chat id you tried to use is simply wrong, double check it.
|
- The chat id you tried to use is simply wrong, double check it.
|
||||||
- The chat id refers to a group or channel you are not a member of.
|
- The chat id refers to a group or channel you are not a member of.
|
||||||
- The chat id refers to a user you have't seen yet (from contacts, groups in common, forwarded messages or private
|
|
||||||
chats).
|
|
||||||
- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``.
|
- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``.
|
||||||
|
- The chat id refers to a user your current session haven't met yet.
|
||||||
|
|
||||||
|
About the last point: in order for you to meet a user and thus communicate with them, you should ask yourself how to
|
||||||
|
contact people using official apps. The answer is the same for Pyrogram too and involves normal usages such as searching
|
||||||
|
for usernames, meet them in a common group, have their phone contacts saved, getting a message mentioning them (either a
|
||||||
|
forward or a mention in the message text).
|
||||||
|
|
||||||
UnicodeEncodeError: '<encoding>' codec can't encode …
|
UnicodeEncodeError: '<encoding>' codec can't encode …
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
@ -258,6 +261,14 @@ shows up when you try to print something and has very little to do with Pyrogram
|
|||||||
your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to a
|
your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to a
|
||||||
better terminal altogether.
|
better terminal altogether.
|
||||||
|
|
||||||
|
Uploading with URLs gives error WEBPAGE_CURL_FAILED
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
When uploading media files using an URL, the server automatically tries to download the media and uploads it to the
|
||||||
|
Telegram cloud. This error usually happens in case the provided URL is not publicly accessible by Telegram itself or the
|
||||||
|
media exceeds 20 MB in size. In such cases, your only option is to download the media yourself and upload from your
|
||||||
|
local machine.
|
||||||
|
|
||||||
My verification code expires immediately!
|
My verification code expires immediately!
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
|
@ -45,8 +45,9 @@ Welcome to Pyrogram
|
|||||||
topics/tgcrypto
|
topics/tgcrypto
|
||||||
topics/storage-engines
|
topics/storage-engines
|
||||||
topics/text-formatting
|
topics/text-formatting
|
||||||
topics/serialize
|
topics/serializing
|
||||||
topics/proxy
|
topics/proxy
|
||||||
|
topics/scheduling
|
||||||
topics/bots-interaction
|
topics/bots-interaction
|
||||||
topics/mtproto-vs-botapi
|
topics/mtproto-vs-botapi
|
||||||
topics/debugging
|
topics/debugging
|
||||||
|
87
docs/source/topics/scheduling.rst
Normal file
87
docs/source/topics/scheduling.rst
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
Scheduling Tasks
|
||||||
|
================
|
||||||
|
|
||||||
|
Scheduling tasks means executing one or more functions periodically at pre-defined intervals or after a delay. This is
|
||||||
|
useful, for example, to send recurring messages to specific chats or users.
|
||||||
|
|
||||||
|
Since there's no built-in task scheduler in Pyrogram, this page will only show examples on how to integrate Pyrogram
|
||||||
|
with the main Python schedule libraries such as ``schedule`` and ``apscheduler``. For more detailed information, you can
|
||||||
|
visit and learn from each library documentation.
|
||||||
|
|
||||||
|
Using ``schedule``
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- Install with ``pip3 install schedule``
|
||||||
|
- Documentation: https://schedule.readthedocs.io
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
import schedule
|
||||||
|
|
||||||
|
from pyrogram import Client
|
||||||
|
|
||||||
|
app = Client("my_account")
|
||||||
|
|
||||||
|
|
||||||
|
def job():
|
||||||
|
app.send_message("me", "Hi!")
|
||||||
|
|
||||||
|
|
||||||
|
schedule.every(3).seconds.do(job)
|
||||||
|
|
||||||
|
with app:
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Using ``apscheduler``
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
- Install with ``pip3 install apscheduler``
|
||||||
|
- Documentation: https://apscheduler.readthedocs.io
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from apscheduler.schedulers.background import BackgroundScheduler
|
||||||
|
|
||||||
|
from pyrogram import Client
|
||||||
|
|
||||||
|
app = Client("my_account")
|
||||||
|
|
||||||
|
|
||||||
|
def job():
|
||||||
|
app.send_message("me", "Hi!")
|
||||||
|
|
||||||
|
|
||||||
|
scheduler = BackgroundScheduler()
|
||||||
|
scheduler.add_job(job, "interval", seconds=3)
|
||||||
|
|
||||||
|
scheduler.start()
|
||||||
|
app.run()
|
||||||
|
|
||||||
|
``apscheduler`` does also support async code, here's an example with
|
||||||
|
`Pyrogram Asyncio <https://docs.pyrogram.org/intro/install.html#asynchronous>`_:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||||
|
|
||||||
|
from pyrogram import Client
|
||||||
|
|
||||||
|
app = Client("my_account")
|
||||||
|
|
||||||
|
|
||||||
|
async def job():
|
||||||
|
await app.send_message("me", "Hi!")
|
||||||
|
|
||||||
|
|
||||||
|
scheduler = AsyncIOScheduler()
|
||||||
|
scheduler.add_job(job, "interval", seconds=3)
|
||||||
|
|
||||||
|
scheduler.start()
|
||||||
|
app.run()
|
||||||
|
|
@ -19,8 +19,7 @@
|
|||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
|
||||||
from .all import objects
|
from .all import objects
|
||||||
from .core.tl_object import TLObject
|
|
||||||
|
|
||||||
for k, v in objects.items():
|
for k, v in objects.items():
|
||||||
path, name = v.rsplit(".", 1)
|
path, name = v.rsplit(".", 1)
|
||||||
TLObject.all[k] = getattr(import_module(path), name)
|
objects[k] = getattr(import_module(path), name)
|
||||||
|
@ -22,8 +22,5 @@ from .gzip_packed import GzipPacked
|
|||||||
from .list import List
|
from .list import List
|
||||||
from .message import Message
|
from .message import Message
|
||||||
from .msg_container import MsgContainer
|
from .msg_container import MsgContainer
|
||||||
from .primitives import (
|
from .primitives import *
|
||||||
Bool, BoolTrue, BoolFalse, Bytes, Double,
|
|
||||||
Int, Long, Int128, Int256, Null, String, Vector
|
|
||||||
)
|
|
||||||
from .tl_object import TLObject
|
from .tl_object import TLObject
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
# 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 .bool import Bool, BoolTrue, BoolFalse
|
from .bool import Bool, BoolFalse, BoolTrue
|
||||||
from .bytes import Bytes
|
from .bytes import Bytes
|
||||||
from .double import Double
|
from .double import Double
|
||||||
from .int import Int, Long, Int128, Int256
|
from .int import Int, Long, Int128, Int256
|
||||||
from .null import Null
|
|
||||||
from .string import String
|
from .string import String
|
||||||
from .vector import Vector
|
from .vector import Vector
|
||||||
|
|
||||||
|
__all__ = ["Bool", "BoolFalse", "BoolTrue", "Bytes", "Double", "Int", "Long", "Int128", "Int256", "String", "Vector"]
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
# 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 io import BytesIO
|
|
||||||
|
|
||||||
from ..tl_object import TLObject
|
|
||||||
|
|
||||||
|
|
||||||
class Null(TLObject):
|
|
||||||
ID = 0x56730bcc
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def read(b: BytesIO, *args) -> None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def __new__(cls) -> bytes:
|
|
||||||
return cls.ID.to_bytes(4, "little")
|
|
@ -20,17 +20,17 @@ from collections import OrderedDict
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from json import dumps
|
from json import dumps
|
||||||
|
|
||||||
|
from ..all import objects
|
||||||
|
|
||||||
|
|
||||||
class TLObject:
|
class TLObject:
|
||||||
all = {}
|
|
||||||
|
|
||||||
__slots__ = []
|
__slots__ = []
|
||||||
|
|
||||||
QUALNAME = "Base"
|
QUALNAME = "Base"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def read(b: BytesIO, *args): # TODO: Rename b -> data
|
def read(b: BytesIO, *args): # TODO: Rename b -> data
|
||||||
return TLObject.all[int.from_bytes(b.read(4), "little")].read(b, *args)
|
return objects[int.from_bytes(b.read(4), "little")].read(b, *args)
|
||||||
|
|
||||||
def write(self, *args) -> bytes:
|
def write(self, *args) -> bytes:
|
||||||
pass
|
pass
|
||||||
|
@ -1031,7 +1031,7 @@ class Client(Methods, BaseClient):
|
|||||||
access_hash = 0
|
access_hash = 0
|
||||||
peer_type = "group"
|
peer_type = "group"
|
||||||
elif isinstance(peer, (types.Channel, types.ChannelForbidden)):
|
elif isinstance(peer, (types.Channel, types.ChannelForbidden)):
|
||||||
peer_id = int("-100" + str(peer.id))
|
peer_id = utils.get_channel_id(peer.id)
|
||||||
access_hash = peer.access_hash
|
access_hash = peer.access_hash
|
||||||
|
|
||||||
username = getattr(peer, "username", None)
|
username = getattr(peer, "username", None)
|
||||||
@ -1139,7 +1139,7 @@ class Client(Methods, BaseClient):
|
|||||||
try:
|
try:
|
||||||
diff = await self.send(
|
diff = await self.send(
|
||||||
functions.updates.GetChannelDifference(
|
functions.updates.GetChannelDifference(
|
||||||
channel=await self.resolve_peer(int("-100" + str(channel_id))),
|
channel=await self.resolve_peer(utils.get_channel_id(channel_id)),
|
||||||
filter=types.ChannelMessagesFilter(
|
filter=types.ChannelMessagesFilter(
|
||||||
ranges=[types.MessageRange(
|
ranges=[types.MessageRange(
|
||||||
min_id=update.message.id,
|
min_id=update.message.id,
|
||||||
@ -1527,33 +1527,38 @@ class Client(Methods, BaseClient):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise PeerIdInvalid
|
raise PeerIdInvalid
|
||||||
|
|
||||||
if peer_id > 0:
|
peer_type = utils.get_type(peer_id)
|
||||||
|
|
||||||
|
if peer_type == "user":
|
||||||
self.fetch_peers(
|
self.fetch_peers(
|
||||||
await self.send(
|
await self.send(
|
||||||
functions.users.GetUsers(
|
functions.users.GetUsers(
|
||||||
id=[types.InputUser(
|
id=[
|
||||||
user_id=peer_id,
|
types.InputUser(
|
||||||
access_hash=0
|
user_id=peer_id,
|
||||||
)]
|
access_hash=0
|
||||||
|
)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
elif peer_type == "chat":
|
||||||
|
await self.send(
|
||||||
|
functions.messages.GetChats(
|
||||||
|
id=[-peer_id]
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
if str(peer_id).startswith("-100"):
|
await self.send(
|
||||||
await self.send(
|
functions.channels.GetChannels(
|
||||||
functions.channels.GetChannels(
|
id=[
|
||||||
id=[types.InputChannel(
|
types.InputChannel(
|
||||||
channel_id=int(str(peer_id)[4:]),
|
channel_id=utils.get_channel_id(peer_id),
|
||||||
access_hash=0
|
access_hash=0
|
||||||
)]
|
)
|
||||||
)
|
]
|
||||||
)
|
|
||||||
else:
|
|
||||||
await self.send(
|
|
||||||
functions.messages.GetChats(
|
|
||||||
id=[-peer_id]
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self.storage.get_peer_by_id(peer_id)
|
return self.storage.get_peer_by_id(peer_id)
|
||||||
|
@ -171,8 +171,13 @@ class Dispatcher:
|
|||||||
args = None
|
args = None
|
||||||
|
|
||||||
if isinstance(handler, handler_type):
|
if isinstance(handler, handler_type):
|
||||||
if handler.check(parsed_update):
|
try:
|
||||||
args = (parsed_update,)
|
if handler.check(parsed_update):
|
||||||
|
args = (parsed_update,)
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e, exc_info=True)
|
||||||
|
continue
|
||||||
|
|
||||||
elif isinstance(handler, RawUpdateHandler):
|
elif isinstance(handler, RawUpdateHandler):
|
||||||
args = (update, users, chats)
|
args = (update, users, chats)
|
||||||
|
|
||||||
|
@ -21,10 +21,11 @@ import base64
|
|||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
from concurrent.futures.thread import ThreadPoolExecutor
|
from concurrent.futures.thread import ThreadPoolExecutor
|
||||||
from typing import Union, List
|
from typing import List
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
import pyrogram
|
import pyrogram
|
||||||
|
from pyrogram.api.types import PeerUser, PeerChat, PeerChannel
|
||||||
from . import BaseClient
|
from . import BaseClient
|
||||||
from ...api import types
|
from ...api import types
|
||||||
|
|
||||||
@ -33,10 +34,17 @@ def decode(s: str) -> bytes:
|
|||||||
s = base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))
|
s = base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))
|
||||||
r = b""
|
r = b""
|
||||||
|
|
||||||
assert s[-1] == 2
|
try:
|
||||||
|
assert s[-1] == 2
|
||||||
|
skip = 1
|
||||||
|
except AssertionError:
|
||||||
|
assert s[-2] == 22
|
||||||
|
assert s[-1] == 4
|
||||||
|
skip = 2
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(s) - 1:
|
|
||||||
|
while i < len(s) - skip:
|
||||||
if s[i] != 0:
|
if s[i] != 0:
|
||||||
r += bytes([s[i]])
|
r += bytes([s[i]])
|
||||||
else:
|
else:
|
||||||
@ -52,7 +60,7 @@ def encode(s: bytes) -> str:
|
|||||||
r = b""
|
r = b""
|
||||||
n = 0
|
n = 0
|
||||||
|
|
||||||
for i in s + bytes([2]):
|
for i in s + bytes([22]) + bytes([4]):
|
||||||
if i == 0:
|
if i == 0:
|
||||||
n += 1
|
n += 1
|
||||||
else:
|
else:
|
||||||
@ -74,23 +82,6 @@ async def ainput(prompt: str = ""):
|
|||||||
)).rstrip()
|
)).rstrip()
|
||||||
|
|
||||||
|
|
||||||
def get_peer_id(input_peer) -> int:
|
|
||||||
return (
|
|
||||||
input_peer.user_id if isinstance(input_peer, types.InputPeerUser)
|
|
||||||
else -input_peer.chat_id if isinstance(input_peer, types.InputPeerChat)
|
|
||||||
else int("-100" + str(input_peer.channel_id))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_input_peer(peer_id: int, access_hash: int):
|
|
||||||
return (
|
|
||||||
types.InputPeerUser(user_id=peer_id, access_hash=access_hash) if peer_id > 0
|
|
||||||
else types.InputPeerChannel(channel_id=int(str(peer_id)[4:]), access_hash=access_hash)
|
|
||||||
if (str(peer_id).startswith("-100") and access_hash)
|
|
||||||
else types.InputPeerChat(chat_id=-peer_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_offset_date(dialogs):
|
def get_offset_date(dialogs):
|
||||||
for m in reversed(dialogs.messages):
|
for m in reversed(dialogs.messages):
|
||||||
if isinstance(m, types.MessageEmpty):
|
if isinstance(m, types.MessageEmpty):
|
||||||
@ -195,7 +186,7 @@ def parse_deleted_messages(client, update) -> List["pyrogram.Message"]:
|
|||||||
pyrogram.Message(
|
pyrogram.Message(
|
||||||
message_id=message,
|
message_id=message,
|
||||||
chat=pyrogram.Chat(
|
chat=pyrogram.Chat(
|
||||||
id=int("-100" + str(channel_id)),
|
id=get_channel_id(channel_id),
|
||||||
type="channel",
|
type="channel",
|
||||||
client=client
|
client=client
|
||||||
) if channel_id is not None else None,
|
) if channel_id is not None else None,
|
||||||
@ -215,3 +206,39 @@ def unpack_inline_message_id(inline_message_id: str) -> types.InputBotInlineMess
|
|||||||
id=r[1],
|
id=r[1],
|
||||||
access_hash=r[2]
|
access_hash=r[2]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
MIN_CHANNEL_ID = -1002147483647
|
||||||
|
MAX_CHANNEL_ID = -1000000000000
|
||||||
|
MIN_CHAT_ID = -2147483647
|
||||||
|
MAX_USER_ID = 2147483647
|
||||||
|
|
||||||
|
|
||||||
|
def get_peer_id(peer: Union[PeerUser, PeerChat, PeerChannel]) -> int:
|
||||||
|
if isinstance(peer, PeerUser):
|
||||||
|
return peer.user_id
|
||||||
|
|
||||||
|
if isinstance(peer, PeerChat):
|
||||||
|
return -peer.chat_id
|
||||||
|
|
||||||
|
if isinstance(peer, PeerChannel):
|
||||||
|
return MAX_CHANNEL_ID - peer.channel_id
|
||||||
|
|
||||||
|
raise ValueError("Peer type invalid: {}".format(peer))
|
||||||
|
|
||||||
|
|
||||||
|
def get_type(peer_id: int) -> str:
|
||||||
|
if peer_id < 0:
|
||||||
|
if MIN_CHAT_ID <= peer_id:
|
||||||
|
return "chat"
|
||||||
|
|
||||||
|
if MIN_CHANNEL_ID <= peer_id < MAX_CHANNEL_ID:
|
||||||
|
return "channel"
|
||||||
|
elif 0 < peer_id <= MAX_USER_ID:
|
||||||
|
return "user"
|
||||||
|
|
||||||
|
raise ValueError("Peer id invalid: {}".format(peer_id))
|
||||||
|
|
||||||
|
|
||||||
|
def get_channel_id(peer_id: int) -> int:
|
||||||
|
return MAX_CHANNEL_ID - peer_id
|
||||||
|
@ -20,7 +20,7 @@ from typing import Union
|
|||||||
|
|
||||||
import pyrogram
|
import pyrogram
|
||||||
from pyrogram.api import functions, types
|
from pyrogram.api import functions, types
|
||||||
from ...ext import BaseClient
|
from ...ext import BaseClient, utils
|
||||||
|
|
||||||
|
|
||||||
class GetChat(BaseClient):
|
class GetChat(BaseClient):
|
||||||
@ -70,7 +70,7 @@ class GetChat(BaseClient):
|
|||||||
chat_id = -r.chat.id
|
chat_id = -r.chat.id
|
||||||
|
|
||||||
if isinstance(r.chat, types.Channel):
|
if isinstance(r.chat, types.Channel):
|
||||||
chat_id = int("-100" + str(r.chat.id))
|
chat_id = utils.get_channel_id(r.chat.id)
|
||||||
|
|
||||||
peer = await self.resolve_peer(chat_id)
|
peer = await self.resolve_peer(chat_id)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import pyrogram
|
|||||||
from pyrogram.api import functions, types
|
from pyrogram.api import functions, types
|
||||||
from pyrogram.errors import FloodWait
|
from pyrogram.errors import FloodWait
|
||||||
|
|
||||||
from ...ext import BaseClient
|
from ...ext import BaseClient, utils
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -101,10 +101,8 @@ class GetDialogs(BaseClient):
|
|||||||
chat_id = to_id.user_id
|
chat_id = to_id.user_id
|
||||||
else:
|
else:
|
||||||
chat_id = message.from_id
|
chat_id = message.from_id
|
||||||
elif isinstance(to_id, types.PeerChat):
|
|
||||||
chat_id = -to_id.chat_id
|
|
||||||
else:
|
else:
|
||||||
chat_id = int("-100" + str(to_id.channel_id))
|
chat_id = utils.get_peer_id(to_id)
|
||||||
|
|
||||||
messages[chat_id] = await pyrogram.Message._parse(self, message, users, chats)
|
messages[chat_id] = await pyrogram.Message._parse(self, message, users, chats)
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from pyrogram.api import functions
|
from pyrogram.api import functions
|
||||||
|
|
||||||
from ...ext import BaseClient
|
from ...ext import BaseClient
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ from typing import List, Union
|
|||||||
|
|
||||||
from pyrogram.api import functions, types
|
from pyrogram.api import functions, types
|
||||||
from pyrogram.client.ext import utils
|
from pyrogram.client.ext import utils
|
||||||
|
|
||||||
from ...ext import BaseClient
|
from ...ext import BaseClient
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ from typing import Union, List
|
|||||||
import pyrogram
|
import pyrogram
|
||||||
from pyrogram.api import functions, types
|
from pyrogram.api import functions, types
|
||||||
from pyrogram.client.ext import utils
|
from pyrogram.client.ext import utils
|
||||||
|
|
||||||
from ...ext import BaseClient
|
from ...ext import BaseClient
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from pyrogram.api import functions, types
|
from pyrogram.api import functions, types
|
||||||
|
|
||||||
from ...ext import BaseClient
|
from ...ext import BaseClient
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from pyrogram.api import functions
|
from pyrogram.api import functions
|
||||||
|
|
||||||
from ...ext import BaseClient
|
from ...ext import BaseClient
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@
|
|||||||
# 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 .memory_storage import MemoryStorage
|
|
||||||
from .file_storage import FileStorage
|
from .file_storage import FileStorage
|
||||||
|
from .memory_storage import MemoryStorage
|
||||||
from .storage import Storage
|
from .storage import Storage
|
||||||
|
@ -25,7 +25,5 @@ class CallbackGame(Object):
|
|||||||
Use BotFather to set up your game.
|
Use BotFather to set up your game.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = []
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -25,6 +25,7 @@ from pyrogram.api import types
|
|||||||
from ..object import Object
|
from ..object import Object
|
||||||
from ..update import Update
|
from ..update import Update
|
||||||
from ..user_and_chats import User
|
from ..user_and_chats import User
|
||||||
|
from ...ext import utils
|
||||||
|
|
||||||
|
|
||||||
class CallbackQuery(Object, Update):
|
class CallbackQuery(Object, Update):
|
||||||
@ -60,8 +61,6 @@ class CallbackQuery(Object, Update):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["id", "from_user", "chat_instance", "message", "inline_message_id", "data", "game_short_name"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -90,16 +89,7 @@ class CallbackQuery(Object, Update):
|
|||||||
inline_message_id = None
|
inline_message_id = None
|
||||||
|
|
||||||
if isinstance(callback_query, types.UpdateBotCallbackQuery):
|
if isinstance(callback_query, types.UpdateBotCallbackQuery):
|
||||||
peer = callback_query.peer
|
message = await client.get_messages(utils.get_peer_id(callback_query.peer), callback_query.msg_id)
|
||||||
|
|
||||||
if isinstance(peer, types.PeerUser):
|
|
||||||
peer_id = peer.user_id
|
|
||||||
elif isinstance(peer, types.PeerChat):
|
|
||||||
peer_id = -peer.chat_id
|
|
||||||
else:
|
|
||||||
peer_id = int("-100" + str(peer.channel_id))
|
|
||||||
|
|
||||||
message = await client.get_messages(peer_id, callback_query.msg_id)
|
|
||||||
elif isinstance(callback_query, types.UpdateInlineBotCallbackQuery):
|
elif isinstance(callback_query, types.UpdateInlineBotCallbackQuery):
|
||||||
inline_message_id = b64encode(
|
inline_message_id = b64encode(
|
||||||
pack(
|
pack(
|
||||||
|
@ -37,8 +37,6 @@ class ForceReply(Object):
|
|||||||
2) if the bot's message is a reply (has reply_to_message_id), sender of the original message.
|
2) if the bot's message is a reply (has reply_to_message_id), sender of the original message.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["selective"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
selective: bool = None
|
selective: bool = None
|
||||||
|
@ -37,8 +37,6 @@ class GameHighScore(Object):
|
|||||||
Position in high score table for the game.
|
Position in high score table for the game.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["user", "score", "position"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -23,6 +23,7 @@ from pyrogram.api.types import (
|
|||||||
KeyboardButtonUrl, KeyboardButtonCallback,
|
KeyboardButtonUrl, KeyboardButtonCallback,
|
||||||
KeyboardButtonSwitchInline, KeyboardButtonGame
|
KeyboardButtonSwitchInline, KeyboardButtonGame
|
||||||
)
|
)
|
||||||
|
|
||||||
from .callback_game import CallbackGame
|
from .callback_game import CallbackGame
|
||||||
from ..object import Object
|
from ..object import Object
|
||||||
|
|
||||||
@ -59,10 +60,6 @@ class InlineKeyboardButton(Object):
|
|||||||
|
|
||||||
# TODO: Add callback_game and pay fields
|
# TODO: Add callback_game and pay fields
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"text", "url", "callback_data", "switch_inline_query", "switch_inline_query_current_chat", "callback_game"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from pyrogram.api.types import ReplyInlineMarkup, KeyboardButtonRow
|
from pyrogram.api.types import ReplyInlineMarkup, KeyboardButtonRow
|
||||||
|
|
||||||
from . import InlineKeyboardButton
|
from . import InlineKeyboardButton
|
||||||
from ..object import Object
|
from ..object import Object
|
||||||
|
|
||||||
@ -31,8 +32,6 @@ class InlineKeyboardMarkup(Object):
|
|||||||
List of button rows, each represented by a List of InlineKeyboardButton objects.
|
List of button rows, each represented by a List of InlineKeyboardButton objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["inline_keyboard"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
inline_keyboard: List[List[InlineKeyboardButton]]
|
inline_keyboard: List[List[InlineKeyboardButton]]
|
||||||
|
@ -41,8 +41,6 @@ class KeyboardButton(Object):
|
|||||||
Available in private chats only.
|
Available in private chats only.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["text", "request_contact", "request_location"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
|
@ -20,6 +20,7 @@ from typing import List, Union
|
|||||||
|
|
||||||
from pyrogram.api.types import KeyboardButtonRow
|
from pyrogram.api.types import KeyboardButtonRow
|
||||||
from pyrogram.api.types import ReplyKeyboardMarkup as RawReplyKeyboardMarkup
|
from pyrogram.api.types import ReplyKeyboardMarkup as RawReplyKeyboardMarkup
|
||||||
|
|
||||||
from . import KeyboardButton
|
from . import KeyboardButton
|
||||||
from ..object import Object
|
from ..object import Object
|
||||||
|
|
||||||
@ -49,8 +50,6 @@ class ReplyKeyboardMarkup(Object):
|
|||||||
select the new language. Other users in the group don't see the keyboard.
|
select the new language. Other users in the group don't see the keyboard.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["keyboard", "resize_keyboard", "one_time_keyboard", "selective"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
keyboard: List[List[Union[KeyboardButton, str]]],
|
keyboard: List[List[Union[KeyboardButton, str]]],
|
||||||
|
@ -38,8 +38,6 @@ class ReplyKeyboardRemove(Object):
|
|||||||
keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet.
|
keyboard for that user, while still showing the keyboard with poll options to users who haven't voted yet.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["selective"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
selective: bool = None
|
selective: bool = None
|
||||||
|
@ -48,7 +48,6 @@ class InlineQuery(Object, Update):
|
|||||||
location (:obj:`Location`. *optional*):
|
location (:obj:`Location`. *optional*):
|
||||||
Sender location, only for bots that request user location.
|
Sender location, only for bots that request user location.
|
||||||
"""
|
"""
|
||||||
__slots__ = ["id", "from_user", "query", "offset", "location"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
@ -53,8 +53,6 @@ class InlineQueryResult(Object):
|
|||||||
- :obj:`InlineQueryResultAnimation`
|
- :obj:`InlineQueryResultAnimation`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["type", "id", "input_message_content", "reply_markup"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
type: str,
|
type: str,
|
||||||
|
@ -68,11 +68,6 @@ class InlineQueryResultAnimation(InlineQueryResult):
|
|||||||
Content of the message to be sent instead of the photo.
|
Content of the message to be sent instead of the photo.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"animation_url", "thumb_url", "title", "description", "caption", "parse_mode", "reply_markup",
|
|
||||||
"input_message_content"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
animation_url: str,
|
animation_url: str,
|
||||||
|
@ -49,8 +49,6 @@ class InlineQueryResultArticle(InlineQueryResult):
|
|||||||
Inline keyboard attached to the message.
|
Inline keyboard attached to the message.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["title", "url", "description", "thumb_url"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
title: str,
|
title: str,
|
||||||
|
@ -68,11 +68,6 @@ class InlineQueryResultPhoto(InlineQueryResult):
|
|||||||
Content of the message to be sent instead of the photo.
|
Content of the message to be sent instead of the photo.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"photo_url", "thumb_url", "title", "description", "caption", "parse_mode", "reply_markup",
|
|
||||||
"input_message_content"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
photo_url: str,
|
photo_url: str,
|
||||||
|
@ -30,7 +30,6 @@ class InputMedia(Object):
|
|||||||
- :obj:`InputMediaPhoto`
|
- :obj:`InputMediaPhoto`
|
||||||
- :obj:`InputMediaVideo`
|
- :obj:`InputMediaVideo`
|
||||||
"""
|
"""
|
||||||
__slots__ = ["media", "caption", "parse_mode"]
|
|
||||||
|
|
||||||
def __init__(self, media: str, caption: str, parse_mode: str):
|
def __init__(self, media: str, caption: str, parse_mode: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
@ -56,8 +56,6 @@ class InputMediaAnimation(InputMedia):
|
|||||||
Animation duration.
|
Animation duration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["thumb", "width", "height", "duration"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
media: str,
|
media: str,
|
||||||
|
@ -58,8 +58,6 @@ class InputMediaAudio(InputMedia):
|
|||||||
Title of the audio
|
Title of the audio
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["thumb", "duration", "performer", "title"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
media: str,
|
media: str,
|
||||||
|
@ -47,8 +47,6 @@ class InputMediaDocument(InputMedia):
|
|||||||
Pass None to completely disable style parsing.
|
Pass None to completely disable style parsing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["thumb"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
media: str,
|
media: str,
|
||||||
|
@ -43,8 +43,6 @@ class InputMediaPhoto(InputMedia):
|
|||||||
Pass None to completely disable style parsing.
|
Pass None to completely disable style parsing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = []
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
media: str,
|
media: str,
|
||||||
|
@ -61,8 +61,6 @@ class InputMediaVideo(InputMedia):
|
|||||||
Pass True, if the uploaded video is suitable for streaming.
|
Pass True, if the uploaded video is suitable for streaming.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["thumb", "width", "height", "duration", "supports_streaming"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
media: str,
|
media: str,
|
||||||
|
@ -37,8 +37,6 @@ class InputPhoneContact(Object):
|
|||||||
Contact's last name
|
Contact's last name
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = []
|
|
||||||
|
|
||||||
def __init__(self, phone: str, first_name: str, last_name: str = ""):
|
def __init__(self, phone: str, first_name: str, last_name: str = ""):
|
||||||
super().__init__(None)
|
super().__init__(None)
|
||||||
|
|
||||||
|
@ -31,8 +31,6 @@ class InputMessageContent(Object):
|
|||||||
- :obj:`InputTextMessageContent`
|
- :obj:`InputTextMessageContent`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = []
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@ -41,8 +41,6 @@ class InputTextMessageContent(InputMessageContent):
|
|||||||
Disables link previews for links in this message.
|
Disables link previews for links in this message.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["message_text", "parse_mode", "disable_web_page_preview"]
|
|
||||||
|
|
||||||
def __init__(self, message_text: str, parse_mode: Union[str, None] = object, disable_web_page_preview: bool = None):
|
def __init__(self, message_text: str, parse_mode: Union[str, None] = object, disable_web_page_preview: bool = None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
@ -58,8 +58,6 @@ class Animation(Object):
|
|||||||
Animation thumbnails.
|
Animation thumbnails.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "duration", "thumbs"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -58,10 +58,6 @@ class Audio(Object):
|
|||||||
Thumbnails of the music file album cover.
|
Thumbnails of the music file album cover.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"file_id", "file_name", "mime_type", "file_size", "date", "duration", "performer", "title", "thumbs"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -42,8 +42,6 @@ class Contact(Object):
|
|||||||
Additional data about the contact in the form of a vCard.
|
Additional data about the contact in the form of a vCard.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["phone_number", "first_name", "last_name", "user_id", "vcard"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -49,8 +49,6 @@ class Document(Object):
|
|||||||
Document thumbnails as defined by sender.
|
Document thumbnails as defined by sender.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["file_id", "file_name", "mime_type", "file_size", "date", "thumbs"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -48,8 +48,6 @@ class Game(Object):
|
|||||||
Upload via BotFather.
|
Upload via BotFather.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["id", "title", "short_name", "description", "photo", "animation"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -33,8 +33,6 @@ class Location(Object):
|
|||||||
Latitude as defined by sender.
|
Latitude as defined by sender.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["longitude", "latitude"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -31,7 +31,8 @@ from ..object import Object
|
|||||||
from ..update import Update
|
from ..update import Update
|
||||||
from ..user_and_chats.chat import Chat
|
from ..user_and_chats.chat import Chat
|
||||||
from ..user_and_chats.user import User
|
from ..user_and_chats.user import User
|
||||||
from ...parser import utils, Parser
|
from ...ext import utils
|
||||||
|
from ...parser import utils as parser_utils, Parser
|
||||||
|
|
||||||
|
|
||||||
class Str(str):
|
class Str(str):
|
||||||
@ -54,7 +55,7 @@ class Str(str):
|
|||||||
return Parser.unparse(self, self.entities, True)
|
return Parser.unparse(self, self.entities, True)
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
return utils.remove_surrogates(utils.add_surrogates(self)[item])
|
return parser_utils.remove_surrogates(parser_utils.add_surrogates(self)[item])
|
||||||
|
|
||||||
|
|
||||||
class Message(Object, Update):
|
class Message(Object, Update):
|
||||||
@ -263,17 +264,6 @@ class Message(Object, Update):
|
|||||||
|
|
||||||
# TODO: Add game missing field. Also invoice, successful_payment, connected_website
|
# TODO: Add game missing field. Also invoice, successful_payment, connected_website
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"message_id", "date", "chat", "from_user", "forward_from", "forward_sender_name", "forward_from_chat",
|
|
||||||
"forward_from_message_id", "forward_signature", "forward_date", "reply_to_message", "mentioned", "empty",
|
|
||||||
"service", "media", "edit_date", "media_group_id", "author_signature", "text", "entities", "caption_entities",
|
|
||||||
"audio", "document", "photo", "sticker", "animation", "game", "video", "voice", "video_note", "caption",
|
|
||||||
"contact", "location", "venue", "web_page", "poll", "new_chat_members", "left_chat_member", "new_chat_title",
|
|
||||||
"new_chat_photo", "delete_chat_photo", "group_chat_created", "supergroup_chat_created", "channel_chat_created",
|
|
||||||
"migrate_to_chat_id", "migrate_from_chat_id", "pinned_message", "game_high_score", "views", "via_bot",
|
|
||||||
"outgoing", "matches", "command", "reply_markup"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -446,7 +436,7 @@ class Message(Object, Update):
|
|||||||
new_chat_title=new_chat_title,
|
new_chat_title=new_chat_title,
|
||||||
new_chat_photo=new_chat_photo,
|
new_chat_photo=new_chat_photo,
|
||||||
delete_chat_photo=delete_chat_photo,
|
delete_chat_photo=delete_chat_photo,
|
||||||
migrate_to_chat_id=int("-100" + str(migrate_to_chat_id)) if migrate_to_chat_id else None,
|
migrate_to_chat_id=utils.get_channel_id(migrate_to_chat_id) if migrate_to_chat_id else None,
|
||||||
migrate_from_chat_id=-migrate_from_chat_id if migrate_from_chat_id else None,
|
migrate_from_chat_id=-migrate_from_chat_id if migrate_from_chat_id else None,
|
||||||
group_chat_created=group_chat_created,
|
group_chat_created=group_chat_created,
|
||||||
channel_chat_created=channel_chat_created,
|
channel_chat_created=channel_chat_created,
|
||||||
@ -602,10 +592,26 @@ class Message(Object, Update):
|
|||||||
date=message.date,
|
date=message.date,
|
||||||
chat=Chat._parse(client, message, users, chats),
|
chat=Chat._parse(client, message, users, chats),
|
||||||
from_user=User._parse(client, users.get(message.from_id, None)),
|
from_user=User._parse(client, users.get(message.from_id, None)),
|
||||||
text=Str(message.message).init(entities) or None if media is None else None,
|
text=(
|
||||||
caption=Str(message.message).init(entities) or None if media is not None else None,
|
Str(message.message).init(entities) or None
|
||||||
entities=entities or None if media is None else None,
|
if media is None or web_page is not None
|
||||||
caption_entities=entities or None if media is not None else None,
|
else None
|
||||||
|
),
|
||||||
|
caption=(
|
||||||
|
Str(message.message).init(entities) or None
|
||||||
|
if media is not None and web_page is None
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
entities=(
|
||||||
|
entities or None
|
||||||
|
if media is None or web_page is not None
|
||||||
|
else None
|
||||||
|
),
|
||||||
|
caption_entities=(
|
||||||
|
entities or None
|
||||||
|
if media is not None and web_page is None
|
||||||
|
else None
|
||||||
|
),
|
||||||
author_signature=message.post_author,
|
author_signature=message.post_author,
|
||||||
forward_from=forward_from,
|
forward_from=forward_from,
|
||||||
forward_sender_name=forward_sender_name,
|
forward_sender_name=forward_sender_name,
|
||||||
|
@ -47,8 +47,6 @@ class MessageEntity(Object):
|
|||||||
For "text_mention" only, the mentioned user.
|
For "text_mention" only, the mentioned user.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["type", "offset", "length", "url", "user"]
|
|
||||||
|
|
||||||
ENTITIES = {
|
ENTITIES = {
|
||||||
types.MessageEntityMention.ID: "mention",
|
types.MessageEntityMention.ID: "mention",
|
||||||
types.MessageEntityHashtag.ID: "hashtag",
|
types.MessageEntityHashtag.ID: "hashtag",
|
||||||
|
@ -49,8 +49,6 @@ class Photo(Object):
|
|||||||
Available thumbnails of this photo.
|
Available thumbnails of this photo.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["file_id", "width", "height", "file_size", "date", "thumbs"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -48,8 +48,6 @@ class Poll(Object, Update):
|
|||||||
Index of your chosen option (0-9), None in case you haven't voted yet.
|
Index of your chosen option (0-9), None in case you haven't voted yet.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["id", "question", "options", "is_closed", "total_voters", "chosen_option"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -35,8 +35,6 @@ class PollOption(Object):
|
|||||||
The data this poll option is holding.
|
The data this poll option is holding.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["text", "voter_count", "data"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -66,10 +66,6 @@ class Sticker(Object):
|
|||||||
|
|
||||||
# TODO: Add mask position
|
# TODO: Add mask position
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"file_id", "file_name", "mime_type", "file_size", "date", "width", "height", "emoji", "set_name", "thumbs"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -29,8 +29,6 @@ class StrippedThumbnail(Object):
|
|||||||
Thumbnail data
|
Thumbnail data
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["data"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -43,8 +43,6 @@ class Thumbnail(Object):
|
|||||||
File size.
|
File size.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["file_id", "width", "height", "file_size"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -44,8 +44,6 @@ class Venue(Object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["location", "title", "address", "foursquare_id", "foursquare_type"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -61,11 +61,6 @@ class Video(Object):
|
|||||||
Video thumbnails.
|
Video thumbnails.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"file_id", "width", "height", "duration", "file_name", "mime_type", "supports_streaming", "file_size", "date",
|
|
||||||
"thumbs"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -52,8 +52,6 @@ class VideoNote(Object):
|
|||||||
Video thumbnails.
|
Video thumbnails.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["file_id", "mime_type", "file_size", "date", "length", "duration", "thumbs"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -47,8 +47,6 @@ class Voice(Object):
|
|||||||
Date the voice was sent in Unix time.
|
Date the voice was sent in Unix time.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["file_id", "duration", "waveform", "mime_type", "file_size", "date"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -83,12 +83,6 @@ class WebPage(Object):
|
|||||||
Author of the webpage, eg the Twitter user for a tweet, or the author in an article.
|
Author of the webpage, eg the Twitter user for a tweet, or the author in an article.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"id", "url", "display_url", "type", "site_name", "title", "description",
|
|
||||||
"audio", "document", "photo", "animation", "video",
|
|
||||||
"embed_url", "embed_type", "embed_width", "embed_height", "duration", "author"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -29,8 +29,6 @@ class Meta(type, metaclass=type("", (type,), {"__str__": lambda _: "~hi"})):
|
|||||||
|
|
||||||
|
|
||||||
class Object(metaclass=Meta):
|
class Object(metaclass=Meta):
|
||||||
__slots__ = ["_client"]
|
|
||||||
|
|
||||||
def __init__(self, client: "pyrogram.BaseClient" = None):
|
def __init__(self, client: "pyrogram.BaseClient" = None):
|
||||||
self._client = client
|
self._client = client
|
||||||
|
|
||||||
@ -50,7 +48,7 @@ class Object(metaclass=Meta):
|
|||||||
else (attr, str(datetime.fromtimestamp(getattr(obj, attr))))
|
else (attr, str(datetime.fromtimestamp(getattr(obj, attr))))
|
||||||
if attr.endswith("date")
|
if attr.endswith("date")
|
||||||
else (attr, getattr(obj, attr))
|
else (attr, getattr(obj, attr))
|
||||||
for attr in getattr(obj, "__slots__", [])
|
for attr in filter(lambda x: not x.startswith("_"), obj.__dict__)
|
||||||
if getattr(obj, attr) is not None
|
if getattr(obj, attr) is not None
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -63,13 +61,13 @@ class Object(metaclass=Meta):
|
|||||||
self.__class__.__name__,
|
self.__class__.__name__,
|
||||||
", ".join(
|
", ".join(
|
||||||
"{}={}".format(attr, repr(getattr(self, attr)))
|
"{}={}".format(attr, repr(getattr(self, attr)))
|
||||||
for attr in self.__slots__
|
for attr in filter(lambda x: not x.startswith("_"), self.__dict__)
|
||||||
if getattr(self, attr) is not None
|
if getattr(self, attr) is not None
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def __eq__(self, other: "Object") -> bool:
|
def __eq__(self, other: "Object") -> bool:
|
||||||
for attr in self.__slots__:
|
for attr in self.__dict__:
|
||||||
try:
|
try:
|
||||||
if getattr(self, attr) != getattr(other, attr):
|
if getattr(self, attr) != getattr(other, attr):
|
||||||
return False
|
return False
|
||||||
|
@ -26,8 +26,6 @@ class ContinuePropagation(StopAsyncIteration):
|
|||||||
|
|
||||||
|
|
||||||
class Update:
|
class Update:
|
||||||
__slots__ = []
|
|
||||||
|
|
||||||
def stop_propagation(self):
|
def stop_propagation(self):
|
||||||
raise StopPropagation
|
raise StopPropagation
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ from pyrogram.api import types
|
|||||||
from .chat_permissions import ChatPermissions
|
from .chat_permissions import ChatPermissions
|
||||||
from .chat_photo import ChatPhoto
|
from .chat_photo import ChatPhoto
|
||||||
from ..object import Object
|
from ..object import Object
|
||||||
|
from ...ext import utils
|
||||||
|
|
||||||
|
|
||||||
class Chat(Object):
|
class Chat(Object):
|
||||||
@ -94,12 +95,6 @@ class Chat(Object):
|
|||||||
Information about the chat default permissions, for groups and supergroups.
|
Information about the chat default permissions, for groups and supergroups.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"id", "type", "is_verified", "is_restricted", "is_scam", "is_support", "title", "username", "first_name",
|
|
||||||
"last_name", "photo", "description", "invite_link", "pinned_message", "sticker_set_name", "can_set_sticker_set",
|
|
||||||
"members_count", "restriction_reason", "permissions"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -180,7 +175,7 @@ class Chat(Object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse_channel_chat(client, channel: types.Channel) -> "Chat":
|
def _parse_channel_chat(client, channel: types.Channel) -> "Chat":
|
||||||
peer_id = int("-100" + str(channel.id))
|
peer_id = utils.get_channel_id(channel.id)
|
||||||
|
|
||||||
return Chat(
|
return Chat(
|
||||||
id=peer_id,
|
id=peer_id,
|
||||||
|
@ -54,8 +54,6 @@ class ChatMember(Object):
|
|||||||
Information about the member permissions.
|
Information about the member permissions.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["user", "status", "date", "is_member", "invited_by", "promoted_by", "restricted_by", "permissions"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -94,13 +94,6 @@ class ChatPermissions(Object):
|
|||||||
True, if polls can be sent, implies can_send_media_messages.
|
True, if polls can be sent, implies can_send_media_messages.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"until_date", "can_be_edited", "can_change_info", "can_post_messages", "can_edit_messages",
|
|
||||||
"can_delete_messages", "can_restrict_members", "can_invite_users", "can_pin_messages", "can_promote_members",
|
|
||||||
"can_send_messages", "can_send_media_messages", "can_send_other_messages", "can_add_web_page_previews",
|
|
||||||
"can_send_polls"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -35,8 +35,6 @@ class ChatPhoto(Object):
|
|||||||
Unique file identifier of big (640x640) chat photo. This file_id can be used only for photo download.
|
Unique file identifier of big (640x640) chat photo. This file_id can be used only for photo download.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["small_file_id", "big_file_id"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -45,8 +45,6 @@ class ChatPreview(Object):
|
|||||||
Preview of some of the chat members.
|
Preview of some of the chat members.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["title", "type", "members_count", "photo", "members"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -21,6 +21,7 @@ import pyrogram
|
|||||||
from pyrogram.api import types
|
from pyrogram.api import types
|
||||||
from ..object import Object
|
from ..object import Object
|
||||||
from ..user_and_chats import Chat
|
from ..user_and_chats import Chat
|
||||||
|
from ...ext import utils
|
||||||
|
|
||||||
|
|
||||||
class Dialog(Object):
|
class Dialog(Object):
|
||||||
@ -46,8 +47,6 @@ class Dialog(Object):
|
|||||||
True, if the dialog is pinned.
|
True, if the dialog is pinned.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ["chat", "top_message", "unread_messages_count", "unread_mentions_count", "unread_mark", "is_pinned"]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
@ -70,18 +69,9 @@ class Dialog(Object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _parse(client, dialog: types.Dialog, messages, users, chats) -> "Dialog":
|
def _parse(client, dialog: types.Dialog, messages, users, chats) -> "Dialog":
|
||||||
chat_id = dialog.peer
|
|
||||||
|
|
||||||
if isinstance(chat_id, types.PeerUser):
|
|
||||||
chat_id = chat_id.user_id
|
|
||||||
elif isinstance(chat_id, types.PeerChat):
|
|
||||||
chat_id = -chat_id.chat_id
|
|
||||||
else:
|
|
||||||
chat_id = int("-100" + str(chat_id.channel_id))
|
|
||||||
|
|
||||||
return Dialog(
|
return Dialog(
|
||||||
chat=Chat._parse_dialog(client, dialog.peer, users, chats),
|
chat=Chat._parse_dialog(client, dialog.peer, users, chats),
|
||||||
top_message=messages.get(chat_id),
|
top_message=messages.get(utils.get_peer_id(dialog.peer)),
|
||||||
unread_messages_count=dialog.unread_count,
|
unread_messages_count=dialog.unread_count,
|
||||||
unread_mentions_count=dialog.unread_mentions_count,
|
unread_mentions_count=dialog.unread_mentions_count,
|
||||||
unread_mark=dialog.unread_mark,
|
unread_mark=dialog.unread_mark,
|
||||||
|
@ -106,12 +106,6 @@ class User(Object, Update):
|
|||||||
This field is available only in case *is_restricted* is True.
|
This field is available only in case *is_restricted* is True.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = [
|
|
||||||
"id", "is_self", "is_contact", "is_mutual_contact", "is_deleted", "is_bot", "is_verified", "is_restricted",
|
|
||||||
"is_scam", "is_support", "first_name", "last_name", "status", "last_online_date", "next_offline_date",
|
|
||||||
"username", "language_code", "dc_id", "phone_number", "photo", "restriction_reason"
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
@ -21,8 +21,9 @@ from datetime import datetime
|
|||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
from pyrogram.api.core import TLObject
|
|
||||||
from pyrogram.api.types import RpcError as RawRPCError
|
from pyrogram.api.types import RpcError as RawRPCError
|
||||||
|
|
||||||
|
from pyrogram.api.core import TLObject
|
||||||
from .exceptions.all import exceptions
|
from .exceptions.all import exceptions
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ from pyrogram.api import functions, types
|
|||||||
from pyrogram.api.core import TLObject, Long, Int
|
from pyrogram.api.core import TLObject, Long, Int
|
||||||
from pyrogram.connection import Connection
|
from pyrogram.connection import Connection
|
||||||
from pyrogram.crypto import AES, RSA, Prime
|
from pyrogram.crypto import AES, RSA, Prime
|
||||||
|
|
||||||
from .internals import MsgId
|
from .internals import MsgId
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -16,9 +16,10 @@
|
|||||||
# 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 pyrogram.api.core import Message, MsgContainer, TLObject
|
|
||||||
from pyrogram.api.functions import Ping
|
from pyrogram.api.functions import Ping
|
||||||
from pyrogram.api.types import MsgsAck, HttpWait
|
from pyrogram.api.types import MsgsAck, HttpWait
|
||||||
|
|
||||||
|
from pyrogram.api.core import Message, MsgContainer, TLObject
|
||||||
from .msg_id import MsgId
|
from .msg_id import MsgId
|
||||||
from .seq_no import SeqNo
|
from .seq_no import SeqNo
|
||||||
|
|
||||||
|
@ -22,15 +22,15 @@ from datetime import datetime, timedelta
|
|||||||
from hashlib import sha1
|
from hashlib import sha1
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
|
from pyrogram.api.all import layer
|
||||||
|
|
||||||
import pyrogram
|
import pyrogram
|
||||||
from pyrogram import __copyright__, __license__, __version__
|
from pyrogram import __copyright__, __license__, __version__
|
||||||
from pyrogram.api import functions, types
|
from pyrogram.api import functions, types
|
||||||
from pyrogram.api.all import layer
|
|
||||||
from pyrogram.api.core import TLObject, MsgContainer, Int, Long, FutureSalt, FutureSalts
|
from pyrogram.api.core import TLObject, MsgContainer, Int, Long, FutureSalt, FutureSalts
|
||||||
from pyrogram.connection import Connection
|
from pyrogram.connection import Connection
|
||||||
from pyrogram.crypto import MTProto
|
from pyrogram.crypto import MTProto
|
||||||
from pyrogram.errors import RPCError, InternalServerError, AuthKeyDuplicated
|
from pyrogram.errors import RPCError, InternalServerError, AuthKeyDuplicated
|
||||||
|
|
||||||
from .internals import MsgId, MsgFactory
|
from .internals import MsgId, MsgFactory
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user