mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-06-19 11:36:41 +00:00
Add a custom role for TL references and make use of it
This commit is contained in:
parent
c6d821910e
commit
43c6896481
@ -17,15 +17,16 @@
|
|||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#
|
#
|
||||||
# import os
|
|
||||||
# import sys
|
|
||||||
# sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
|
|
||||||
root = os.path.abspath(os.path.join(__file__, os.path.pardir, os.path.pardir))
|
root = os.path.abspath(os.path.join(__file__, os.path.pardir, os.path.pardir))
|
||||||
|
|
||||||
|
tl_ref_url = 'https://lonamiwebs.github.io/Telethon'
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ------------------------------------------------
|
# -- General configuration ------------------------------------------------
|
||||||
|
|
||||||
@ -36,7 +37,10 @@ root = os.path.abspath(os.path.join(__file__, os.path.pardir, os.path.pardir))
|
|||||||
# Add any Sphinx extension module names here, as strings. They can be
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
# ones.
|
# ones.
|
||||||
extensions = ['sphinx.ext.autodoc']
|
extensions = [
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'custom_roles'
|
||||||
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
69
readthedocs/custom_roles.py
Normal file
69
readthedocs/custom_roles.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
from docutils import nodes, utils
|
||||||
|
from docutils.parsers.rst.roles import set_classes
|
||||||
|
|
||||||
|
|
||||||
|
def make_link_node(rawtext, app, name, options):
|
||||||
|
"""
|
||||||
|
Create a link to the TL reference.
|
||||||
|
|
||||||
|
:param rawtext: Text being replaced with link node.
|
||||||
|
:param app: Sphinx application context
|
||||||
|
:param name: Name of the object to link to
|
||||||
|
:param options: Options dictionary passed to role func.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
base = app.config.tl_ref_url
|
||||||
|
if not base:
|
||||||
|
raise AttributeError
|
||||||
|
except AttributeError as e:
|
||||||
|
raise ValueError('tl_ref_url config value is not set') from e
|
||||||
|
|
||||||
|
if base[-1] != '/':
|
||||||
|
base += '/'
|
||||||
|
|
||||||
|
set_classes(options)
|
||||||
|
node = nodes.reference(rawtext, utils.unescape(name),
|
||||||
|
refuri='{}?q={}'.format(base, name),
|
||||||
|
**options)
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
def tl_role(name, rawtext, text, lineno, inliner, options=None, content=None):
|
||||||
|
"""
|
||||||
|
Link to the TL reference.
|
||||||
|
|
||||||
|
Returns 2 part tuple containing list of nodes to insert into the
|
||||||
|
document and a list of system messages. Both are allowed to be empty.
|
||||||
|
|
||||||
|
:param name: The role name used in the document.
|
||||||
|
:param rawtext: The entire markup snippet, with role.
|
||||||
|
:param text: The text marked with the role.
|
||||||
|
:param lineno: The line number where rawtext appears in the input.
|
||||||
|
:param inliner: The inliner instance that called us.
|
||||||
|
:param options: Directive options for customization.
|
||||||
|
:param content: The directive content for customization.
|
||||||
|
"""
|
||||||
|
if options is None:
|
||||||
|
options = {}
|
||||||
|
if content is None:
|
||||||
|
content = []
|
||||||
|
|
||||||
|
# TODO Report error on type not found?
|
||||||
|
# Usage:
|
||||||
|
# msg = inliner.reporter.error(..., line=lineno)
|
||||||
|
# return [inliner.problematic(rawtext, rawtext, msg)], [msg]
|
||||||
|
app = inliner.document.settings.env.app
|
||||||
|
node = make_link_node(rawtext, app, text, options)
|
||||||
|
return [node], []
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
"""
|
||||||
|
Install the plugin.
|
||||||
|
|
||||||
|
:param app: Sphinx application context.
|
||||||
|
"""
|
||||||
|
app.info('Initializing TL reference plugin')
|
||||||
|
app.add_role('tl', tl_role)
|
||||||
|
app.add_config_value('tl_ref_url', None, 'env')
|
||||||
|
return
|
@ -25,7 +25,7 @@ You should also refer to the documentation to see what the objects
|
|||||||
from a common type, and that's the reason for this distinction.
|
from a common type, and that's the reason for this distinction.
|
||||||
|
|
||||||
Say ``client.send_message()`` didn't exist, we could use the `search`__
|
Say ``client.send_message()`` didn't exist, we could use the `search`__
|
||||||
to look for "message". There we would find `SendMessageRequest`__,
|
to look for "message". There we would find :tl:`SendMessageRequest`,
|
||||||
which we can work with.
|
which we can work with.
|
||||||
|
|
||||||
Every request is a Python class, and has the parameters needed for you
|
Every request is a Python class, and has the parameters needed for you
|
||||||
@ -45,11 +45,11 @@ If you're going to use a lot of these, you may do:
|
|||||||
# We now have access to 'functions.messages.SendMessageRequest'
|
# We now have access to 'functions.messages.SendMessageRequest'
|
||||||
|
|
||||||
We see that this request must take at least two parameters, a ``peer``
|
We see that this request must take at least two parameters, a ``peer``
|
||||||
of type `InputPeer`__, and a ``message`` which is just a Python
|
of type :tl:`InputPeer`, and a ``message`` which is just a Python
|
||||||
``str``\ ing.
|
``str``\ ing.
|
||||||
|
|
||||||
How can we retrieve this ``InputPeer``? We have two options. We manually
|
How can we retrieve this :tl:`InputPeer`? We have two options. We manually
|
||||||
`construct one`__, for instance:
|
construct one, for instance:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@ -64,7 +64,7 @@ Or we call ``.get_input_entity()``:
|
|||||||
peer = client.get_input_entity('someone')
|
peer = client.get_input_entity('someone')
|
||||||
|
|
||||||
When you're going to invoke an API method, most require you to pass an
|
When you're going to invoke an API method, most require you to pass an
|
||||||
``InputUser``, ``InputChat``, or so on, this is why using
|
:tl:`InputUser`, :tl:`InputChat`, or so on, this is why using
|
||||||
``.get_input_entity()`` is more straightforward (and often
|
``.get_input_entity()`` is more straightforward (and often
|
||||||
immediate, if you've seen the user before, know their ID, etc.).
|
immediate, if you've seen the user before, know their ID, etc.).
|
||||||
If you also need to have information about the whole user, use
|
If you also need to have information about the whole user, use
|
||||||
@ -138,6 +138,3 @@ This can further be simplified to:
|
|||||||
__ https://lonamiwebs.github.io/Telethon
|
__ https://lonamiwebs.github.io/Telethon
|
||||||
__ https://lonamiwebs.github.io/Telethon/methods/index.html
|
__ https://lonamiwebs.github.io/Telethon/methods/index.html
|
||||||
__ https://lonamiwebs.github.io/Telethon/?q=message
|
__ https://lonamiwebs.github.io/Telethon/?q=message
|
||||||
__ https://lonamiwebs.github.io/Telethon/methods/messages/send_message.html
|
|
||||||
__ https://lonamiwebs.github.io/Telethon/types/input_peer.html
|
|
||||||
__ https://lonamiwebs.github.io/Telethon/constructors/input_peer_user.html
|
|
||||||
|
@ -9,16 +9,16 @@ Introduction
|
|||||||
************
|
************
|
||||||
|
|
||||||
The library widely uses the concept of "entities". An entity will refer
|
The library widely uses the concept of "entities". An entity will refer
|
||||||
to any ``User``, ``Chat`` or ``Channel`` object that the API may return
|
to any :tl:`User`, :tl:`Chat` or :tl:`Channel` object that the API may return
|
||||||
in response to certain methods, such as ``GetUsersRequest``.
|
in response to certain methods, such as :tl:`GetUsersRequest`.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
When something "entity-like" is required, it means that you need to
|
When something "entity-like" is required, it means that you need to
|
||||||
provide something that can be turned into an entity. These things include,
|
provide something that can be turned into an entity. These things include,
|
||||||
but are not limited to, usernames, exact titles, IDs, ``Peer`` objects,
|
but are not limited to, usernames, exact titles, IDs, :tl:`Peer` objects,
|
||||||
or even entire ``User``, ``Chat`` and ``Channel`` objects and even phone
|
or even entire :tl:`User`, :tl:`Chat` and :tl:`Channel` objects and even
|
||||||
numbers from people you have in your contacts.
|
phone numbers from people you have in your contacts.
|
||||||
|
|
||||||
Getting entities
|
Getting entities
|
||||||
****************
|
****************
|
||||||
@ -73,7 +73,7 @@ become possible.
|
|||||||
Every entity the library encounters (in any response to any call) will by
|
Every entity the library encounters (in any response to any call) will by
|
||||||
default be cached in the ``.session`` file (an SQLite database), to avoid
|
default be cached in the ``.session`` file (an SQLite database), to avoid
|
||||||
performing unnecessary API calls. If the entity cannot be found, additonal
|
performing unnecessary API calls. If the entity cannot be found, additonal
|
||||||
calls like ``ResolveUsernameRequest`` or ``GetContactsRequest`` may be
|
calls like :tl:`ResolveUsernameRequest` or :tl:`GetContactsRequest` may be
|
||||||
made to obtain the required information.
|
made to obtain the required information.
|
||||||
|
|
||||||
|
|
||||||
@ -90,14 +90,14 @@ Entities vs. Input Entities
|
|||||||
|
|
||||||
On top of the normal types, the API also make use of what they call their
|
On top of the normal types, the API also make use of what they call their
|
||||||
``Input*`` versions of objects. The input version of an entity (e.g.
|
``Input*`` versions of objects. The input version of an entity (e.g.
|
||||||
``InputPeerUser``, ``InputChat``, etc.) only contains the minimum
|
:tl:`InputPeerUser`, :tl:`InputChat`, etc.) only contains the minimum
|
||||||
information that's required from Telegram to be able to identify
|
information that's required from Telegram to be able to identify
|
||||||
who you're referring to: a ``Peer``'s **ID** and **hash**.
|
who you're referring to: a :tl:`Peer`'s **ID** and **hash**.
|
||||||
|
|
||||||
This ID/hash pair is unique per user, so if you use the pair given by another
|
This ID/hash pair is unique per user, so if you use the pair given by another
|
||||||
user **or bot** it will **not** work.
|
user **or bot** it will **not** work.
|
||||||
|
|
||||||
To save *even more* bandwidth, the API also makes use of the ``Peer``
|
To save *even more* bandwidth, the API also makes use of the :tl:`Peer`
|
||||||
versions, which just have an ID. This serves to identify them, but
|
versions, which just have an ID. This serves to identify them, but
|
||||||
peers alone are not enough to use them. You need to know their hash
|
peers alone are not enough to use them. You need to know their hash
|
||||||
before you can "use them".
|
before you can "use them".
|
||||||
@ -106,8 +106,8 @@ As we just mentioned, API calls don't need to know the whole information
|
|||||||
about the entities, only their ID and hash. For this reason, another method,
|
about the entities, only their ID and hash. For this reason, another method,
|
||||||
``.get_input_entity()`` is available. This will always use the cache while
|
``.get_input_entity()`` is available. This will always use the cache while
|
||||||
possible, making zero API calls most of the time. When a request is made,
|
possible, making zero API calls most of the time. When a request is made,
|
||||||
if you provided the full entity, e.g. an ``User``, the library will convert
|
if you provided the full entity, e.g. an :tl:`User`, the library will convert
|
||||||
it to the required ``InputPeer`` automatically for you.
|
it to the required :tl:`InputPeer` automatically for you.
|
||||||
|
|
||||||
**You should always favour** ``.get_input_entity()`` **over** ``.get_entity()``
|
**You should always favour** ``.get_input_entity()`` **over** ``.get_entity()``
|
||||||
for this reason! Calling the latter will always make an API call to get
|
for this reason! Calling the latter will always make an API call to get
|
||||||
@ -125,5 +125,5 @@ library, the raw requests you make to the API are also able to call
|
|||||||
client(SendMessageRequest('username', 'hello'))
|
client(SendMessageRequest('username', 'hello'))
|
||||||
|
|
||||||
The library will call the ``.resolve()`` method of the request, which will
|
The library will call the ``.resolve()`` method of the request, which will
|
||||||
resolve ``'username'`` with the appropriated ``InputPeer``. Don't worry if
|
resolve ``'username'`` with the appropriated :tl:`InputPeer`. Don't worry if
|
||||||
you don't get this yet, but remember some of the details here are important.
|
you don't get this yet, but remember some of the details here are important.
|
||||||
|
@ -315,7 +315,7 @@ library alone (when invoking a request), it means that you can now use
|
|||||||
``Peer`` types or even usernames where a ``InputPeer`` is required. The
|
``Peer`` types or even usernames where a ``InputPeer`` is required. The
|
||||||
object now has access to the ``client``, so that it can fetch the right
|
object now has access to the ``client``, so that it can fetch the right
|
||||||
type if needed, or access the session database. Furthermore, you can
|
type if needed, or access the session database. Furthermore, you can
|
||||||
reuse requests that need "autocast" (e.g. you put ``User`` but ``InputPeer``
|
reuse requests that need "autocast" (e.g. you put :tl:`User` but ``InputPeer``
|
||||||
was needed), since ``.resolve()`` is called when invoking. Before, it was
|
was needed), since ``.resolve()`` is called when invoking. Before, it was
|
||||||
only done on object construction.
|
only done on object construction.
|
||||||
|
|
||||||
|
@ -91,13 +91,13 @@ class _EventCommon(abc.ABC):
|
|||||||
|
|
||||||
def _get_entity(self, msg_id, entity_id, chat=None):
|
def _get_entity(self, msg_id, entity_id, chat=None):
|
||||||
"""
|
"""
|
||||||
Helper function to call GetMessages on the give msg_id and
|
Helper function to call :tl:`GetMessages` on the give msg_id and
|
||||||
return the input entity whose ID is the given entity ID.
|
return the input entity whose ID is the given entity ID.
|
||||||
|
|
||||||
If ``chat`` is present it must be an InputPeer.
|
If ``chat`` is present it must be an :tl:`InputPeer`.
|
||||||
|
|
||||||
Returns a tuple of (entity, input_peer) if it was found, or
|
Returns a tuple of ``(entity, input_peer)`` if it was found, or
|
||||||
a tuple of (None, None) if it couldn't be.
|
a tuple of ``(None, None)`` if it couldn't be.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if isinstance(chat, types.InputPeerChannel):
|
if isinstance(chat, types.InputPeerChannel):
|
||||||
@ -124,7 +124,7 @@ class _EventCommon(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
def input_chat(self):
|
def input_chat(self):
|
||||||
"""
|
"""
|
||||||
The (:obj:`InputPeer`) (group, megagroup or channel) on which
|
The (:tl:`InputPeer`) (group, megagroup or channel) on which
|
||||||
the event occurred. This doesn't have the title or anything,
|
the event occurred. This doesn't have the title or anything,
|
||||||
but is useful if you don't need those to avoid further
|
but is useful if you don't need those to avoid further
|
||||||
requests.
|
requests.
|
||||||
@ -156,7 +156,7 @@ class _EventCommon(abc.ABC):
|
|||||||
@property
|
@property
|
||||||
def chat(self):
|
def chat(self):
|
||||||
"""
|
"""
|
||||||
The (:obj:`User` | :obj:`Chat` | :obj:`Channel`, optional) on which
|
The (:tl:`User` | :tl:`Chat` | :tl:`Channel`, optional) on which
|
||||||
the event occurred. This property may make an API call the first time
|
the event occurred. This property may make an API call the first time
|
||||||
to get the most up to date version of the chat (mostly when the event
|
to get the most up to date version of the chat (mostly when the event
|
||||||
doesn't belong to a channel), so keep that in mind.
|
doesn't belong to a channel), so keep that in mind.
|
||||||
@ -312,8 +312,8 @@ class NewMessage(_EventBuilder):
|
|||||||
Represents the event of a new message.
|
Represents the event of a new message.
|
||||||
|
|
||||||
Members:
|
Members:
|
||||||
message (:obj:`Message`):
|
message (:tl:`Message`):
|
||||||
This is the original ``Message`` object.
|
This is the original :tl:`Message` object.
|
||||||
|
|
||||||
is_private (:obj:`bool`):
|
is_private (:obj:`bool`):
|
||||||
True if the message was sent as a private message.
|
True if the message was sent as a private message.
|
||||||
@ -406,7 +406,7 @@ class NewMessage(_EventBuilder):
|
|||||||
@property
|
@property
|
||||||
def input_sender(self):
|
def input_sender(self):
|
||||||
"""
|
"""
|
||||||
This (:obj:`InputPeer`) is the input version of the user who
|
This (:tl:`InputPeer`) is the input version of the user who
|
||||||
sent the message. Similarly to ``input_chat``, this doesn't have
|
sent the message. Similarly to ``input_chat``, this doesn't have
|
||||||
things like username or similar, but still useful in some cases.
|
things like username or similar, but still useful in some cases.
|
||||||
|
|
||||||
@ -434,7 +434,7 @@ class NewMessage(_EventBuilder):
|
|||||||
@property
|
@property
|
||||||
def sender(self):
|
def sender(self):
|
||||||
"""
|
"""
|
||||||
This (:obj:`User`) may make an API call the first time to get
|
This (:tl:`User`) may make an API call the first time to get
|
||||||
the most up to date version of the sender (mostly when the event
|
the most up to date version of the sender (mostly when the event
|
||||||
doesn't belong to a channel), so keep that in mind.
|
doesn't belong to a channel), so keep that in mind.
|
||||||
|
|
||||||
@ -474,8 +474,8 @@ class NewMessage(_EventBuilder):
|
|||||||
@property
|
@property
|
||||||
def reply_message(self):
|
def reply_message(self):
|
||||||
"""
|
"""
|
||||||
This (:obj:`Message`, optional) will make an API call the first
|
This optional :tl:`Message` will make an API call the first
|
||||||
time to get the full ``Message`` object that one was replying to,
|
time to get the full :tl:`Message` object that one was replying to,
|
||||||
so use with care as there is no caching besides local caching yet.
|
so use with care as there is no caching besides local caching yet.
|
||||||
"""
|
"""
|
||||||
if not self.message.reply_to_msg_id:
|
if not self.message.reply_to_msg_id:
|
||||||
@ -498,14 +498,14 @@ class NewMessage(_EventBuilder):
|
|||||||
@property
|
@property
|
||||||
def forward(self):
|
def forward(self):
|
||||||
"""
|
"""
|
||||||
The unmodified (:obj:`MessageFwdHeader`, optional).
|
The unmodified :tl:`MessageFwdHeader`, if present..
|
||||||
"""
|
"""
|
||||||
return self.message.fwd_from
|
return self.message.fwd_from
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media(self):
|
def media(self):
|
||||||
"""
|
"""
|
||||||
The unmodified (:obj:`MessageMedia`, optional).
|
The unmodified :tl:`MessageMedia`, if present.
|
||||||
"""
|
"""
|
||||||
return self.message.media
|
return self.message.media
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def photo(self):
|
def photo(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a photo,
|
If the message media is a photo,
|
||||||
this returns the (:obj:`Photo`) object.
|
this returns the :tl:`Photo` object.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.message.media, types.MessageMediaPhoto):
|
if isinstance(self.message.media, types.MessageMediaPhoto):
|
||||||
photo = self.message.media.photo
|
photo = self.message.media.photo
|
||||||
@ -524,7 +524,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def document(self):
|
def document(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a document,
|
If the message media is a document,
|
||||||
this returns the (:obj:`Document`) object.
|
this returns the :tl:`Document` object.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.message.media, types.MessageMediaDocument):
|
if isinstance(self.message.media, types.MessageMediaDocument):
|
||||||
doc = self.message.media.document
|
doc = self.message.media.document
|
||||||
@ -547,7 +547,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def audio(self):
|
def audio(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a document with an Audio attribute,
|
If the message media is a document with an Audio attribute,
|
||||||
this returns the (:obj:`Document`) object.
|
this returns the :tl:`Document` object.
|
||||||
"""
|
"""
|
||||||
return self._document_by_attribute(types.DocumentAttributeAudio,
|
return self._document_by_attribute(types.DocumentAttributeAudio,
|
||||||
lambda attr: not attr.voice)
|
lambda attr: not attr.voice)
|
||||||
@ -556,7 +556,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def voice(self):
|
def voice(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a document with a Voice attribute,
|
If the message media is a document with a Voice attribute,
|
||||||
this returns the (:obj:`Document`) object.
|
this returns the :tl:`Document` object.
|
||||||
"""
|
"""
|
||||||
return self._document_by_attribute(types.DocumentAttributeAudio,
|
return self._document_by_attribute(types.DocumentAttributeAudio,
|
||||||
lambda attr: attr.voice)
|
lambda attr: attr.voice)
|
||||||
@ -565,7 +565,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def video(self):
|
def video(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a document with a Video attribute,
|
If the message media is a document with a Video attribute,
|
||||||
this returns the (:obj:`Document`) object.
|
this returns the :tl:`Document` object.
|
||||||
"""
|
"""
|
||||||
return self._document_by_attribute(types.DocumentAttributeVideo)
|
return self._document_by_attribute(types.DocumentAttributeVideo)
|
||||||
|
|
||||||
@ -573,7 +573,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def video_note(self):
|
def video_note(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a document with a Video attribute,
|
If the message media is a document with a Video attribute,
|
||||||
this returns the (:obj:`Document`) object.
|
this returns the :tl:`Document` object.
|
||||||
"""
|
"""
|
||||||
return self._document_by_attribute(types.DocumentAttributeVideo,
|
return self._document_by_attribute(types.DocumentAttributeVideo,
|
||||||
lambda attr: attr.round_message)
|
lambda attr: attr.round_message)
|
||||||
@ -582,7 +582,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def gif(self):
|
def gif(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a document with an Animated attribute,
|
If the message media is a document with an Animated attribute,
|
||||||
this returns the (:obj:`Document`) object.
|
this returns the :tl:`Document` object.
|
||||||
"""
|
"""
|
||||||
return self._document_by_attribute(types.DocumentAttributeAnimated)
|
return self._document_by_attribute(types.DocumentAttributeAnimated)
|
||||||
|
|
||||||
@ -590,7 +590,7 @@ class NewMessage(_EventBuilder):
|
|||||||
def sticker(self):
|
def sticker(self):
|
||||||
"""
|
"""
|
||||||
If the message media is a document with a Sticker attribute,
|
If the message media is a document with a Sticker attribute,
|
||||||
this returns the (:obj:`Document`) object.
|
this returns the :tl:`Document` object.
|
||||||
"""
|
"""
|
||||||
return self._document_by_attribute(types.DocumentAttributeSticker)
|
return self._document_by_attribute(types.DocumentAttributeSticker)
|
||||||
|
|
||||||
@ -689,7 +689,7 @@ class ChatAction(_EventBuilder):
|
|||||||
new_photo (:obj:`bool`):
|
new_photo (:obj:`bool`):
|
||||||
``True`` if there's a new chat photo (or it was removed).
|
``True`` if there's a new chat photo (or it was removed).
|
||||||
|
|
||||||
photo (:obj:`Photo`, optional):
|
photo (:tl:`Photo`, optional):
|
||||||
The new photo (or ``None`` if it was removed).
|
The new photo (or ``None`` if it was removed).
|
||||||
|
|
||||||
|
|
||||||
@ -793,7 +793,7 @@ class ChatAction(_EventBuilder):
|
|||||||
@property
|
@property
|
||||||
def pinned_message(self):
|
def pinned_message(self):
|
||||||
"""
|
"""
|
||||||
If ``new_pin`` is ``True``, this returns the (:obj:`Message`)
|
If ``new_pin`` is ``True``, this returns the (:tl:`Message`)
|
||||||
object that was pinned.
|
object that was pinned.
|
||||||
"""
|
"""
|
||||||
if self._pinned_message == 0:
|
if self._pinned_message == 0:
|
||||||
@ -857,7 +857,7 @@ class ChatAction(_EventBuilder):
|
|||||||
@property
|
@property
|
||||||
def input_user(self):
|
def input_user(self):
|
||||||
"""
|
"""
|
||||||
Input version of the self.user property.
|
Input version of the ``self.user`` property.
|
||||||
"""
|
"""
|
||||||
if self.input_users:
|
if self.input_users:
|
||||||
return self._input_users[0]
|
return self._input_users[0]
|
||||||
@ -894,7 +894,7 @@ class ChatAction(_EventBuilder):
|
|||||||
@property
|
@property
|
||||||
def input_users(self):
|
def input_users(self):
|
||||||
"""
|
"""
|
||||||
Input version of the self.users property.
|
Input version of the ``self.users`` property.
|
||||||
"""
|
"""
|
||||||
if self._input_users is None and self._user_peers:
|
if self._input_users is None and self._user_peers:
|
||||||
self._input_users = []
|
self._input_users = []
|
||||||
@ -947,7 +947,7 @@ class UserUpdate(_EventBuilder):
|
|||||||
recently (:obj:`bool`):
|
recently (:obj:`bool`):
|
||||||
``True`` if the user was seen within a day.
|
``True`` if the user was seen within a day.
|
||||||
|
|
||||||
action (:obj:`SendMessageAction`, optional):
|
action (:tl:`SendMessageAction`, optional):
|
||||||
The "typing" action if any the user is performing if any.
|
The "typing" action if any the user is performing if any.
|
||||||
|
|
||||||
cancel (:obj:`bool`):
|
cancel (:obj:`bool`):
|
||||||
|
@ -24,13 +24,15 @@ __log__ = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class MtProtoSender:
|
class MtProtoSender:
|
||||||
"""MTProto Mobile Protocol sender
|
"""
|
||||||
(https://core.telegram.org/mtproto/description).
|
MTProto Mobile Protocol sender
|
||||||
|
(https://core.telegram.org/mtproto/description).
|
||||||
|
|
||||||
Note that this class is not thread-safe, and calling send/receive
|
Note that this class is not thread-safe, and calling send/receive
|
||||||
from two or more threads at the same time is undefined behaviour.
|
from two or more threads at the same time is undefined behaviour.
|
||||||
Rationale: a new connection should be spawned to send/receive requests
|
Rationale:
|
||||||
in parallel, so thread-safety (hence locking) isn't needed.
|
a new connection should be spawned to send/receive requests
|
||||||
|
in parallel, so thread-safety (hence locking) isn't needed.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, session, connection):
|
def __init__(self, session, connection):
|
||||||
|
@ -213,7 +213,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Whether to force sending as SMS.
|
Whether to force sending as SMS.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Information about the result of the request.
|
An instance of :tl:`SentCode`.
|
||||||
"""
|
"""
|
||||||
phone = utils.parse_phone(phone) or self._phone
|
phone = utils.parse_phone(phone) or self._phone
|
||||||
phone_hash = self._phone_code_hash.get(phone)
|
phone_hash = self._phone_code_hash.get(phone)
|
||||||
@ -257,8 +257,9 @@ class TelegramClient(TelegramBareClient):
|
|||||||
This is only required if it is enabled in your account.
|
This is only required if it is enabled in your account.
|
||||||
|
|
||||||
bot_token (:obj:`str`):
|
bot_token (:obj:`str`):
|
||||||
Bot Token obtained by @BotFather to log in as a bot.
|
Bot Token obtained by `@BotFather <https://t.me/BotFather>`_
|
||||||
Cannot be specified with `phone` (only one of either allowed).
|
to log in as a bot. Cannot be specified with ``phone`` (only
|
||||||
|
one of either allowed).
|
||||||
|
|
||||||
force_sms (:obj:`bool`, optional):
|
force_sms (:obj:`bool`, optional):
|
||||||
Whether to force sending the code request as SMS.
|
Whether to force sending the code request as SMS.
|
||||||
@ -276,8 +277,8 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Similar to the first name, but for the last. Optional.
|
Similar to the first name, but for the last. Optional.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`TelegramClient`:
|
This :obj:`TelegramClient`, so initialization
|
||||||
This client, so initialization can be chained with `.start()`.
|
can be chained with ``.start()``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if code_callback is None:
|
if code_callback is None:
|
||||||
@ -453,7 +454,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Optional last name.
|
Optional last name.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The new created user.
|
The new created :tl:`User`.
|
||||||
"""
|
"""
|
||||||
if self.is_user_authorized():
|
if self.is_user_authorized():
|
||||||
self._check_events_pending_resolve()
|
self._check_events_pending_resolve()
|
||||||
@ -478,7 +479,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Logs out Telegram and deletes the current ``*.session`` file.
|
Logs out Telegram and deletes the current ``*.session`` file.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if the operation was successful.
|
``True`` if the operation was successful.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self(LogOutRequest())
|
self(LogOutRequest())
|
||||||
@ -496,12 +497,12 @@ class TelegramClient(TelegramBareClient):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
input_peer (:obj:`bool`, optional):
|
input_peer (:obj:`bool`, optional):
|
||||||
Whether to return the ``InputPeerUser`` version or the normal
|
Whether to return the :tl:`InputPeerUser` version or the normal
|
||||||
``User``. This can be useful if you just need to know the ID
|
:tl:`User`. This can be useful if you just need to know the ID
|
||||||
of yourself.
|
of yourself.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
:obj:`User`: Your own user.
|
Your own :tl:`User`.
|
||||||
"""
|
"""
|
||||||
if input_peer and self._self_input_peer:
|
if input_peer and self._self_input_peer:
|
||||||
return self._self_input_peer
|
return self._self_input_peer
|
||||||
@ -541,7 +542,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
offset_id (:obj:`int`, optional):
|
offset_id (:obj:`int`, optional):
|
||||||
The message ID to be used as an offset.
|
The message ID to be used as an offset.
|
||||||
|
|
||||||
offset_peer (:obj:`InputPeer`, optional):
|
offset_peer (:tl:`InputPeer`, optional):
|
||||||
The peer to be used as an offset.
|
The peer to be used as an offset.
|
||||||
|
|
||||||
_total (:obj:`list`, optional):
|
_total (:obj:`list`, optional):
|
||||||
@ -712,10 +713,10 @@ class TelegramClient(TelegramBareClient):
|
|||||||
entity (:obj:`entity`):
|
entity (:obj:`entity`):
|
||||||
To who will it be sent.
|
To who will it be sent.
|
||||||
|
|
||||||
message (:obj:`str` | :obj:`Message`):
|
message (:obj:`str` | :tl:`Message`):
|
||||||
The message to be sent, or another message object to resend.
|
The message to be sent, or another message object to resend.
|
||||||
|
|
||||||
reply_to (:obj:`int` | :obj:`Message`, optional):
|
reply_to (:obj:`int` | :tl:`Message`, optional):
|
||||||
Whether to reply to a message or not. If an integer is provided,
|
Whether to reply to a message or not. If an integer is provided,
|
||||||
it should be the ID of the message that it should reply to.
|
it should be the ID of the message that it should reply to.
|
||||||
|
|
||||||
@ -740,7 +741,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Has no effect when sending a file.
|
Has no effect when sending a file.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
the sent message.
|
The sent :tl:`Message`.
|
||||||
"""
|
"""
|
||||||
if file is not None:
|
if file is not None:
|
||||||
return self.send_file(
|
return self.send_file(
|
||||||
@ -806,7 +807,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
entity (:obj:`entity`):
|
entity (:obj:`entity`):
|
||||||
To which entity the message(s) will be forwarded.
|
To which entity the message(s) will be forwarded.
|
||||||
|
|
||||||
messages (:obj:`list` | :obj:`int` | :obj:`Message`):
|
messages (:obj:`list` | :obj:`int` | :tl:`Message`):
|
||||||
The message(s) to forward, or their integer IDs.
|
The message(s) to forward, or their integer IDs.
|
||||||
|
|
||||||
from_peer (:obj:`entity`):
|
from_peer (:obj:`entity`):
|
||||||
@ -815,7 +816,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
order for the forward to work.
|
order for the forward to work.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The forwarded messages.
|
The list of forwarded :tl:`Message`.
|
||||||
"""
|
"""
|
||||||
if not utils.is_list_like(messages):
|
if not utils.is_list_like(messages):
|
||||||
messages = (messages,)
|
messages = (messages,)
|
||||||
@ -882,7 +883,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
not modified at all.
|
not modified at all.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
the edited message
|
The edited :tl:`Message`.
|
||||||
"""
|
"""
|
||||||
message, msg_entities = self._parse_message_text(message, parse_mode)
|
message, msg_entities = self._parse_message_text(message, parse_mode)
|
||||||
request = EditMessageRequest(
|
request = EditMessageRequest(
|
||||||
@ -905,7 +906,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
be ``None`` for normal chats, but **must** be present
|
be ``None`` for normal chats, but **must** be present
|
||||||
for channels and megagroups.
|
for channels and megagroups.
|
||||||
|
|
||||||
message_ids (:obj:`list` | :obj:`int` | :obj:`Message`):
|
message_ids (:obj:`list` | :obj:`int` | :tl:`Message`):
|
||||||
The IDs (or ID) or messages to be deleted.
|
The IDs (or ID) or messages to be deleted.
|
||||||
|
|
||||||
revoke (:obj:`bool`, optional):
|
revoke (:obj:`bool`, optional):
|
||||||
@ -915,7 +916,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
This has no effect on channels or megagroups.
|
This has no effect on channels or megagroups.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The affected messages.
|
The :tl:`AffectedMessages`.
|
||||||
"""
|
"""
|
||||||
if not utils.is_list_like(message_ids):
|
if not utils.is_list_like(message_ids):
|
||||||
message_ids = (message_ids,)
|
message_ids = (message_ids,)
|
||||||
@ -978,7 +979,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
you are still free to do so.
|
you are still free to do so.
|
||||||
|
|
||||||
wait_time (:obj:`int`):
|
wait_time (:obj:`int`):
|
||||||
Wait time between different ``GetHistoryRequest``. Use this
|
Wait time between different :tl:`GetHistoryRequest`. Use this
|
||||||
parameter to avoid hitting the ``FloodWaitError`` as needed.
|
parameter to avoid hitting the ``FloodWaitError`` as needed.
|
||||||
If left to ``None``, it will default to 1 second only if
|
If left to ``None``, it will default to 1 second only if
|
||||||
the limit is higher than 3000.
|
the limit is higher than 3000.
|
||||||
@ -987,7 +988,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
A single-item list to pass the total parameter by reference.
|
A single-item list to pass the total parameter by reference.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
Instances of ``telethon.tl.types.Message`` with extra attributes:
|
Instances of :tl:`Message` with extra attributes:
|
||||||
|
|
||||||
* ``.sender`` = entity of the sender.
|
* ``.sender`` = entity of the sender.
|
||||||
* ``.fwd_from.sender`` = if fwd_from, who sent it originally.
|
* ``.fwd_from.sender`` = if fwd_from, who sent it originally.
|
||||||
@ -995,7 +996,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
* ``.to`` = entity to which the message was sent.
|
* ``.to`` = entity to which the message was sent.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
Telegram's flood wait limit for ``GetHistoryRequest`` seems to
|
Telegram's flood wait limit for :tl:`GetHistoryRequest` seems to
|
||||||
be around 30 seconds per 3000 messages, therefore a sleep of 1
|
be around 30 seconds per 3000 messages, therefore a sleep of 1
|
||||||
second is the default for this limit (or above). You may need
|
second is the default for this limit (or above). You may need
|
||||||
an higher limit, so you're free to set the ``batch_size`` that
|
an higher limit, so you're free to set the ``batch_size`` that
|
||||||
@ -1101,7 +1102,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
entity (:obj:`entity`):
|
entity (:obj:`entity`):
|
||||||
The chat where these messages are located.
|
The chat where these messages are located.
|
||||||
|
|
||||||
message (:obj:`list` | :obj:`Message`):
|
message (:obj:`list` | :tl:`Message`):
|
||||||
Either a list of messages or a single message.
|
Either a list of messages or a single message.
|
||||||
|
|
||||||
max_id (:obj:`int`):
|
max_id (:obj:`int`):
|
||||||
@ -1172,9 +1173,8 @@ class TelegramClient(TelegramBareClient):
|
|||||||
search (:obj:`str`, optional):
|
search (:obj:`str`, optional):
|
||||||
Look for participants with this string in name/username.
|
Look for participants with this string in name/username.
|
||||||
|
|
||||||
filter (:obj:`ChannelParticipantsFilter`, optional):
|
filter (:tl:`ChannelParticipantsFilter`, optional):
|
||||||
The filter to be used, if you want e.g. only admins. See
|
The filter to be used, if you want e.g. only admins
|
||||||
https://lonamiwebs.github.io/Telethon/types/channel_participants_filter.html.
|
|
||||||
Note that you might not have permissions for some filter.
|
Note that you might not have permissions for some filter.
|
||||||
This has no effect for normal chats or users.
|
This has no effect for normal chats or users.
|
||||||
|
|
||||||
@ -1192,10 +1192,10 @@ class TelegramClient(TelegramBareClient):
|
|||||||
A single-item list to pass the total parameter by reference.
|
A single-item list to pass the total parameter by reference.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
The ``User`` objects returned by ``GetParticipantsRequest``
|
The :tl:`User` objects returned by :tl:`GetParticipantsRequest`
|
||||||
with an additional ``.participant`` attribute which is the
|
with an additional ``.participant`` attribute which is the
|
||||||
matched ``ChannelParticipant`` type for channels/megagroups
|
matched :tl:`ChannelParticipant` type for channels/megagroups
|
||||||
or ``ChatParticipants`` for normal chats.
|
or :tl:`ChatParticipants` for normal chats.
|
||||||
"""
|
"""
|
||||||
if isinstance(filter, type):
|
if isinstance(filter, type):
|
||||||
filter = filter()
|
filter = filter()
|
||||||
@ -1362,12 +1362,12 @@ class TelegramClient(TelegramBareClient):
|
|||||||
A callback function accepting two parameters:
|
A callback function accepting two parameters:
|
||||||
``(sent bytes, total)``.
|
``(sent bytes, total)``.
|
||||||
|
|
||||||
reply_to (:obj:`int` | :obj:`Message`):
|
reply_to (:obj:`int` | :tl:`Message`):
|
||||||
Same as reply_to from .send_message().
|
Same as reply_to from .send_message().
|
||||||
|
|
||||||
attributes (:obj:`list`, optional):
|
attributes (:obj:`list`, optional):
|
||||||
Optional attributes that override the inferred ones, like
|
Optional attributes that override the inferred ones, like
|
||||||
``DocumentAttributeFilename`` and so on.
|
:tl:`DocumentAttributeFilename` and so on.
|
||||||
|
|
||||||
thumb (:obj:`str` | :obj:`bytes` | :obj:`file`, optional):
|
thumb (:obj:`str` | :obj:`bytes` | :obj:`file`, optional):
|
||||||
Optional thumbnail (for videos).
|
Optional thumbnail (for videos).
|
||||||
@ -1390,7 +1390,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
it will be used to determine metadata from audio and video files.
|
it will be used to determine metadata from audio and video files.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The message (or messages) containing the sent file.
|
The :tl:`Message` (or messages) containing the sent file.
|
||||||
"""
|
"""
|
||||||
# First check if the user passed an iterable, in which case
|
# First check if the user passed an iterable, in which case
|
||||||
# we may want to send as an album if all are photo files.
|
# we may want to send as an album if all are photo files.
|
||||||
@ -1551,7 +1551,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
return msg
|
return msg
|
||||||
|
|
||||||
def send_voice_note(self, *args, **kwargs):
|
def send_voice_note(self, *args, **kwargs):
|
||||||
"""Wrapper method around .send_file() with is_voice_note=True"""
|
"""Wrapper method around :meth:`send_file` with is_voice_note=True."""
|
||||||
kwargs['is_voice_note'] = True
|
kwargs['is_voice_note'] = True
|
||||||
return self.send_file(*args, **kwargs)
|
return self.send_file(*args, **kwargs)
|
||||||
|
|
||||||
@ -1652,8 +1652,8 @@ class TelegramClient(TelegramBareClient):
|
|||||||
``(sent bytes, total)``.
|
``(sent bytes, total)``.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
``InputFileBig`` if the file size is larger than 10MB,
|
:tl:`InputFileBig` if the file size is larger than 10MB,
|
||||||
``InputSizedFile`` (subclass of ``InputFile``) otherwise.
|
``InputSizedFile`` (subclass of :tl:`InputFile`) otherwise.
|
||||||
"""
|
"""
|
||||||
if isinstance(file, (InputFile, InputFileBig)):
|
if isinstance(file, (InputFile, InputFileBig)):
|
||||||
return file # Already uploaded
|
return file # Already uploaded
|
||||||
@ -1836,7 +1836,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
"""
|
"""
|
||||||
Downloads the given media, or the media from a specified Message.
|
Downloads the given media, or the media from a specified Message.
|
||||||
|
|
||||||
message (:obj:`Message` | :obj:`Media`):
|
message (:tl:`Message` | :tl:`Media`):
|
||||||
The media or message containing the media that will be downloaded.
|
The media or message containing the media that will be downloaded.
|
||||||
|
|
||||||
file (:obj:`str` | :obj:`file`, optional):
|
file (:obj:`str` | :obj:`file`, optional):
|
||||||
@ -1845,7 +1845,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
|
|
||||||
progress_callback (:obj:`callable`, optional):
|
progress_callback (:obj:`callable`, optional):
|
||||||
A callback function accepting two parameters:
|
A callback function accepting two parameters:
|
||||||
``(recv bytes, total)``.
|
``(received bytes, total)``.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
``None`` if no media was provided, or if it was Empty. On success
|
``None`` if no media was provided, or if it was Empty. On success
|
||||||
@ -2065,7 +2065,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
Downloads the given input location to a file.
|
Downloads the given input location to a file.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
input_location (:obj:`InputFileLocation`):
|
input_location (:tl:`InputFileLocation`):
|
||||||
The file location from which the file will be downloaded.
|
The file location from which the file will be downloaded.
|
||||||
|
|
||||||
file (:obj:`str` | :obj:`file`):
|
file (:obj:`str` | :obj:`file`):
|
||||||
@ -2293,7 +2293,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
"""
|
"""
|
||||||
Turns the given entity into a valid Telegram user or chat.
|
Turns the given entity into a valid Telegram user or chat.
|
||||||
|
|
||||||
entity (:obj:`str` | :obj:`int` | :obj:`Peer` | :obj:`InputPeer`):
|
entity (:obj:`str` | :obj:`int` | :tl:`Peer` | :tl:`InputPeer`):
|
||||||
The entity (or iterable of entities) to be transformed.
|
The entity (or iterable of entities) to be transformed.
|
||||||
If it's a string which can be converted to an integer or starts
|
If it's a string which can be converted to an integer or starts
|
||||||
with '+' it will be resolved as if it were a phone number.
|
with '+' it will be resolved as if it were a phone number.
|
||||||
@ -2309,7 +2309,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
error will be raised.
|
error will be raised.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
``User``, ``Chat`` or ``Channel`` corresponding to the input
|
:tl:`User`, :tl:`Chat` or :tl:`Channel` corresponding to the input
|
||||||
entity.
|
entity.
|
||||||
"""
|
"""
|
||||||
if utils.is_list_like(entity):
|
if utils.is_list_like(entity):
|
||||||
@ -2410,9 +2410,9 @@ class TelegramClient(TelegramBareClient):
|
|||||||
use this kind of InputUser, InputChat and so on, so this is the
|
use this kind of InputUser, InputChat and so on, so this is the
|
||||||
most suitable call to make for those cases.
|
most suitable call to make for those cases.
|
||||||
|
|
||||||
entity (:obj:`str` | :obj:`int` | :obj:`Peer` | :obj:`InputPeer`):
|
entity (:obj:`str` | :obj:`int` | :tl:`Peer` | :tl:`InputPeer`):
|
||||||
The integer ID of an user or otherwise either of a
|
The integer ID of an user or otherwise either of a
|
||||||
``PeerUser``, ``PeerChat`` or ``PeerChannel``, for
|
:tl:`PeerUser`, :tl:`PeerChat` or :tl:`PeerChannel`, for
|
||||||
which to get its ``Input*`` version.
|
which to get its ``Input*`` version.
|
||||||
|
|
||||||
If this ``Peer`` hasn't been seen before by the library, the top
|
If this ``Peer`` hasn't been seen before by the library, the top
|
||||||
@ -2423,7 +2423,7 @@ class TelegramClient(TelegramBareClient):
|
|||||||
a ValueError will be raised.
|
a ValueError will be raised.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
``InputPeerUser``, ``InputPeerChat`` or ``InputPeerChannel``.
|
:tl:`InputPeerUser`, :tl:`InputPeerChat` or :tl:`InputPeerChannel`.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# First try to get the entity from cache, otherwise figure it out
|
# First try to get the entity from cache, otherwise figure it out
|
||||||
|
@ -10,13 +10,13 @@ class Dialog:
|
|||||||
return instances of this class when calling :meth:`.get_dialogs()`.
|
return instances of this class when calling :meth:`.get_dialogs()`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
dialog (:obj:`Dialog`):
|
dialog (:tl:`Dialog`):
|
||||||
The original ``Dialog`` instance.
|
The original ``Dialog`` instance.
|
||||||
|
|
||||||
pinned (:obj:`bool`):
|
pinned (:obj:`bool`):
|
||||||
Whether this dialog is pinned to the top or not.
|
Whether this dialog is pinned to the top or not.
|
||||||
|
|
||||||
message (:obj:`Message`):
|
message (:tl:`Message`):
|
||||||
The last message sent on this dialog. Note that this member
|
The last message sent on this dialog. Note that this member
|
||||||
will not be updated when new messages arrive, it's only set
|
will not be updated when new messages arrive, it's only set
|
||||||
on creation of the instance.
|
on creation of the instance.
|
||||||
@ -27,7 +27,7 @@ class Dialog:
|
|||||||
entity (:obj:`entity`):
|
entity (:obj:`entity`):
|
||||||
The entity that belongs to this dialog (user, chat or channel).
|
The entity that belongs to this dialog (user, chat or channel).
|
||||||
|
|
||||||
input_entity (:obj:`InputPeer`):
|
input_entity (:tl:`InputPeer`):
|
||||||
Input version of the entity.
|
Input version of the entity.
|
||||||
|
|
||||||
id (:obj:`int`):
|
id (:obj:`int`):
|
||||||
|
@ -128,7 +128,7 @@ class Draft:
|
|||||||
def send(self, clear=True, parse_mode='md'):
|
def send(self, clear=True, parse_mode='md'):
|
||||||
"""
|
"""
|
||||||
Sends the contents of this draft to the dialog. This is just a
|
Sends the contents of this draft to the dialog. This is just a
|
||||||
wrapper around send_message(dialog.input_entity, *args, **kwargs).
|
wrapper around ``send_message(dialog.input_entity, *args, **kwargs)``.
|
||||||
"""
|
"""
|
||||||
self._client.send_message(self._peer, self.text,
|
self._client.send_message(self._peer, self.text,
|
||||||
reply_to=self.reply_to_msg_id,
|
reply_to=self.reply_to_msg_id,
|
||||||
|
@ -11,8 +11,9 @@ __log__ = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
class UpdateState:
|
class UpdateState:
|
||||||
"""Used to hold the current state of processed updates.
|
"""
|
||||||
To retrieve an update, .poll() should be called.
|
Used to hold the current state of processed updates.
|
||||||
|
To retrieve an update, :meth:`poll` should be called.
|
||||||
"""
|
"""
|
||||||
WORKER_POLL_TIMEOUT = 5.0 # Avoid waiting forever on the workers
|
WORKER_POLL_TIMEOUT = 5.0 # Avoid waiting forever on the workers
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ VALID_USERNAME_RE = re.compile(r'^[a-zA-Z][\w\d]{3,30}[a-zA-Z\d]$')
|
|||||||
|
|
||||||
def get_display_name(entity):
|
def get_display_name(entity):
|
||||||
"""
|
"""
|
||||||
Gets the display name for the given entity, if it's an ``User``,
|
Gets the display name for the given entity, if it's an :tl:`User`,
|
||||||
``Chat`` or ``Channel``. Returns an empty string otherwise.
|
:tl:`Chat` or :tl:`Channel`. Returns an empty string otherwise.
|
||||||
"""
|
"""
|
||||||
if isinstance(entity, User):
|
if isinstance(entity, User):
|
||||||
if entity.last_name and entity.first_name:
|
if entity.last_name and entity.first_name:
|
||||||
@ -58,7 +58,7 @@ def get_display_name(entity):
|
|||||||
|
|
||||||
|
|
||||||
def get_extension(media):
|
def get_extension(media):
|
||||||
"""Gets the corresponding extension for any Telegram media"""
|
"""Gets the corresponding extension for any Telegram media."""
|
||||||
|
|
||||||
# Photos are always compressed as .jpg by Telegram
|
# Photos are always compressed as .jpg by Telegram
|
||||||
if isinstance(media, (UserProfilePhoto, ChatPhoto, MessageMediaPhoto)):
|
if isinstance(media, (UserProfilePhoto, ChatPhoto, MessageMediaPhoto)):
|
||||||
@ -83,8 +83,10 @@ def _raise_cast_fail(entity, target):
|
|||||||
|
|
||||||
|
|
||||||
def get_input_peer(entity, allow_self=True):
|
def get_input_peer(entity, allow_self=True):
|
||||||
"""Gets the input peer for the given "entity" (user, chat or channel).
|
"""
|
||||||
A TypeError is raised if the given entity isn't a supported type."""
|
Gets the input peer for the given "entity" (user, chat or channel).
|
||||||
|
A ``TypeError`` is raised if the given entity isn't a supported type.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
if entity.SUBCLASS_OF_ID == 0xc91c90b6: # crc32(b'InputPeer')
|
if entity.SUBCLASS_OF_ID == 0xc91c90b6: # crc32(b'InputPeer')
|
||||||
return entity
|
return entity
|
||||||
@ -129,7 +131,7 @@ def get_input_peer(entity, allow_self=True):
|
|||||||
|
|
||||||
|
|
||||||
def get_input_channel(entity):
|
def get_input_channel(entity):
|
||||||
"""Similar to get_input_peer, but for InputChannel's alone"""
|
"""Similar to :meth:`get_input_peer`, but for :tl:`InputChannel`'s alone."""
|
||||||
try:
|
try:
|
||||||
if entity.SUBCLASS_OF_ID == 0x40f202fd: # crc32(b'InputChannel')
|
if entity.SUBCLASS_OF_ID == 0x40f202fd: # crc32(b'InputChannel')
|
||||||
return entity
|
return entity
|
||||||
@ -146,7 +148,7 @@ def get_input_channel(entity):
|
|||||||
|
|
||||||
|
|
||||||
def get_input_user(entity):
|
def get_input_user(entity):
|
||||||
"""Similar to get_input_peer, but for InputUser's alone"""
|
"""Similar to :meth:`get_input_peer`, but for :tl:`InputUser`'s alone."""
|
||||||
try:
|
try:
|
||||||
if entity.SUBCLASS_OF_ID == 0xe669bf46: # crc32(b'InputUser'):
|
if entity.SUBCLASS_OF_ID == 0xe669bf46: # crc32(b'InputUser'):
|
||||||
return entity
|
return entity
|
||||||
@ -175,7 +177,7 @@ def get_input_user(entity):
|
|||||||
|
|
||||||
|
|
||||||
def get_input_document(document):
|
def get_input_document(document):
|
||||||
"""Similar to get_input_peer, but for documents"""
|
"""Similar to :meth:`get_input_peer`, but for documents"""
|
||||||
try:
|
try:
|
||||||
if document.SUBCLASS_OF_ID == 0xf33fdb68: # crc32(b'InputDocument'):
|
if document.SUBCLASS_OF_ID == 0xf33fdb68: # crc32(b'InputDocument'):
|
||||||
return document
|
return document
|
||||||
@ -198,7 +200,7 @@ def get_input_document(document):
|
|||||||
|
|
||||||
|
|
||||||
def get_input_photo(photo):
|
def get_input_photo(photo):
|
||||||
"""Similar to get_input_peer, but for documents"""
|
"""Similar to :meth:`get_input_peer`, but for photos"""
|
||||||
try:
|
try:
|
||||||
if photo.SUBCLASS_OF_ID == 0x846363e0: # crc32(b'InputPhoto'):
|
if photo.SUBCLASS_OF_ID == 0x846363e0: # crc32(b'InputPhoto'):
|
||||||
return photo
|
return photo
|
||||||
@ -218,7 +220,7 @@ def get_input_photo(photo):
|
|||||||
|
|
||||||
|
|
||||||
def get_input_geo(geo):
|
def get_input_geo(geo):
|
||||||
"""Similar to get_input_peer, but for geo points"""
|
"""Similar to :meth:`get_input_peer`, but for geo points"""
|
||||||
try:
|
try:
|
||||||
if geo.SUBCLASS_OF_ID == 0x430d225: # crc32(b'InputGeoPoint'):
|
if geo.SUBCLASS_OF_ID == 0x430d225: # crc32(b'InputGeoPoint'):
|
||||||
return geo
|
return geo
|
||||||
@ -241,10 +243,11 @@ def get_input_geo(geo):
|
|||||||
|
|
||||||
|
|
||||||
def get_input_media(media, is_photo=False):
|
def get_input_media(media, is_photo=False):
|
||||||
"""Similar to get_input_peer, but for media.
|
"""
|
||||||
|
Similar to :meth:`get_input_peer`, but for media.
|
||||||
|
|
||||||
If the media is a file location and is_photo is known to be True,
|
If the media is a file location and ``is_photo`` is known to be ``True``,
|
||||||
it will be treated as an InputMediaUploadedPhoto.
|
it will be treated as an :tl:`InputMediaUploadedPhoto`.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if media.SUBCLASS_OF_ID == 0xfaf846f4: # crc32(b'InputMedia'):
|
if media.SUBCLASS_OF_ID == 0xfaf846f4: # crc32(b'InputMedia'):
|
||||||
@ -317,7 +320,7 @@ def get_input_media(media, is_photo=False):
|
|||||||
|
|
||||||
def is_image(file):
|
def is_image(file):
|
||||||
"""
|
"""
|
||||||
Returns True if the file extension looks like an image file to Telegram.
|
Returns ``True`` if the file extension looks like an image file to Telegram.
|
||||||
"""
|
"""
|
||||||
if not isinstance(file, str):
|
if not isinstance(file, str):
|
||||||
return False
|
return False
|
||||||
@ -326,23 +329,23 @@ def is_image(file):
|
|||||||
|
|
||||||
|
|
||||||
def is_audio(file):
|
def is_audio(file):
|
||||||
"""Returns True if the file extension looks like an audio file"""
|
"""Returns ``True`` if the file extension looks like an audio file."""
|
||||||
return (isinstance(file, str) and
|
return (isinstance(file, str) and
|
||||||
(mimetypes.guess_type(file)[0] or '').startswith('audio/'))
|
(mimetypes.guess_type(file)[0] or '').startswith('audio/'))
|
||||||
|
|
||||||
|
|
||||||
def is_video(file):
|
def is_video(file):
|
||||||
"""Returns True if the file extension looks like a video file"""
|
"""Returns ``True`` if the file extension looks like a video file."""
|
||||||
return (isinstance(file, str) and
|
return (isinstance(file, str) and
|
||||||
(mimetypes.guess_type(file)[0] or '').startswith('video/'))
|
(mimetypes.guess_type(file)[0] or '').startswith('video/'))
|
||||||
|
|
||||||
|
|
||||||
def is_list_like(obj):
|
def is_list_like(obj):
|
||||||
"""
|
"""
|
||||||
Returns True if the given object looks like a list.
|
Returns ``True`` if the given object looks like a list.
|
||||||
|
|
||||||
Checking if hasattr(obj, '__iter__') and ignoring str/bytes is not
|
Checking ``if hasattr(obj, '__iter__')`` and ignoring ``str/bytes`` is not
|
||||||
enough. Things like open() are also iterable (and probably many
|
enough. Things like ``open()`` are also iterable (and probably many
|
||||||
other things), so just support the commonly known list-like objects.
|
other things), so just support the commonly known list-like objects.
|
||||||
"""
|
"""
|
||||||
return isinstance(obj, (list, tuple, set, dict,
|
return isinstance(obj, (list, tuple, set, dict,
|
||||||
@ -350,7 +353,7 @@ def is_list_like(obj):
|
|||||||
|
|
||||||
|
|
||||||
def parse_phone(phone):
|
def parse_phone(phone):
|
||||||
"""Parses the given phone, or returns None if it's invalid"""
|
"""Parses the given phone, or returns ``None`` if it's invalid."""
|
||||||
if isinstance(phone, int):
|
if isinstance(phone, int):
|
||||||
return str(phone)
|
return str(phone)
|
||||||
else:
|
else:
|
||||||
@ -365,7 +368,7 @@ def parse_username(username):
|
|||||||
both the stripped, lowercase username and whether it is
|
both the stripped, lowercase username and whether it is
|
||||||
a joinchat/ hash (in which case is not lowercase'd).
|
a joinchat/ hash (in which case is not lowercase'd).
|
||||||
|
|
||||||
Returns None if the username is not valid.
|
Returns ``None`` if the ``username`` is not valid.
|
||||||
"""
|
"""
|
||||||
username = username.strip()
|
username = username.strip()
|
||||||
m = USERNAME_RE.match(username)
|
m = USERNAME_RE.match(username)
|
||||||
@ -386,7 +389,7 @@ def parse_username(username):
|
|||||||
def _fix_peer_id(peer_id):
|
def _fix_peer_id(peer_id):
|
||||||
"""
|
"""
|
||||||
Fixes the peer ID for chats and channels, in case the users
|
Fixes the peer ID for chats and channels, in case the users
|
||||||
mix marking the ID with the ``Peer()`` constructors.
|
mix marking the ID with the :tl:`Peer` constructors.
|
||||||
"""
|
"""
|
||||||
peer_id = abs(peer_id)
|
peer_id = abs(peer_id)
|
||||||
if str(peer_id).startswith('100'):
|
if str(peer_id).startswith('100'):
|
||||||
@ -401,7 +404,7 @@ def get_peer_id(peer):
|
|||||||
chat ID is negated, and channel ID is prefixed with -100.
|
chat ID is negated, and channel ID is prefixed with -100.
|
||||||
|
|
||||||
The original ID and the peer type class can be returned with
|
The original ID and the peer type class can be returned with
|
||||||
a call to utils.resolve_id(marked_id).
|
a call to :meth:`resolve_id(marked_id)`.
|
||||||
"""
|
"""
|
||||||
# First we assert it's a Peer TLObject, or early return for integers
|
# First we assert it's a Peer TLObject, or early return for integers
|
||||||
if isinstance(peer, int):
|
if isinstance(peer, int):
|
||||||
@ -450,7 +453,7 @@ def get_peer_id(peer):
|
|||||||
|
|
||||||
|
|
||||||
def resolve_id(marked_id):
|
def resolve_id(marked_id):
|
||||||
"""Given a marked ID, returns the original ID and its Peer type"""
|
"""Given a marked ID, returns the original ID and its :tl:`Peer` type."""
|
||||||
if marked_id >= 0:
|
if marked_id >= 0:
|
||||||
return marked_id, PeerUser
|
return marked_id, PeerUser
|
||||||
|
|
||||||
@ -461,8 +464,10 @@ def resolve_id(marked_id):
|
|||||||
|
|
||||||
|
|
||||||
def get_appropriated_part_size(file_size):
|
def get_appropriated_part_size(file_size):
|
||||||
"""Gets the appropriated part size when uploading or downloading files,
|
"""
|
||||||
given an initial file size"""
|
Gets the appropriated part size when uploading or downloading files,
|
||||||
|
given an initial file size.
|
||||||
|
"""
|
||||||
if file_size <= 104857600: # 100MB
|
if file_size <= 104857600: # 100MB
|
||||||
return 128
|
return 128
|
||||||
if file_size <= 786432000: # 750MB
|
if file_size <= 786432000: # 750MB
|
||||||
|
Loading…
Reference in New Issue
Block a user