mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-11-10 19:46:36 +03:00
Add type hints to all public methods in the client
This commit is contained in:
parent
c0e506e568
commit
cd4b915522
|
@ -1,10 +1,14 @@
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
import inspect
|
||||||
|
import typing
|
||||||
|
|
||||||
from .users import UserMethods, _NOT_A_REQUEST
|
from .users import UserMethods, _NOT_A_REQUEST
|
||||||
from .. import helpers, utils
|
from .. import helpers, utils
|
||||||
from ..tl import functions, TLRequest
|
from ..tl import functions, TLRequest
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
# TODO Make use of :tl:`InvokeWithMessagesRange` somehow
|
# TODO Make use of :tl:`InvokeWithMessagesRange` somehow
|
||||||
# For that, we need to use :tl:`GetSplitRanges` first.
|
# For that, we need to use :tl:`GetSplitRanges` first.
|
||||||
|
@ -105,8 +109,16 @@ class _TakeoutClient:
|
||||||
|
|
||||||
class AccountMethods(UserMethods):
|
class AccountMethods(UserMethods):
|
||||||
def takeout(
|
def takeout(
|
||||||
self, finalize=True, *, contacts=None, users=None, chats=None,
|
self: 'TelegramClient',
|
||||||
megagroups=None, channels=None, files=None, max_file_size=None):
|
finalize: bool = True,
|
||||||
|
*,
|
||||||
|
contacts: bool = None,
|
||||||
|
users: bool = None,
|
||||||
|
chats: bool = None,
|
||||||
|
megagroups: bool = None,
|
||||||
|
channels: bool = None,
|
||||||
|
files: bool = None,
|
||||||
|
max_file_size: bool = None) -> 'TelegramClient':
|
||||||
"""
|
"""
|
||||||
Creates a proxy object over the current :ref:`TelegramClient` through
|
Creates a proxy object over the current :ref:`TelegramClient` through
|
||||||
which making requests will use :tl:`InvokeWithTakeoutRequest` to wrap
|
which making requests will use :tl:`InvokeWithTakeoutRequest` to wrap
|
||||||
|
@ -146,6 +158,10 @@ class AccountMethods(UserMethods):
|
||||||
<telethon.sessions.abstract.Session.takeout_id>`.
|
<telethon.sessions.abstract.Session.takeout_id>`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
finalize (`bool`):
|
||||||
|
Whether the takeout session should be finalized upon
|
||||||
|
exit or not.
|
||||||
|
|
||||||
contacts (`bool`):
|
contacts (`bool`):
|
||||||
Set to ``True`` if you plan on downloading contacts.
|
Set to ``True`` if you plan on downloading contacts.
|
||||||
|
|
||||||
|
@ -192,7 +208,7 @@ class AccountMethods(UserMethods):
|
||||||
|
|
||||||
return _TakeoutClient(finalize, self, request)
|
return _TakeoutClient(finalize, self, request)
|
||||||
|
|
||||||
async def end_takeout(self, success):
|
async def end_takeout(self: 'TelegramClient', success: bool) -> bool:
|
||||||
"""
|
"""
|
||||||
Finishes a takeout, with specified result sent back to Telegram.
|
Finishes a takeout, with specified result sent back to Telegram.
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,33 @@
|
||||||
import datetime
|
|
||||||
import getpass
|
import getpass
|
||||||
import hashlib
|
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import typing
|
||||||
|
|
||||||
from .messageparse import MessageParseMethods
|
from .messageparse import MessageParseMethods
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import utils, helpers, errors, password as pwd_mod
|
from .. import utils, helpers, errors, password as pwd_mod
|
||||||
from ..tl import types, functions
|
from ..tl import types, functions
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class AuthMethods(MessageParseMethods, UserMethods):
|
class AuthMethods(MessageParseMethods, UserMethods):
|
||||||
|
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
def start(
|
def start(
|
||||||
self,
|
self: 'TelegramClient',
|
||||||
phone=lambda: input('Please enter your phone (or bot token): '),
|
phone: typing.Callable[[], str] = lambda: input('Please enter your phone (or bot token): '),
|
||||||
password=lambda: getpass.getpass('Please enter your password: '),
|
password: typing.Callable[[], str] = lambda: getpass.getpass('Please enter your password: '),
|
||||||
*,
|
*,
|
||||||
bot_token=None, force_sms=False, code_callback=None,
|
bot_token: str = None,
|
||||||
first_name='New User', last_name='', max_attempts=3):
|
force_sms: bool = False,
|
||||||
|
code_callback: typing.Callable[[], typing.Union[str, int]] = None,
|
||||||
|
first_name: str = 'New User',
|
||||||
|
last_name: str = '',
|
||||||
|
max_attempts: int = 3) -> 'TelegramClient':
|
||||||
"""
|
"""
|
||||||
Convenience method to interactively connect and sign in if required,
|
Convenience method to interactively connect and sign in if required,
|
||||||
also taking into consideration that 2FA may be enabled in the account.
|
also taking into consideration that 2FA may be enabled in the account.
|
||||||
|
@ -238,8 +244,13 @@ class AuthMethods(MessageParseMethods, UserMethods):
|
||||||
return phone, phone_hash
|
return phone, phone_hash
|
||||||
|
|
||||||
async def sign_in(
|
async def sign_in(
|
||||||
self, phone=None, code=None, *, password=None,
|
self: 'TelegramClient',
|
||||||
bot_token=None, phone_code_hash=None):
|
phone: str = None,
|
||||||
|
code: typing.Union[str, int] = None,
|
||||||
|
*,
|
||||||
|
password: str = None,
|
||||||
|
bot_token: str = None,
|
||||||
|
phone_code_hash: str = None) -> types.User:
|
||||||
"""
|
"""
|
||||||
Starts or completes the sign in process with the given phone number
|
Starts or completes the sign in process with the given phone number
|
||||||
or code that Telegram sent.
|
or code that Telegram sent.
|
||||||
|
@ -304,8 +315,14 @@ class AuthMethods(MessageParseMethods, UserMethods):
|
||||||
|
|
||||||
return self._on_login(result.user)
|
return self._on_login(result.user)
|
||||||
|
|
||||||
async def sign_up(self, code, first_name, last_name='',
|
async def sign_up(
|
||||||
*, phone=None, phone_code_hash=None):
|
self: 'TelegramClient',
|
||||||
|
code: typing.Union[str, int],
|
||||||
|
first_name: str,
|
||||||
|
last_name: str = '',
|
||||||
|
*,
|
||||||
|
phone: str = None,
|
||||||
|
phone_code_hash: str = None) -> types.User:
|
||||||
"""
|
"""
|
||||||
Signs up to Telegram if you don't have an account yet.
|
Signs up to Telegram if you don't have an account yet.
|
||||||
You must call .send_code_request(phone) first.
|
You must call .send_code_request(phone) first.
|
||||||
|
@ -377,7 +394,11 @@ class AuthMethods(MessageParseMethods, UserMethods):
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
async def send_code_request(self, phone, *, force_sms=False):
|
async def send_code_request(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
phone: str,
|
||||||
|
*,
|
||||||
|
force_sms: bool = False) -> types.auth.SentCode:
|
||||||
"""
|
"""
|
||||||
Sends a code request to the specified phone number.
|
Sends a code request to the specified phone number.
|
||||||
|
|
||||||
|
@ -417,7 +438,7 @@ class AuthMethods(MessageParseMethods, UserMethods):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def log_out(self):
|
async def log_out(self: 'TelegramClient') -> bool:
|
||||||
"""
|
"""
|
||||||
Logs out Telegram and deletes the current ``*.session`` file.
|
Logs out Telegram and deletes the current ``*.session`` file.
|
||||||
|
|
||||||
|
@ -439,8 +460,13 @@ class AuthMethods(MessageParseMethods, UserMethods):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def edit_2fa(
|
async def edit_2fa(
|
||||||
self, current_password=None, new_password=None,
|
self: 'TelegramClient',
|
||||||
*, hint='', email=None, email_code_callback=None):
|
current_password: str = None,
|
||||||
|
new_password: str = None,
|
||||||
|
*,
|
||||||
|
hint: str = '',
|
||||||
|
email: str = None,
|
||||||
|
email_code_callback: typing.Callable[[int], str] = None) -> bool:
|
||||||
"""
|
"""
|
||||||
Changes the 2FA settings of the logged in user, according to the
|
Changes the 2FA settings of the logged in user, according to the
|
||||||
passed parameters. Take note of the parameter explanations.
|
passed parameters. Take note of the parameter explanations.
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
|
from .. import hints
|
||||||
from ..tl import types, functions, custom
|
from ..tl import types, functions, custom
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class BotMethods(UserMethods):
|
class BotMethods(UserMethods):
|
||||||
async def inline_query(self, bot, query, *, offset=None, geo_point=None):
|
async def inline_query(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
bot: hints.EntityLike,
|
||||||
|
query: str,
|
||||||
|
*,
|
||||||
|
offset: str = None,
|
||||||
|
geo_point: types.GeoPoint = None) -> custom.InlineResults:
|
||||||
"""
|
"""
|
||||||
Makes the given inline query to the specified bot
|
Makes the given inline query to the specified bot
|
||||||
i.e. ``@vote My New Poll`` would be as follows:
|
i.e. ``@vote My New Poll`` would be as follows:
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
from .updates import UpdateMethods
|
from .updates import UpdateMethods
|
||||||
|
from .. import utils, hints
|
||||||
from ..tl import types, custom
|
from ..tl import types, custom
|
||||||
from .. import utils, events
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class ButtonMethods(UpdateMethods):
|
class ButtonMethods(UpdateMethods):
|
||||||
@staticmethod
|
def build_reply_markup(
|
||||||
def build_reply_markup(buttons, inline_only=False):
|
self: 'TelegramClient',
|
||||||
|
buttons: typing.Optional[hints.MarkupLike],
|
||||||
|
inline_only: bool = False) -> typing.Optional[types.TypeReplyMarkup]:
|
||||||
"""
|
"""
|
||||||
Builds a :tl`ReplyInlineMarkup` or :tl:`ReplyKeyboardMarkup` for
|
Builds a :tl`ReplyInlineMarkup` or :tl:`ReplyKeyboardMarkup` for
|
||||||
the given buttons, or does nothing if either no buttons are
|
the given buttons, or does nothing if either no buttons are
|
||||||
|
|
|
@ -3,13 +3,17 @@ import itertools
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import helpers, utils
|
from .. import helpers, utils, hints
|
||||||
from ..requestiter import RequestIter
|
from ..requestiter import RequestIter
|
||||||
from ..tl import types, functions, custom
|
from ..tl import types, functions, custom
|
||||||
|
|
||||||
_MAX_PARTICIPANTS_CHUNK_SIZE = 200
|
_MAX_PARTICIPANTS_CHUNK_SIZE = 200
|
||||||
_MAX_ADMIN_LOG_CHUNK_SIZE = 100
|
_MAX_ADMIN_LOG_CHUNK_SIZE = 100
|
||||||
|
|
||||||
|
import typing
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class _ChatAction:
|
class _ChatAction:
|
||||||
_str_mapping = {
|
_str_mapping = {
|
||||||
|
@ -275,9 +279,13 @@ class ChatMethods(UserMethods):
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
def iter_participants(
|
def iter_participants(
|
||||||
self, entity, limit=None, *, search='',
|
self: 'TelegramClient',
|
||||||
filter=None, aggressive=False
|
entity: hints.EntityLike,
|
||||||
):
|
limit: float = None,
|
||||||
|
*,
|
||||||
|
search: str = '',
|
||||||
|
filter: types.TypeChannelParticipantsFilter = None,
|
||||||
|
aggressive: bool = False) -> _ParticipantsIter:
|
||||||
"""
|
"""
|
||||||
Iterator over the participants belonging to the specified chat.
|
Iterator over the participants belonging to the specified chat.
|
||||||
|
|
||||||
|
@ -330,7 +338,10 @@ class ChatMethods(UserMethods):
|
||||||
aggressive=aggressive
|
aggressive=aggressive
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_participants(self, *args, **kwargs):
|
async def get_participants(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
*args,
|
||||||
|
**kwargs) -> hints.TotalList:
|
||||||
"""
|
"""
|
||||||
Same as `iter_participants`, but returns a
|
Same as `iter_participants`, but returns a
|
||||||
`TotalList <telethon.helpers.TotalList>` instead.
|
`TotalList <telethon.helpers.TotalList>` instead.
|
||||||
|
@ -338,10 +349,28 @@ class ChatMethods(UserMethods):
|
||||||
return await self.iter_participants(*args, **kwargs).collect()
|
return await self.iter_participants(*args, **kwargs).collect()
|
||||||
|
|
||||||
def iter_admin_log(
|
def iter_admin_log(
|
||||||
self, entity, limit=None, *, max_id=0, min_id=0, search=None,
|
self: 'TelegramClient',
|
||||||
admins=None, join=None, leave=None, invite=None, restrict=None,
|
entity: hints.EntityLike,
|
||||||
unrestrict=None, ban=None, unban=None, promote=None, demote=None,
|
limit: float = None,
|
||||||
info=None, settings=None, pinned=None, edit=None, delete=None):
|
*,
|
||||||
|
max_id: int = 0,
|
||||||
|
min_id: int = 0,
|
||||||
|
search: str = None,
|
||||||
|
admins: hints.EntitiesLike = None,
|
||||||
|
join: bool = None,
|
||||||
|
leave: bool = None,
|
||||||
|
invite: bool = None,
|
||||||
|
restrict: bool = None,
|
||||||
|
unrestrict: bool = None,
|
||||||
|
ban: bool = None,
|
||||||
|
unban: bool = None,
|
||||||
|
promote: bool = None,
|
||||||
|
demote: bool = None,
|
||||||
|
info: bool = None,
|
||||||
|
settings: bool = None,
|
||||||
|
pinned: bool = None,
|
||||||
|
edit: bool = None,
|
||||||
|
delete: bool = None) -> _AdminLogIter:
|
||||||
"""
|
"""
|
||||||
Iterator over the admin log for the specified channel.
|
Iterator over the admin log for the specified channel.
|
||||||
|
|
||||||
|
@ -453,13 +482,22 @@ class ChatMethods(UserMethods):
|
||||||
delete=delete
|
delete=delete
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_admin_log(self, *args, **kwargs):
|
async def get_admin_log(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
*args,
|
||||||
|
**kwargs) -> hints.TotalList:
|
||||||
"""
|
"""
|
||||||
Same as `iter_admin_log`, but returns a ``list`` instead.
|
Same as `iter_admin_log`, but returns a ``list`` instead.
|
||||||
"""
|
"""
|
||||||
return await self.iter_admin_log(*args, **kwargs).collect()
|
return await self.iter_admin_log(*args, **kwargs).collect()
|
||||||
|
|
||||||
def action(self, entity, action, *, delay=4, auto_cancel=True):
|
def action(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
entity: hints.EntityLike,
|
||||||
|
action: typing.Union[str, types.TypeSendMessageAction],
|
||||||
|
*,
|
||||||
|
delay: float = 4,
|
||||||
|
auto_cancel: bool = True) -> typing.Union[_ChatAction, typing.Coroutine]:
|
||||||
"""
|
"""
|
||||||
Returns a context-manager object to represent a "chat action".
|
Returns a context-manager object to represent a "chat action".
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import itertools
|
import itertools
|
||||||
|
import typing
|
||||||
|
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import utils
|
from .. import utils, hints
|
||||||
from ..requestiter import RequestIter
|
from ..requestiter import RequestIter
|
||||||
from ..tl import types, functions, custom
|
from ..tl import types, functions, custom
|
||||||
|
|
||||||
_MAX_CHUNK_SIZE = 100
|
_MAX_CHUNK_SIZE = 100
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class _DialogsIter(RequestIter):
|
class _DialogsIter(RequestIter):
|
||||||
async def _init(
|
async def _init(
|
||||||
|
@ -98,9 +102,14 @@ class DialogMethods(UserMethods):
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
def iter_dialogs(
|
def iter_dialogs(
|
||||||
self, limit=None, *, offset_date=None, offset_id=0,
|
self: 'TelegramClient',
|
||||||
offset_peer=types.InputPeerEmpty(), ignore_migrated=False
|
limit: float = None,
|
||||||
):
|
*,
|
||||||
|
offset_date: hints.DateLike = None,
|
||||||
|
offset_id: int = 0,
|
||||||
|
offset_peer: hints.EntityLike = types.InputPeerEmpty(),
|
||||||
|
ignore_migrated: bool = False
|
||||||
|
) -> _DialogsIter:
|
||||||
"""
|
"""
|
||||||
Returns an iterator over the dialogs, yielding 'limit' at most.
|
Returns an iterator over the dialogs, yielding 'limit' at most.
|
||||||
Dialogs are the open "chats" or conversations with other people,
|
Dialogs are the open "chats" or conversations with other people,
|
||||||
|
@ -141,14 +150,14 @@ class DialogMethods(UserMethods):
|
||||||
ignore_migrated=ignore_migrated
|
ignore_migrated=ignore_migrated
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_dialogs(self, *args, **kwargs):
|
async def get_dialogs(self: 'TelegramClient', *args, **kwargs) -> hints.TotalList:
|
||||||
"""
|
"""
|
||||||
Same as `iter_dialogs`, but returns a
|
Same as `iter_dialogs`, but returns a
|
||||||
`TotalList <telethon.helpers.TotalList>` instead.
|
`TotalList <telethon.helpers.TotalList>` instead.
|
||||||
"""
|
"""
|
||||||
return await self.iter_dialogs(*args, **kwargs).collect()
|
return await self.iter_dialogs(*args, **kwargs).collect()
|
||||||
|
|
||||||
def iter_drafts(self):
|
def iter_drafts(self: 'TelegramClient') -> _DraftsIter:
|
||||||
"""
|
"""
|
||||||
Iterator over all open draft messages.
|
Iterator over all open draft messages.
|
||||||
|
|
||||||
|
@ -160,16 +169,21 @@ class DialogMethods(UserMethods):
|
||||||
# TODO Passing a limit here makes no sense
|
# TODO Passing a limit here makes no sense
|
||||||
return _DraftsIter(self, None)
|
return _DraftsIter(self, None)
|
||||||
|
|
||||||
async def get_drafts(self):
|
async def get_drafts(self: 'TelegramClient') -> hints.TotalList:
|
||||||
"""
|
"""
|
||||||
Same as :meth:`iter_drafts`, but returns a list instead.
|
Same as :meth:`iter_drafts`, but returns a list instead.
|
||||||
"""
|
"""
|
||||||
return await self.iter_drafts().collect()
|
return await self.iter_drafts().collect()
|
||||||
|
|
||||||
def conversation(
|
def conversation(
|
||||||
self, entity,
|
self: 'TelegramClient',
|
||||||
*, timeout=60, total_timeout=None, max_messages=100,
|
entity: hints.EntityLike,
|
||||||
exclusive=True, replies_are_responses=True):
|
*,
|
||||||
|
timeout: float = 60,
|
||||||
|
total_timeout: float = None,
|
||||||
|
max_messages: int = 100,
|
||||||
|
exclusive: bool = True,
|
||||||
|
replies_are_responses: bool = True) -> custom.Conversation:
|
||||||
"""
|
"""
|
||||||
Creates a `Conversation <telethon.tl.custom.conversation.Conversation>`
|
Creates a `Conversation <telethon.tl.custom.conversation.Conversation>`
|
||||||
with the given entity so you can easily send messages and await for
|
with the given entity so you can easily send messages and await for
|
||||||
|
|
|
@ -2,9 +2,10 @@ import datetime
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import typing
|
||||||
|
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import utils, helpers, errors
|
from .. import utils, helpers, errors, hints
|
||||||
from ..tl import TLObject, types, functions
|
from ..tl import TLObject, types, functions
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -12,13 +13,20 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
aiohttp = None
|
aiohttp = None
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class DownloadMethods(UserMethods):
|
class DownloadMethods(UserMethods):
|
||||||
|
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
async def download_profile_photo(
|
async def download_profile_photo(
|
||||||
self, entity, file=None, *, download_big=True):
|
self: 'TelegramClient',
|
||||||
|
entity: hints.EntityLike,
|
||||||
|
file: hints.FileLike = None,
|
||||||
|
*,
|
||||||
|
download_big: bool = True) -> typing.Optional[str]:
|
||||||
"""
|
"""
|
||||||
Downloads the profile photo of the given entity (user/chat/channel).
|
Downloads the profile photo of the given entity (user/chat/channel).
|
||||||
|
|
||||||
|
@ -118,8 +126,13 @@ class DownloadMethods(UserMethods):
|
||||||
# Until there's a report for chats, no need to.
|
# Until there's a report for chats, no need to.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def download_media(self, message, file=None,
|
async def download_media(
|
||||||
*, thumb=None, progress_callback=None):
|
self: 'TelegramClient',
|
||||||
|
message: hints.MessageLike,
|
||||||
|
file: hints.FileLike = None,
|
||||||
|
*,
|
||||||
|
thumb: hints.FileLike = None,
|
||||||
|
progress_callback: hints.ProgressCallback = None) -> typing.Optional[str]:
|
||||||
"""
|
"""
|
||||||
Downloads the given media, or the media from a specified Message.
|
Downloads the given media, or the media from a specified Message.
|
||||||
|
|
||||||
|
@ -194,8 +207,14 @@ class DownloadMethods(UserMethods):
|
||||||
)
|
)
|
||||||
|
|
||||||
async def download_file(
|
async def download_file(
|
||||||
self, input_location, file=None, *, part_size_kb=None,
|
self: 'TelegramClient',
|
||||||
file_size=None, progress_callback=None, dc_id=None):
|
input_location: hints.FileLike,
|
||||||
|
file: hints.OutFileLike = None,
|
||||||
|
*,
|
||||||
|
part_size_kb: float = None,
|
||||||
|
file_size: int = None,
|
||||||
|
progress_callback: hints.ProgressCallback = None,
|
||||||
|
dc_id: int = None) -> None:
|
||||||
"""
|
"""
|
||||||
Downloads the given input location to a file.
|
Downloads the given input location to a file.
|
||||||
|
|
||||||
|
@ -337,8 +356,7 @@ class DownloadMethods(UserMethods):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
def _download_cached_photo_size(self: 'TelegramClient', size, file):
|
||||||
def _download_cached_photo_size(size, file):
|
|
||||||
# No need to download anything, simply write the bytes
|
# No need to download anything, simply write the bytes
|
||||||
if file is bytes:
|
if file is bytes:
|
||||||
return size.bytes
|
return size.bytes
|
||||||
|
@ -357,7 +375,7 @@ class DownloadMethods(UserMethods):
|
||||||
f.close()
|
f.close()
|
||||||
return file
|
return file
|
||||||
|
|
||||||
async def _download_photo(self, photo, file, date, thumb, progress_callback):
|
async def _download_photo(self: 'TelegramClient', photo, file, date, thumb, progress_callback):
|
||||||
"""Specialized version of .download_media() for photos"""
|
"""Specialized version of .download_media() for photos"""
|
||||||
# Determine the photo and its largest size
|
# Determine the photo and its largest size
|
||||||
if isinstance(photo, types.MessageMediaPhoto):
|
if isinstance(photo, types.MessageMediaPhoto):
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
|
import typing
|
||||||
|
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import utils
|
from .. import utils
|
||||||
from ..tl import types
|
from ..tl import types
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class MessageParseMethods(UserMethods):
|
class MessageParseMethods(UserMethods):
|
||||||
|
|
||||||
# region Public properties
|
# region Public properties
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parse_mode(self):
|
def parse_mode(self: 'TelegramClient'):
|
||||||
"""
|
"""
|
||||||
This property is the default parse mode used when sending messages.
|
This property is the default parse mode used when sending messages.
|
||||||
Defaults to `telethon.extensions.markdown`. It will always
|
Defaults to `telethon.extensions.markdown`. It will always
|
||||||
|
@ -38,14 +42,14 @@ class MessageParseMethods(UserMethods):
|
||||||
return self._parse_mode
|
return self._parse_mode
|
||||||
|
|
||||||
@parse_mode.setter
|
@parse_mode.setter
|
||||||
def parse_mode(self, mode):
|
def parse_mode(self: 'TelegramClient', mode: str):
|
||||||
self._parse_mode = utils.sanitize_parse_mode(mode)
|
self._parse_mode = utils.sanitize_parse_mode(mode)
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Private methods
|
# region Private methods
|
||||||
|
|
||||||
async def _replace_with_mention(self, entities, i, user):
|
async def _replace_with_mention(self: 'TelegramClient', entities, i, user):
|
||||||
"""
|
"""
|
||||||
Helper method to replace ``entities[i]`` to mention ``user``,
|
Helper method to replace ``entities[i]`` to mention ``user``,
|
||||||
or do nothing if it can't be found.
|
or do nothing if it can't be found.
|
||||||
|
@ -59,7 +63,7 @@ class MessageParseMethods(UserMethods):
|
||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def _parse_message_text(self, message, parse_mode):
|
async def _parse_message_text(self: 'TelegramClient', message, parse_mode):
|
||||||
"""
|
"""
|
||||||
Returns a (parsed message, entities) tuple depending on ``parse_mode``.
|
Returns a (parsed message, entities) tuple depending on ``parse_mode``.
|
||||||
"""
|
"""
|
||||||
|
@ -89,7 +93,7 @@ class MessageParseMethods(UserMethods):
|
||||||
|
|
||||||
return message, msg_entities
|
return message, msg_entities
|
||||||
|
|
||||||
def _get_response_message(self, request, result, input_chat):
|
def _get_response_message(self: 'TelegramClient', request, result, input_chat):
|
||||||
"""
|
"""
|
||||||
Extracts the response message known a request and Update result.
|
Extracts the response message known a request and Update result.
|
||||||
The request may also be the ID of the message to match.
|
The request may also be the ID of the message to match.
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
import itertools
|
import itertools
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from .buttons import ButtonMethods
|
||||||
from .messageparse import MessageParseMethods
|
from .messageparse import MessageParseMethods
|
||||||
from .uploads import UploadMethods
|
from .uploads import UploadMethods
|
||||||
from .buttons import ButtonMethods
|
from .. import utils, errors, hints
|
||||||
from .. import utils, errors
|
|
||||||
from ..tl import types, functions
|
|
||||||
from ..requestiter import RequestIter
|
from ..requestiter import RequestIter
|
||||||
|
from ..tl import types, functions
|
||||||
|
|
||||||
_MAX_CHUNK_SIZE = 100
|
_MAX_CHUNK_SIZE = 100
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class _MessagesIter(RequestIter):
|
class _MessagesIter(RequestIter):
|
||||||
"""
|
"""
|
||||||
|
@ -293,10 +297,22 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
# region Message retrieval
|
# region Message retrieval
|
||||||
|
|
||||||
def iter_messages(
|
def iter_messages(
|
||||||
self, entity, limit=None, *, offset_date=None, offset_id=0,
|
self: 'TelegramClient',
|
||||||
max_id=0, min_id=0, add_offset=0, search=None, filter=None,
|
entity: hints.EntityLike,
|
||||||
from_user=None, wait_time=None, ids=None, reverse=False
|
limit: float = None,
|
||||||
):
|
*,
|
||||||
|
offset_date: hints.DateLike = None,
|
||||||
|
offset_id: int = 0,
|
||||||
|
max_id: int = 0,
|
||||||
|
min_id: int = 0,
|
||||||
|
add_offset: int = 0,
|
||||||
|
search: str = None,
|
||||||
|
filter: typing.Union[types.TypeMessagesFilter, typing.Type[types.TypeMessagesFilter]] = None,
|
||||||
|
from_user: hints.EntityLike = None,
|
||||||
|
wait_time: float = None,
|
||||||
|
ids: typing.Union[int, typing.Sequence[int]] = None,
|
||||||
|
reverse: bool = False
|
||||||
|
) -> typing.Union[_MessagesIter, _IDsIter]:
|
||||||
"""
|
"""
|
||||||
Iterator over the message history for the specified entity.
|
Iterator over the message history for the specified entity.
|
||||||
If either `search`, `filter` or `from_user` are provided,
|
If either `search`, `filter` or `from_user` are provided,
|
||||||
|
@ -417,7 +433,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
search=search
|
search=search
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_messages(self, *args, **kwargs):
|
async def get_messages(self: 'TelegramClient', *args, **kwargs) -> hints.TotalList:
|
||||||
"""
|
"""
|
||||||
Same as `iter_messages`, but returns a
|
Same as `iter_messages`, but returns a
|
||||||
`TotalList <telethon.helpers.TotalList>` instead.
|
`TotalList <telethon.helpers.TotalList>` instead.
|
||||||
|
@ -457,10 +473,18 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
# region Message sending/editing/deleting
|
# region Message sending/editing/deleting
|
||||||
|
|
||||||
async def send_message(
|
async def send_message(
|
||||||
self, entity, message='', *, reply_to=None,
|
self: 'TelegramClient',
|
||||||
parse_mode=(), link_preview=True, file=None,
|
entity: hints.EntityLike,
|
||||||
force_document=False, clear_draft=False, buttons=None,
|
message: hints.MessageLike = '',
|
||||||
silent=None):
|
*,
|
||||||
|
reply_to: typing.Union[int, types.Message] = None,
|
||||||
|
parse_mode: typing.Optional[str] = (),
|
||||||
|
link_preview: bool = True,
|
||||||
|
file: hints.FileLike = None,
|
||||||
|
force_document: bool = False,
|
||||||
|
clear_draft: bool = False,
|
||||||
|
buttons: hints.MarkupLike = None,
|
||||||
|
silent: bool = None) -> types.Message:
|
||||||
"""
|
"""
|
||||||
Sends the given message to the specified entity (user/chat/channel).
|
Sends the given message to the specified entity (user/chat/channel).
|
||||||
|
|
||||||
|
@ -609,8 +633,14 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
|
|
||||||
return self._get_response_message(request, result, entity)
|
return self._get_response_message(request, result, entity)
|
||||||
|
|
||||||
async def forward_messages(self, entity, messages, from_peer=None,
|
async def forward_messages(
|
||||||
*, silent=None, as_album=None):
|
self: 'TelegramClient',
|
||||||
|
entity: hints.EntityLike,
|
||||||
|
messages: typing.Union[hints.MessageIDLike, typing.Sequence[hints.MessageIDLike]],
|
||||||
|
from_peer: hints.EntityLike = None,
|
||||||
|
*,
|
||||||
|
silent: bool = None,
|
||||||
|
as_album: bool = None) -> typing.Sequence[types.Message]:
|
||||||
"""
|
"""
|
||||||
Forwards the given message(s) to the specified entity.
|
Forwards the given message(s) to the specified entity.
|
||||||
|
|
||||||
|
@ -719,9 +749,15 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
return sent[0] if single else sent
|
return sent[0] if single else sent
|
||||||
|
|
||||||
async def edit_message(
|
async def edit_message(
|
||||||
self, entity, message=None, text=None,
|
self: 'TelegramClient',
|
||||||
*, parse_mode=(), link_preview=True, file=None,
|
entity: typing.Union[hints.EntityLike, types.Message],
|
||||||
buttons=None):
|
message: hints.MessageLike = None,
|
||||||
|
text: str = None,
|
||||||
|
*,
|
||||||
|
parse_mode: str = (),
|
||||||
|
link_preview: bool = True,
|
||||||
|
file: hints.FileLike = None,
|
||||||
|
buttons: hints.MarkupLike = None) -> types.Message:
|
||||||
"""
|
"""
|
||||||
Edits the given message ID (to change its contents or disable preview).
|
Edits the given message ID (to change its contents or disable preview).
|
||||||
|
|
||||||
|
@ -824,7 +860,12 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
await self._cache_media(msg, file, file_handle, image=image)
|
await self._cache_media(msg, file, file_handle, image=image)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
async def delete_messages(self, entity, message_ids, *, revoke=True):
|
async def delete_messages(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
entity: hints.EntityLike,
|
||||||
|
message_ids: typing.Union[hints.MessageIDLike, typing.Sequence[hints.MessageIDLike]],
|
||||||
|
*,
|
||||||
|
revoke: bool = True) -> typing.Sequence[types.messages.AffectedMessages]:
|
||||||
"""
|
"""
|
||||||
Deletes a message from a chat, optionally "for everyone".
|
Deletes a message from a chat, optionally "for everyone".
|
||||||
|
|
||||||
|
@ -877,7 +918,12 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
# region Miscellaneous
|
# region Miscellaneous
|
||||||
|
|
||||||
async def send_read_acknowledge(
|
async def send_read_acknowledge(
|
||||||
self, entity, message=None, *, max_id=None, clear_mentions=False):
|
self: 'TelegramClient',
|
||||||
|
entity: hints.EntityLike,
|
||||||
|
message: typing.Union[hints.MessageIDLike, typing.Sequence[hints.MessageIDLike]] = None,
|
||||||
|
*,
|
||||||
|
max_id: int = None,
|
||||||
|
clear_mentions: bool = False) -> bool:
|
||||||
"""
|
"""
|
||||||
Sends a "read acknowledge" (i.e., notifying the given peer that we've
|
Sends a "read acknowledge" (i.e., notifying the given peer that we've
|
||||||
read their messages, also known as the "double check").
|
read their messages, also known as the "double check").
|
||||||
|
@ -924,7 +970,7 @@ class MessageMethods(UploadMethods, ButtonMethods, MessageParseMethods):
|
||||||
if max_id is not None:
|
if max_id is not None:
|
||||||
if isinstance(entity, types.InputPeerChannel):
|
if isinstance(entity, types.InputPeerChannel):
|
||||||
return await self(functions.channels.ReadHistoryRequest(
|
return await self(functions.channels.ReadHistoryRequest(
|
||||||
entity, max_id=max_id))
|
utils.get_input_channel(entity), max_id=max_id))
|
||||||
else:
|
else:
|
||||||
return await self(functions.messages.ReadHistoryRequest(
|
return await self(functions.messages.ReadHistoryRequest(
|
||||||
entity, max_id=max_id))
|
entity, max_id=max_id))
|
||||||
|
|
|
@ -3,23 +3,26 @@ import asyncio
|
||||||
import logging
|
import logging
|
||||||
import platform
|
import platform
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timezone
|
import typing
|
||||||
|
|
||||||
from .. import version, helpers, __name__ as __base_name__
|
from .. import version, helpers, __name__ as __base_name__
|
||||||
from ..crypto import rsa
|
from ..crypto import rsa
|
||||||
|
from ..entitycache import EntityCache
|
||||||
from ..extensions import markdown
|
from ..extensions import markdown
|
||||||
from ..network import MTProtoSender, ConnectionTcpFull, TcpMTProxy
|
from ..network import MTProtoSender, Connection, ConnectionTcpFull, TcpMTProxy
|
||||||
from ..sessions import Session, SQLiteSession, MemorySession
|
from ..sessions import Session, SQLiteSession, MemorySession
|
||||||
|
from ..statecache import StateCache
|
||||||
from ..tl import TLObject, functions, types
|
from ..tl import TLObject, functions, types
|
||||||
from ..tl.alltlobjects import LAYER
|
from ..tl.alltlobjects import LAYER
|
||||||
from ..entitycache import EntityCache
|
|
||||||
from ..statecache import StateCache
|
|
||||||
|
|
||||||
DEFAULT_DC_ID = 4
|
DEFAULT_DC_ID = 4
|
||||||
DEFAULT_IPV4_IP = '149.154.167.51'
|
DEFAULT_IPV4_IP = '149.154.167.51'
|
||||||
DEFAULT_IPV6_IP = '[2001:67c:4e8:f002::a]'
|
DEFAULT_IPV6_IP = '[2001:67c:4e8:f002::a]'
|
||||||
DEFAULT_PORT = 443
|
DEFAULT_PORT = 443
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
__default_log__ = logging.getLogger(__base_name__)
|
__default_log__ = logging.getLogger(__base_name__)
|
||||||
__default_log__.addHandler(logging.NullHandler())
|
__default_log__.addHandler(logging.NullHandler())
|
||||||
|
|
||||||
|
@ -159,25 +162,29 @@ class TelegramBaseClient(abc.ABC):
|
||||||
|
|
||||||
# region Initialization
|
# region Initialization
|
||||||
|
|
||||||
def __init__(self, session, api_id, api_hash,
|
def __init__(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
session: typing.Union[str, Session],
|
||||||
|
api_id: int,
|
||||||
|
api_hash: str,
|
||||||
*,
|
*,
|
||||||
connection=ConnectionTcpFull,
|
connection: typing.Type[Connection] = ConnectionTcpFull,
|
||||||
use_ipv6=False,
|
use_ipv6: bool = False,
|
||||||
proxy=None,
|
proxy: typing.Union[tuple, dict] = None,
|
||||||
timeout=10,
|
timeout: int = 10,
|
||||||
request_retries=5,
|
request_retries: int = 5,
|
||||||
connection_retries=5,
|
connection_retries: int =5,
|
||||||
retry_delay=1,
|
retry_delay: int =1,
|
||||||
auto_reconnect=True,
|
auto_reconnect: bool = True,
|
||||||
sequential_updates=False,
|
sequential_updates: bool = False,
|
||||||
flood_sleep_threshold=60,
|
flood_sleep_threshold: int = 60,
|
||||||
device_model=None,
|
device_model: str = None,
|
||||||
system_version=None,
|
system_version: str = None,
|
||||||
app_version=None,
|
app_version: str = None,
|
||||||
lang_code='en',
|
lang_code: str = 'en',
|
||||||
system_lang_code='en',
|
system_lang_code: str = 'en',
|
||||||
loop=None,
|
loop: asyncio.AbstractEventLoop = None,
|
||||||
base_logger=None):
|
base_logger: typing.Union[str, logging.Logger] = None):
|
||||||
if not api_id or not api_hash:
|
if not api_id or not api_hash:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Your API ID or Hash cannot be empty or None. "
|
"Your API ID or Hash cannot be empty or None. "
|
||||||
|
@ -334,11 +341,11 @@ class TelegramBaseClient(abc.ABC):
|
||||||
# region Properties
|
# region Properties
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def loop(self):
|
def loop(self: 'TelegramClient') -> asyncio.AbstractEventLoop:
|
||||||
return self._loop
|
return self._loop
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def disconnected(self):
|
def disconnected(self: 'TelegramClient') -> asyncio.Future:
|
||||||
"""
|
"""
|
||||||
Future that resolves when the connection to Telegram
|
Future that resolves when the connection to Telegram
|
||||||
ends, either by user action or in the background.
|
ends, either by user action or in the background.
|
||||||
|
@ -349,7 +356,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
|
|
||||||
# region Connecting
|
# region Connecting
|
||||||
|
|
||||||
async def connect(self):
|
async def connect(self: 'TelegramClient') -> None:
|
||||||
"""
|
"""
|
||||||
Connects to Telegram.
|
Connects to Telegram.
|
||||||
"""
|
"""
|
||||||
|
@ -369,14 +376,14 @@ class TelegramBaseClient(abc.ABC):
|
||||||
|
|
||||||
self._updates_handle = self._loop.create_task(self._update_loop())
|
self._updates_handle = self._loop.create_task(self._update_loop())
|
||||||
|
|
||||||
def is_connected(self):
|
def is_connected(self: 'TelegramClient') -> bool:
|
||||||
"""
|
"""
|
||||||
Returns ``True`` if the user has connected.
|
Returns ``True`` if the user has connected.
|
||||||
"""
|
"""
|
||||||
sender = getattr(self, '_sender', None)
|
sender = getattr(self, '_sender', None)
|
||||||
return sender and sender.is_connected()
|
return sender and sender.is_connected()
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self: 'TelegramClient'):
|
||||||
"""
|
"""
|
||||||
Disconnects from Telegram.
|
Disconnects from Telegram.
|
||||||
|
|
||||||
|
@ -389,7 +396,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
else:
|
else:
|
||||||
self._loop.run_until_complete(self._disconnect_coro())
|
self._loop.run_until_complete(self._disconnect_coro())
|
||||||
|
|
||||||
async def _disconnect_coro(self):
|
async def _disconnect_coro(self: 'TelegramClient'):
|
||||||
await self._disconnect()
|
await self._disconnect()
|
||||||
|
|
||||||
pts, date = self._state_cache[None]
|
pts, date = self._state_cache[None]
|
||||||
|
@ -403,7 +410,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
|
|
||||||
self.session.close()
|
self.session.close()
|
||||||
|
|
||||||
async def _disconnect(self):
|
async def _disconnect(self: 'TelegramClient'):
|
||||||
"""
|
"""
|
||||||
Disconnect only, without closing the session. Used in reconnections
|
Disconnect only, without closing the session. Used in reconnections
|
||||||
to different data centers, where we don't want to close the session
|
to different data centers, where we don't want to close the session
|
||||||
|
@ -414,7 +421,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
await helpers._cancel(self._log[__name__],
|
await helpers._cancel(self._log[__name__],
|
||||||
updates_handle=self._updates_handle)
|
updates_handle=self._updates_handle)
|
||||||
|
|
||||||
async def _switch_dc(self, new_dc):
|
async def _switch_dc(self: 'TelegramClient', new_dc):
|
||||||
"""
|
"""
|
||||||
Permanently switches the current connection to the new data center.
|
Permanently switches the current connection to the new data center.
|
||||||
"""
|
"""
|
||||||
|
@ -430,7 +437,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
await self._disconnect()
|
await self._disconnect()
|
||||||
return await self.connect()
|
return await self.connect()
|
||||||
|
|
||||||
def _auth_key_callback(self, auth_key):
|
def _auth_key_callback(self: 'TelegramClient', auth_key):
|
||||||
"""
|
"""
|
||||||
Callback from the sender whenever it needed to generate a
|
Callback from the sender whenever it needed to generate a
|
||||||
new authorization key. This means we are not authorized.
|
new authorization key. This means we are not authorized.
|
||||||
|
@ -442,7 +449,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
|
|
||||||
# region Working with different connections/Data Centers
|
# region Working with different connections/Data Centers
|
||||||
|
|
||||||
async def _get_dc(self, dc_id, cdn=False):
|
async def _get_dc(self: 'TelegramClient', dc_id, cdn=False):
|
||||||
"""Gets the Data Center (DC) associated to 'dc_id'"""
|
"""Gets the Data Center (DC) associated to 'dc_id'"""
|
||||||
cls = self.__class__
|
cls = self.__class__
|
||||||
if not cls._config:
|
if not cls._config:
|
||||||
|
@ -459,7 +466,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
and bool(dc.ipv6) == self._use_ipv6 and bool(dc.cdn) == cdn
|
and bool(dc.ipv6) == self._use_ipv6 and bool(dc.cdn) == cdn
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _create_exported_sender(self, dc_id):
|
async def _create_exported_sender(self: 'TelegramClient', dc_id):
|
||||||
"""
|
"""
|
||||||
Creates a new exported `MTProtoSender` for the given `dc_id` and
|
Creates a new exported `MTProtoSender` for the given `dc_id` and
|
||||||
returns it. This method should be used by `_borrow_exported_sender`.
|
returns it. This method should be used by `_borrow_exported_sender`.
|
||||||
|
@ -489,7 +496,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
await sender.send(req)
|
await sender.send(req)
|
||||||
return sender
|
return sender
|
||||||
|
|
||||||
async def _borrow_exported_sender(self, dc_id):
|
async def _borrow_exported_sender(self: 'TelegramClient', dc_id):
|
||||||
"""
|
"""
|
||||||
Borrows a connected `MTProtoSender` for the given `dc_id`.
|
Borrows a connected `MTProtoSender` for the given `dc_id`.
|
||||||
If it's not cached, creates a new one if it doesn't exist yet,
|
If it's not cached, creates a new one if it doesn't exist yet,
|
||||||
|
@ -517,7 +524,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
|
|
||||||
return sender
|
return sender
|
||||||
|
|
||||||
async def _return_exported_sender(self, sender):
|
async def _return_exported_sender(self: 'TelegramClient', sender):
|
||||||
"""
|
"""
|
||||||
Returns a borrowed exported sender. If all borrows have
|
Returns a borrowed exported sender. If all borrows have
|
||||||
been returned, the sender is cleanly disconnected.
|
been returned, the sender is cleanly disconnected.
|
||||||
|
@ -532,7 +539,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
'Disconnecting borrowed sender for DC %d', dc_id)
|
'Disconnecting borrowed sender for DC %d', dc_id)
|
||||||
await sender.disconnect()
|
await sender.disconnect()
|
||||||
|
|
||||||
async def _get_cdn_client(self, cdn_redirect):
|
async def _get_cdn_client(self: 'TelegramClient', cdn_redirect):
|
||||||
"""Similar to ._borrow_exported_client, but for CDNs"""
|
"""Similar to ._borrow_exported_client, but for CDNs"""
|
||||||
# TODO Implement
|
# TODO Implement
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -563,7 +570,7 @@ class TelegramBaseClient(abc.ABC):
|
||||||
# region Invoking Telegram requests
|
# region Invoking Telegram requests
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def __call__(self, request, ordered=False):
|
def __call__(self: 'TelegramClient', request, ordered=False):
|
||||||
"""
|
"""
|
||||||
Invokes (sends) one or more MTProtoRequests and returns (receives)
|
Invokes (sends) one or more MTProtoRequests and returns (receives)
|
||||||
their result.
|
their result.
|
||||||
|
@ -584,15 +591,15 @@ class TelegramBaseClient(abc.ABC):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def _handle_update(self, update):
|
def _handle_update(self: 'TelegramClient', update):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def _update_loop(self):
|
def _update_loop(self: 'TelegramClient'):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
async def _handle_auto_reconnect(self):
|
async def _handle_auto_reconnect(self: 'TelegramClient'):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
|
@ -2,20 +2,22 @@ import asyncio
|
||||||
import itertools
|
import itertools
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
import datetime
|
import typing
|
||||||
|
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import events, utils, errors
|
from .. import events, utils, errors
|
||||||
|
from ..events.common import EventBuilder, EventCommon
|
||||||
from ..tl import types, functions
|
from ..tl import types, functions
|
||||||
from ..events.common import EventCommon
|
|
||||||
from ..statecache import StateCache
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class UpdateMethods(UserMethods):
|
class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
async def _run_until_disconnected(self):
|
async def _run_until_disconnected(self: 'TelegramClient'):
|
||||||
try:
|
try:
|
||||||
await self.disconnected
|
await self.disconnected
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
@ -23,7 +25,7 @@ class UpdateMethods(UserMethods):
|
||||||
finally:
|
finally:
|
||||||
await self.disconnect()
|
await self.disconnect()
|
||||||
|
|
||||||
def run_until_disconnected(self):
|
def run_until_disconnected(self: 'TelegramClient'):
|
||||||
"""
|
"""
|
||||||
Runs the event loop until `disconnect` is called or if an error
|
Runs the event loop until `disconnect` is called or if an error
|
||||||
while connecting/sending/receiving occurs in the background. In
|
while connecting/sending/receiving occurs in the background. In
|
||||||
|
@ -43,7 +45,7 @@ class UpdateMethods(UserMethods):
|
||||||
# No loop.run_until_complete; it's already syncified
|
# No loop.run_until_complete; it's already syncified
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
def on(self, event):
|
def on(self: 'TelegramClient', event: EventBuilder):
|
||||||
"""
|
"""
|
||||||
Decorator helper method around `add_event_handler`. Example:
|
Decorator helper method around `add_event_handler`. Example:
|
||||||
|
|
||||||
|
@ -67,7 +69,10 @@ class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
def add_event_handler(self, callback, event=None):
|
def add_event_handler(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
callback: callable,
|
||||||
|
event: EventBuilder = None):
|
||||||
"""
|
"""
|
||||||
Registers the given callback to be called on the specified event.
|
Registers the given callback to be called on the specified event.
|
||||||
|
|
||||||
|
@ -100,7 +105,10 @@ class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
self._event_builders.append((event, callback))
|
self._event_builders.append((event, callback))
|
||||||
|
|
||||||
def remove_event_handler(self, callback, event=None):
|
def remove_event_handler(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
callback: callable,
|
||||||
|
event: EventBuilder = None) -> int:
|
||||||
"""
|
"""
|
||||||
Inverse operation of :meth:`add_event_handler`.
|
Inverse operation of :meth:`add_event_handler`.
|
||||||
|
|
||||||
|
@ -121,14 +129,15 @@ class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
return found
|
return found
|
||||||
|
|
||||||
def list_event_handlers(self):
|
def list_event_handlers(self: 'TelegramClient')\
|
||||||
|
-> typing.Sequence[typing.Tuple[callable, EventBuilder]]:
|
||||||
"""
|
"""
|
||||||
Lists all added event handlers, returning a list of pairs
|
Lists all added event handlers, returning a list of pairs
|
||||||
consisting of (callback, event).
|
consisting of (callback, event).
|
||||||
"""
|
"""
|
||||||
return [(callback, event) for event, callback in self._event_builders]
|
return [(callback, event) for event, callback in self._event_builders]
|
||||||
|
|
||||||
async def catch_up(self):
|
async def catch_up(self: 'TelegramClient'):
|
||||||
"""
|
"""
|
||||||
"Catches up" on the missed updates while the client was offline.
|
"Catches up" on the missed updates while the client was offline.
|
||||||
You should call this method after registering the event handlers
|
You should call this method after registering the event handlers
|
||||||
|
@ -196,7 +205,7 @@ class UpdateMethods(UserMethods):
|
||||||
# It is important to not make _handle_update async because we rely on
|
# It is important to not make _handle_update async because we rely on
|
||||||
# the order that the updates arrive in to update the pts and date to
|
# the order that the updates arrive in to update the pts and date to
|
||||||
# be always-increasing. There is also no need to make this async.
|
# be always-increasing. There is also no need to make this async.
|
||||||
def _handle_update(self, update):
|
def _handle_update(self: 'TelegramClient', update):
|
||||||
self.session.process_entities(update)
|
self.session.process_entities(update)
|
||||||
self._entity_cache.add(update)
|
self._entity_cache.add(update)
|
||||||
|
|
||||||
|
@ -212,7 +221,7 @@ class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
self._state_cache.update(update)
|
self._state_cache.update(update)
|
||||||
|
|
||||||
def _process_update(self, update, entities=None):
|
def _process_update(self: 'TelegramClient', update, entities=None):
|
||||||
update._entities = entities or {}
|
update._entities = entities or {}
|
||||||
|
|
||||||
# This part is somewhat hot so we don't bother patching
|
# This part is somewhat hot so we don't bother patching
|
||||||
|
@ -230,7 +239,7 @@ class UpdateMethods(UserMethods):
|
||||||
|
|
||||||
self._state_cache.update(update)
|
self._state_cache.update(update)
|
||||||
|
|
||||||
async def _update_loop(self):
|
async def _update_loop(self: 'TelegramClient'):
|
||||||
# Pings' ID don't really need to be secure, just "random"
|
# Pings' ID don't really need to be secure, just "random"
|
||||||
rnd = lambda: random.randrange(-2**63, 2**63)
|
rnd = lambda: random.randrange(-2**63, 2**63)
|
||||||
while self.is_connected():
|
while self.is_connected():
|
||||||
|
@ -275,13 +284,13 @@ class UpdateMethods(UserMethods):
|
||||||
except (ConnectionError, asyncio.CancelledError):
|
except (ConnectionError, asyncio.CancelledError):
|
||||||
return
|
return
|
||||||
|
|
||||||
async def _dispatch_queue_updates(self):
|
async def _dispatch_queue_updates(self: 'TelegramClient'):
|
||||||
while not self._updates_queue.empty():
|
while not self._updates_queue.empty():
|
||||||
await self._dispatch_update(*self._updates_queue.get_nowait())
|
await self._dispatch_update(*self._updates_queue.get_nowait())
|
||||||
|
|
||||||
self._dispatching_updates_queue.clear()
|
self._dispatching_updates_queue.clear()
|
||||||
|
|
||||||
async def _dispatch_update(self, update, channel_id, pts_date):
|
async def _dispatch_update(self: 'TelegramClient', update, channel_id, pts_date):
|
||||||
if not self._entity_cache.ensure_cached(update):
|
if not self._entity_cache.ensure_cached(update):
|
||||||
await self._get_difference(update, channel_id, pts_date)
|
await self._get_difference(update, channel_id, pts_date)
|
||||||
|
|
||||||
|
@ -333,7 +342,7 @@ class UpdateMethods(UserMethods):
|
||||||
self._log[__name__].exception('Unhandled exception on %s',
|
self._log[__name__].exception('Unhandled exception on %s',
|
||||||
name)
|
name)
|
||||||
|
|
||||||
async def _get_difference(self, update, channel_id, pts_date):
|
async def _get_difference(self: 'TelegramClient', update, channel_id, pts_date):
|
||||||
"""
|
"""
|
||||||
Get the difference for this `channel_id` if any, then load entities.
|
Get the difference for this `channel_id` if any, then load entities.
|
||||||
|
|
||||||
|
@ -373,7 +382,7 @@ class UpdateMethods(UserMethods):
|
||||||
itertools.chain(result.users, result.chats)
|
itertools.chain(result.users, result.chats)
|
||||||
})
|
})
|
||||||
|
|
||||||
async def _handle_auto_reconnect(self):
|
async def _handle_auto_reconnect(self: 'TelegramClient'):
|
||||||
# TODO Catch-up
|
# TODO Catch-up
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
|
@ -415,7 +424,7 @@ class EventBuilderDict:
|
||||||
"""
|
"""
|
||||||
Helper "dictionary" to return events from types and cache them.
|
Helper "dictionary" to return events from types and cache them.
|
||||||
"""
|
"""
|
||||||
def __init__(self, client, update):
|
def __init__(self, client: 'TelegramClient', update):
|
||||||
self.client = client
|
self.client = client
|
||||||
self.update = update
|
self.update = update
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,13 @@ import io
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
|
import typing
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from .buttons import ButtonMethods
|
from .buttons import ButtonMethods
|
||||||
from .messageparse import MessageParseMethods
|
from .messageparse import MessageParseMethods
|
||||||
from .users import UserMethods
|
from .users import UserMethods
|
||||||
from .. import utils, helpers
|
from .. import utils, helpers, hints
|
||||||
from ..tl import types, functions, custom
|
from ..tl import types, functions, custom
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -18,6 +19,10 @@ except ImportError:
|
||||||
PIL = None
|
PIL = None
|
||||||
|
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class _CacheType:
|
class _CacheType:
|
||||||
"""Like functools.partial but pretends to be the wrapped class."""
|
"""Like functools.partial but pretends to be the wrapped class."""
|
||||||
def __init__(self, cls):
|
def __init__(self, cls):
|
||||||
|
@ -83,11 +88,24 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
async def send_file(
|
async def send_file(
|
||||||
self, entity, file, *, caption=None, force_document=False,
|
self: 'TelegramClient',
|
||||||
progress_callback=None, reply_to=None, attributes=None,
|
entity: hints.EntityLike,
|
||||||
thumb=None, allow_cache=True, parse_mode=(),
|
file: hints.FileLike,
|
||||||
voice_note=False, video_note=False, buttons=None, silent=None,
|
*,
|
||||||
supports_streaming=False, **kwargs):
|
caption: str = None,
|
||||||
|
force_document: bool = False,
|
||||||
|
progress_callback: hints.ProgressCallback = None,
|
||||||
|
reply_to: hints.MessageIDLike = None,
|
||||||
|
attributes: typing.Sequence[types.TypeDocumentAttribute] = None,
|
||||||
|
thumb: hints.FileLike = None,
|
||||||
|
allow_cache: bool = True,
|
||||||
|
parse_mode: str = (),
|
||||||
|
voice_note: bool = False,
|
||||||
|
video_note: bool = False,
|
||||||
|
buttons: hints.MarkupLike = None,
|
||||||
|
silent: bool = None,
|
||||||
|
supports_streaming: bool = False,
|
||||||
|
**kwargs) -> types.Message:
|
||||||
"""
|
"""
|
||||||
Sends a file to the specified entity.
|
Sends a file to the specified entity.
|
||||||
|
|
||||||
|
@ -292,7 +310,7 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
|
||||||
|
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
async def _send_album(self, entity, files, caption='',
|
async def _send_album(self: 'TelegramClient', entity, files, caption='',
|
||||||
progress_callback=None, reply_to=None,
|
progress_callback=None, reply_to=None,
|
||||||
parse_mode=(), silent=None):
|
parse_mode=(), silent=None):
|
||||||
"""Specialized version of .send_file for albums"""
|
"""Specialized version of .send_file for albums"""
|
||||||
|
@ -360,8 +378,13 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
|
||||||
return [messages[m.media.id.id] for m in media]
|
return [messages[m.media.id.id] for m in media]
|
||||||
|
|
||||||
async def upload_file(
|
async def upload_file(
|
||||||
self, file, *, part_size_kb=None, file_name=None, use_cache=None,
|
self: 'TelegramClient',
|
||||||
progress_callback=None):
|
file: hints.FileLike,
|
||||||
|
*,
|
||||||
|
part_size_kb: float = None,
|
||||||
|
file_name: str = None,
|
||||||
|
use_cache: type = None,
|
||||||
|
progress_callback: hints.ProgressCallback = None) -> types.TypeInputFile:
|
||||||
"""
|
"""
|
||||||
Uploads the specified file and returns a handle (an instance of
|
Uploads the specified file and returns a handle (an instance of
|
||||||
:tl:`InputFile` or :tl:`InputFileBig`, as required) which can be
|
:tl:`InputFile` or :tl:`InputFileBig`, as required) which can be
|
||||||
|
@ -607,7 +630,7 @@ class UploadMethods(ButtonMethods, MessageParseMethods, UserMethods):
|
||||||
)
|
)
|
||||||
return file_handle, media, as_image
|
return file_handle, media, as_image
|
||||||
|
|
||||||
async def _cache_media(self, msg, file, file_handle, image):
|
async def _cache_media(self: 'TelegramClient', msg, file, file_handle, image):
|
||||||
if file and msg and isinstance(file_handle,
|
if file and msg and isinstance(file_handle,
|
||||||
custom.InputSizedFile):
|
custom.InputSizedFile):
|
||||||
# There was a response message and we didn't use cached
|
# There was a response message and we didn't use cached
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import itertools
|
import itertools
|
||||||
import time
|
import time
|
||||||
|
import typing
|
||||||
|
|
||||||
from .telegrambaseclient import TelegramBaseClient
|
from .telegrambaseclient import TelegramBaseClient
|
||||||
from .. import errors, utils
|
from .. import errors, utils, hints
|
||||||
from ..errors import MultiError, RPCError
|
from ..errors import MultiError, RPCError
|
||||||
from ..tl import TLObject, TLRequest, types, functions
|
|
||||||
from ..helpers import retry_range
|
from ..helpers import retry_range
|
||||||
|
from ..tl import TLRequest, types, functions
|
||||||
|
|
||||||
_NOT_A_REQUEST = lambda: TypeError('You can only invoke requests, not types!')
|
_NOT_A_REQUEST = lambda: TypeError('You can only invoke requests, not types!')
|
||||||
|
|
||||||
|
if typing.TYPE_CHECKING:
|
||||||
|
from .telegramclient import TelegramClient
|
||||||
|
|
||||||
|
|
||||||
class UserMethods(TelegramBaseClient):
|
class UserMethods(TelegramBaseClient):
|
||||||
async def __call__(self, request, ordered=False):
|
async def __call__(self: 'TelegramClient', request, ordered=False):
|
||||||
requests = (request if utils.is_list_like(request) else (request,))
|
requests = (request if utils.is_list_like(request) else (request,))
|
||||||
for r in requests:
|
for r in requests:
|
||||||
if not isinstance(r, TLRequest):
|
if not isinstance(r, TLRequest):
|
||||||
|
@ -97,7 +101,8 @@ class UserMethods(TelegramBaseClient):
|
||||||
|
|
||||||
# region Public methods
|
# region Public methods
|
||||||
|
|
||||||
async def get_me(self, input_peer=False):
|
async def get_me(self: 'TelegramClient', input_peer: bool = False) \
|
||||||
|
-> typing.Union[types.User, types.InputPeerUser]:
|
||||||
"""
|
"""
|
||||||
Gets "me" (the self user) which is currently authenticated,
|
Gets "me" (the self user) which is currently authenticated,
|
||||||
or None if the request fails (hence, not authenticated).
|
or None if the request fails (hence, not authenticated).
|
||||||
|
@ -128,7 +133,7 @@ class UserMethods(TelegramBaseClient):
|
||||||
except errors.UnauthorizedError:
|
except errors.UnauthorizedError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def is_bot(self):
|
async def is_bot(self: 'TelegramClient') -> bool:
|
||||||
"""
|
"""
|
||||||
Return ``True`` if the signed-in user is a bot, ``False`` otherwise.
|
Return ``True`` if the signed-in user is a bot, ``False`` otherwise.
|
||||||
"""
|
"""
|
||||||
|
@ -137,7 +142,7 @@ class UserMethods(TelegramBaseClient):
|
||||||
|
|
||||||
return self._bot
|
return self._bot
|
||||||
|
|
||||||
async def is_user_authorized(self):
|
async def is_user_authorized(self: 'TelegramClient') -> bool:
|
||||||
"""
|
"""
|
||||||
Returns ``True`` if the user is authorized.
|
Returns ``True`` if the user is authorized.
|
||||||
"""
|
"""
|
||||||
|
@ -151,7 +156,9 @@ class UserMethods(TelegramBaseClient):
|
||||||
|
|
||||||
return self._authorized
|
return self._authorized
|
||||||
|
|
||||||
async def get_entity(self, entity):
|
async def get_entity(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
entity: hints.EntitiesLike) -> hints.Entity:
|
||||||
"""
|
"""
|
||||||
Turns the given entity into a valid Telegram :tl:`User`, :tl:`Chat`
|
Turns the given entity into a valid Telegram :tl:`User`, :tl:`Chat`
|
||||||
or :tl:`Channel`. You can also pass a list or iterable of entities,
|
or :tl:`Channel`. You can also pass a list or iterable of entities,
|
||||||
|
@ -243,7 +250,9 @@ class UserMethods(TelegramBaseClient):
|
||||||
|
|
||||||
return result[0] if single else result
|
return result[0] if single else result
|
||||||
|
|
||||||
async def get_input_entity(self, peer):
|
async def get_input_entity(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
peer: hints.EntityLike) -> types.TypeInputPeer:
|
||||||
"""
|
"""
|
||||||
Turns the given peer into its input entity version. Most requests
|
Turns the given peer into its input entity version. Most requests
|
||||||
use this kind of :tl:`InputPeer`, so this is the most suitable call
|
use this kind of :tl:`InputPeer`, so this is the most suitable call
|
||||||
|
@ -366,7 +375,10 @@ class UserMethods(TelegramBaseClient):
|
||||||
.format(peer)
|
.format(peer)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_peer_id(self, peer, add_mark=True):
|
async def get_peer_id(
|
||||||
|
self: 'TelegramClient',
|
||||||
|
peer: hints.EntityLike,
|
||||||
|
add_mark: bool = True) -> int:
|
||||||
"""
|
"""
|
||||||
Gets the ID for the given peer, which may be anything entity-like.
|
Gets the ID for the given peer, which may be anything entity-like.
|
||||||
|
|
||||||
|
@ -395,7 +407,7 @@ class UserMethods(TelegramBaseClient):
|
||||||
|
|
||||||
# region Private methods
|
# region Private methods
|
||||||
|
|
||||||
async def _get_entity_from_string(self, string):
|
async def _get_entity_from_string(self: 'TelegramClient', string):
|
||||||
"""
|
"""
|
||||||
Gets a full entity from the given string, which may be a phone or
|
Gets a full entity from the given string, which may be a phone or
|
||||||
a username, and processes all the found entities on the session.
|
a username, and processes all the found entities on the session.
|
||||||
|
@ -459,7 +471,7 @@ class UserMethods(TelegramBaseClient):
|
||||||
'Cannot find any entity corresponding to "{}"'.format(string)
|
'Cannot find any entity corresponding to "{}"'.format(string)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _get_input_dialog(self, dialog):
|
async def _get_input_dialog(self: 'TelegramClient', dialog):
|
||||||
"""
|
"""
|
||||||
Returns a :tl:`InputDialogPeer`. This is a bit tricky because
|
Returns a :tl:`InputDialogPeer`. This is a bit tricky because
|
||||||
it may or not need access to the client to convert what's given
|
it may or not need access to the client to convert what's given
|
||||||
|
@ -476,7 +488,7 @@ class UserMethods(TelegramBaseClient):
|
||||||
|
|
||||||
return types.InputDialogPeer(await self.get_input_entity(dialog))
|
return types.InputDialogPeer(await self.get_input_entity(dialog))
|
||||||
|
|
||||||
async def _get_input_notify(self, notify):
|
async def _get_input_notify(self: 'TelegramClient', notify):
|
||||||
"""
|
"""
|
||||||
Returns a :tl:`InputNotifyPeer`. This is a bit tricky because
|
Returns a :tl:`InputNotifyPeer`. This is a bit tricky because
|
||||||
it may or not need access to the client to convert what's given
|
it may or not need access to the client to convert what's given
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import struct
|
import struct
|
||||||
from hashlib import sha1, sha256
|
from hashlib import sha1
|
||||||
|
|
||||||
|
|
||||||
# region Multiple utilities
|
# region Multiple utilities
|
||||||
|
|
|
@ -6,6 +6,7 @@ from .mtprotoplainsender import MTProtoPlainSender
|
||||||
from .authenticator import do_authentication
|
from .authenticator import do_authentication
|
||||||
from .mtprotosender import MTProtoSender
|
from .mtprotosender import MTProtoSender
|
||||||
from .connection import (
|
from .connection import (
|
||||||
|
Connection,
|
||||||
ConnectionTcpFull, ConnectionTcpIntermediate, ConnectionTcpAbridged,
|
ConnectionTcpFull, ConnectionTcpIntermediate, ConnectionTcpAbridged,
|
||||||
ConnectionTcpObfuscated, ConnectionTcpMTProxyAbridged,
|
ConnectionTcpObfuscated, ConnectionTcpMTProxyAbridged,
|
||||||
ConnectionTcpMTProxyIntermediate,
|
ConnectionTcpMTProxyIntermediate,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from .connection import Connection
|
||||||
from .tcpfull import ConnectionTcpFull
|
from .tcpfull import ConnectionTcpFull
|
||||||
from .tcpintermediate import ConnectionTcpIntermediate
|
from .tcpintermediate import ConnectionTcpIntermediate
|
||||||
from .tcpabridged import ConnectionTcpAbridged
|
from .tcpabridged import ConnectionTcpAbridged
|
||||||
|
|
Loading…
Reference in New Issue
Block a user