mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-08 04:52:30 +00:00
Add a custom role for TL references and make use of it
This commit is contained in:
@@ -17,15 +17,16 @@
|
||||
# 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.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
import os
|
||||
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))
|
||||
|
||||
tl_ref_url = 'https://lonamiwebs.github.io/Telethon'
|
||||
|
||||
|
||||
# -- 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
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'custom_roles'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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 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.
|
||||
|
||||
How can we retrieve this ``InputPeer``? We have two options. We manually
|
||||
`construct one`__, for instance:
|
||||
How can we retrieve this :tl:`InputPeer`? We have two options. We manually
|
||||
construct one, for instance:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -64,7 +64,7 @@ Or we call ``.get_input_entity()``:
|
||||
peer = client.get_input_entity('someone')
|
||||
|
||||
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
|
||||
immediate, if you've seen the user before, know their ID, etc.).
|
||||
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/methods/index.html
|
||||
__ 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
|
||||
to any ``User``, ``Chat`` or ``Channel`` object that the API may return
|
||||
in response to certain methods, such as ``GetUsersRequest``.
|
||||
to any :tl:`User`, :tl:`Chat` or :tl:`Channel` object that the API may return
|
||||
in response to certain methods, such as :tl:`GetUsersRequest`.
|
||||
|
||||
.. note::
|
||||
|
||||
When something "entity-like" is required, it means that you need to
|
||||
provide something that can be turned into an entity. These things include,
|
||||
but are not limited to, usernames, exact titles, IDs, ``Peer`` objects,
|
||||
or even entire ``User``, ``Chat`` and ``Channel`` objects and even phone
|
||||
numbers from people you have in your contacts.
|
||||
but are not limited to, usernames, exact titles, IDs, :tl:`Peer` objects,
|
||||
or even entire :tl:`User`, :tl:`Chat` and :tl:`Channel` objects and even
|
||||
phone numbers from people you have in your contacts.
|
||||
|
||||
Getting entities
|
||||
****************
|
||||
@@ -73,7 +73,7 @@ become possible.
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
@@ -90,14 +90,14 @@ Entities vs. Input Entities
|
||||
|
||||
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.
|
||||
``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
|
||||
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
|
||||
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
|
||||
peers alone are not enough to use them. You need to know their hash
|
||||
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,
|
||||
``.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,
|
||||
if you provided the full entity, e.g. an ``User``, the library will convert
|
||||
it to the required ``InputPeer`` automatically for you.
|
||||
if you provided the full entity, e.g. an :tl:`User`, the library will convert
|
||||
it to the required :tl:`InputPeer` automatically for you.
|
||||
|
||||
**You should always favour** ``.get_input_entity()`` **over** ``.get_entity()``
|
||||
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'))
|
||||
|
||||
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.
|
||||
|
@@ -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
|
||||
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
|
||||
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
|
||||
only done on object construction.
|
||||
|
||||
|
Reference in New Issue
Block a user