mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Finally some good ****ing docs
This commit is contained in:
parent
aa74c8f859
commit
0d5ca685f3
37 changed files with 2417 additions and 260 deletions
29
README.md
29
README.md
|
@ -10,17 +10,28 @@ A multipurpose bot framework and webserver
|
|||
|
||||
- [Telegram](https://core.telegram.org/bots)
|
||||
- [Discord](https://discordapp.com/developers/docs/)
|
||||
- [Matrix]() (no E2E support yet)
|
||||
- [Matrix](https://matrix.org/) (no E2E support yet)
|
||||
|
||||
## Installing
|
||||
|
||||
To install `royalnet`, run:
|
||||
```
|
||||
pip install royalnet
|
||||
```
|
||||
|
||||
To install a specific module, run:
|
||||
```
|
||||
pip install royalnet[MODULENAME]
|
||||
```
|
||||
|
||||
To install all `royalnet` modules, run:
|
||||
|
||||
```
|
||||
royalnet[telegram,discord,alchemy_easy,bard,constellation,sentry,herald,coloredlogs]
|
||||
pip install royalnet[telegram,discord,matrix,alchemy_easy,bard,constellation,sentry,herald,coloredlogs]
|
||||
```
|
||||
|
||||
> You will soon be able to install only the modules you need instead of the full package, but the feature isn't ready yet...
|
||||
## Documentation
|
||||
|
||||
`royalnet`'s documentation is available [here](https://gh.steffo.eu/royalnet).
|
||||
|
||||
## Developing `royalnet`
|
||||
|
||||
|
@ -41,13 +52,5 @@ cd royalnet
|
|||
And finally install all dependencies and the package:
|
||||
|
||||
```
|
||||
poetry install -E telegram -E discord -E alchemy_easy -E bard -E constellation -E sentry -E herald -E coloredlogs
|
||||
poetry install -E telegram -E discord -E matrix -E alchemy_easy -E bard -E constellation -E sentry -E herald -E coloredlogs
|
||||
```
|
||||
|
||||
## Developing `royalnet` packages
|
||||
|
||||
See the [royalnet-pack-template](https://github.com/Steffo99/royalnet-pack-template) project.
|
||||
|
||||
## Documentation
|
||||
|
||||
`royalnet`'s documentation is available [here](https://gh.steffo.eu/royalnet).
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/doctrees/packs/command.doctree
Normal file
BIN
docs/doctrees/packs/command.doctree
Normal file
Binary file not shown.
BIN
docs/doctrees/packs/event.doctree
Normal file
BIN
docs/doctrees/packs/event.doctree
Normal file
Binary file not shown.
BIN
docs/doctrees/packs/pack.doctree
Normal file
BIN
docs/doctrees/packs/pack.doctree
Normal file
Binary file not shown.
BIN
docs/doctrees/packs/star.doctree
Normal file
BIN
docs/doctrees/packs/star.doctree
Normal file
Binary file not shown.
BIN
docs/doctrees/packs/table.doctree
Normal file
BIN
docs/doctrees/packs/table.doctree
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: 444318501c4e921b64eae4e12bd3ce08
|
||||
config: 59f01b51bca09082ff992b52b6e98cfc
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
royalnet
|
||||
Royalnet
|
||||
====================================
|
||||
|
||||
Welcome to the documentation of Royalnet!
|
||||
|
@ -6,6 +6,7 @@ Welcome to the documentation of Royalnet!
|
|||
.. toctree::
|
||||
:maxdepth: 5
|
||||
|
||||
packs/pack
|
||||
randomdiscoveries
|
||||
apireference
|
||||
|
||||
|
|
350
docs/html/_sources/packs/command.rst.txt
Normal file
350
docs/html/_sources/packs/command.rst.txt
Normal file
|
@ -0,0 +1,350 @@
|
|||
.. currentmodule:: royalnet.commands
|
||||
|
||||
Adding a Command to the Pack
|
||||
====================================
|
||||
|
||||
A Royalnet Command is a small script that is run whenever a specific message is sent to a Royalnet interface.
|
||||
|
||||
A Command code looks like this: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class PingCommand(rc.Command):
|
||||
name = "ping"
|
||||
|
||||
description = "Play ping-pong with the bot."
|
||||
|
||||
def __init__(self, interface):
|
||||
# This code is run just once, while the bot is starting
|
||||
super().__init__()
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData):
|
||||
# This code is run every time the command is called
|
||||
await data.reply("Pong!")
|
||||
|
||||
Creating a new Command
|
||||
------------------------------------
|
||||
|
||||
First, think of a ``name`` for your command.
|
||||
It's the name your command will be called with: for example, the "spaghetti" command will be called by typing **/spaghetti** in chat.
|
||||
Try to keep the name as short as possible, while staying specific enough so no other command will have the same name.
|
||||
|
||||
Next, create a new Python file with the ``name`` you have thought of.
|
||||
The previously mentioned "spaghetti" command should have a file called ``spaghetti.py``.
|
||||
|
||||
Then, in the first row of the file, import the :class:`Command` class from royalnet, and create a new class inheriting from it: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
...
|
||||
|
||||
Inside the class, override the attributes ``name`` and ``description`` with respectively the **name of the command** and a **small description of what the command will do**: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
name = "spaghetti"
|
||||
|
||||
description = "Send a spaghetti emoji in the chat."
|
||||
|
||||
Now override the :meth:`Command.run` method, adding the code you want the bot to run when the command is called.
|
||||
|
||||
To send a message in the chat the command was called in, you can use the :meth:`CommandData.reply` coroutine: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
name = "spaghetti"
|
||||
|
||||
description = "Send a spaghetti emoji in the chat."
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData):
|
||||
await data.reply("🍝")
|
||||
|
||||
And... it's done! The command is ready to be :doc:`added to your pack <pack>`!
|
||||
|
||||
Command arguments
|
||||
------------------------------------
|
||||
|
||||
A command can have some arguments passed by the user: for example, on Telegram an user may type `/spaghetti carbonara al-dente`
|
||||
to pass the :class:`str` `"carbonara al-dente"` to the command code.
|
||||
|
||||
These arguments can be accessed in multiple ways through the ``args`` parameter passed to the :meth:`Command.run`
|
||||
method.
|
||||
|
||||
If you want your command to use arguments, override the ``syntax`` class attribute with a brief description of the
|
||||
syntax of your command, possibly using {curly braces} for required arguments and [square brackets] for optional
|
||||
ones. ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
name = "spaghetti"
|
||||
|
||||
description = "Send a spaghetti emoji in the chat."
|
||||
|
||||
syntax = "(requestedpasta)"
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData):
|
||||
await data.reply(f"🍝 Here's your {args[0]}!")
|
||||
|
||||
|
||||
Direct access
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can consider arguments as if they were separated by spaces.
|
||||
|
||||
You can then access command arguments directly by number as if the args object was a list of :class:`str`.
|
||||
|
||||
If you request an argument with a certain number, but the argument does not exist, an
|
||||
:exc:`.InvalidInputError` is raised, making the arguments accessed in this way **required**. ::
|
||||
|
||||
args[0]
|
||||
# "carbonara"
|
||||
|
||||
args[1]
|
||||
# "al-dente"
|
||||
|
||||
args[2]
|
||||
# raises InvalidInputError
|
||||
|
||||
Optional access
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you don't want arguments to be required, you can access them through the :meth:`CommandArgs.optional` method: it
|
||||
will return ``None`` if the argument wasn't passed, making it **optional**. ::
|
||||
|
||||
args.optional(0)
|
||||
# "carbonara"
|
||||
|
||||
args.optional(1)
|
||||
# "al-dente"
|
||||
|
||||
args.optional(2)
|
||||
# None
|
||||
|
||||
You can specify a default result too, so that the method will return it instead of returning ``None``: ::
|
||||
|
||||
args.optional(2, default="banana")
|
||||
# "banana"
|
||||
|
||||
Full string
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want the full argument string, you can use the :meth:`CommandArgs.joined` method. ::
|
||||
|
||||
args.joined()
|
||||
# "carbonara al-dente"
|
||||
|
||||
You can specify a minimum number of arguments too, so that an :exc:`.InvalidInputError` will be
|
||||
raised if not enough arguments are present: ::
|
||||
|
||||
args.joined(require_at_least=3)
|
||||
# raises InvalidInputError
|
||||
|
||||
Regular expressions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For more complex commands, you may want to get arguments through `regular expressions <https://regexr.com/>`_.
|
||||
|
||||
You can then use the :meth:`CommandArgs.match` method, which tries to match a pattern to the command argument string,
|
||||
which returns a tuple of the matched groups and raises an :exc:`.InvalidInputError` if there is no match.
|
||||
|
||||
To match a pattern, :func:`re.match` is used, meaning that Python will try to match only at the beginning of the string. ::
|
||||
|
||||
args.match(r"(carb\w+)")
|
||||
# ("carbonara",)
|
||||
|
||||
args.match(r"(al-\w+)")
|
||||
# raises InvalidInputError
|
||||
|
||||
args.match(r"\s*(al-\w+)")
|
||||
# ("al-dente",)
|
||||
|
||||
args.match(r"\s*(carb\w+)\s*(al-\w+)")
|
||||
# ("carbonara", "al-dente")
|
||||
|
||||
Raising errors
|
||||
---------------------------------------------
|
||||
|
||||
If you want to display an error message to the user, you can raise a :exc:`.CommandError` using the error message as argument: ::
|
||||
|
||||
if not kitchen.is_open():
|
||||
raise CommandError("The kitchen is closed. Come back later!")
|
||||
|
||||
There are some subclasses of :exc:`.CommandError` that can be used for some more specific cases:
|
||||
|
||||
:exc:`.UserError`
|
||||
The user did something wrong, it is not a problem with the bot.
|
||||
|
||||
:exc:`.InvalidInputError`
|
||||
The arguments the user passed to the command by the user are invalid.
|
||||
Displays the command syntax in the error message.
|
||||
|
||||
:exc:`.UnsupportedError`
|
||||
The command is not supported on the interface it is being called.
|
||||
|
||||
:exc:`.ConfigurationError`
|
||||
The ``config.toml`` file was misconfigured (a value is missing or invalid).
|
||||
|
||||
:exc:`.ExternalError`
|
||||
An external API the command depends on is unavailable or returned an error.
|
||||
|
||||
:exc:`.ProgramError`
|
||||
An error caused by a programming mistake. Equivalent to :exc:`AssertionError`, but includes a message to facilitate debugging.
|
||||
|
||||
Coroutines and slow operations
|
||||
------------------------------------
|
||||
|
||||
You may have noticed that in the previous examples we used ``await data.reply("🍝")`` instead of just ``data.reply("🍝")``.
|
||||
|
||||
This is because :meth:`CommandData.reply` isn't a simple method: it is a coroutine, a special kind of function that
|
||||
can be executed separately from the rest of the code, allowing the bot to do other things in the meantime.
|
||||
|
||||
By adding the ``await`` keyword before the ``data.reply("🍝")``, we tell the bot that it can do other things, like
|
||||
receiving new messages, while the message is being sent.
|
||||
|
||||
You should avoid running slow normal functions inside bot commands, as they will stop the bot from working until they
|
||||
are finished and may cause bugs in other parts of the code! ::
|
||||
|
||||
async def run(self, args, data):
|
||||
# Don't do this!
|
||||
image = download_1_terabyte_of_spaghetti("right_now", from="italy")
|
||||
...
|
||||
|
||||
If the slow function you want does not cause any side effect, you can wrap it with the :func:`royalnet.utils.asyncify`
|
||||
function: ::
|
||||
|
||||
async def run(self, args, data):
|
||||
# If the called function has no side effect, you can do this!
|
||||
image = await asyncify(download_1_terabyte_of_spaghetti, "right_now", from="italy")
|
||||
...
|
||||
|
||||
Avoid using :func:`time.sleep` function, as it is considered a slow operation: use instead :func:`asyncio.sleep`,
|
||||
a coroutine that does the same exact thing but in an asyncronous way.
|
||||
|
||||
Delete the invoking message
|
||||
------------------------------------
|
||||
|
||||
The invoking message of a command is the message that the user sent that the bot recognized as a command; for example,
|
||||
the message ``/spaghetti carbonara`` is the invoking message for the ``spaghetti`` command run.
|
||||
|
||||
You can have the bot delete the invoking message for a command by calling the :class:`CommandData.delete_invoking`
|
||||
method: ::
|
||||
|
||||
async def run(self, args, data):
|
||||
await data.delete_invoking()
|
||||
|
||||
Not all interfaces support deleting messages; by default, if the interface does not support deletions, the call is
|
||||
ignored.
|
||||
|
||||
You can have the method raise an error if the message can't be deleted by setting the ``error_if_unavailable`` parameter
|
||||
to True: ::
|
||||
|
||||
async def run(self, args, data):
|
||||
try:
|
||||
await data.delete_invoking(error_if_unavailable=True)
|
||||
except royalnet.error.UnsupportedError:
|
||||
await data.reply("🚫 The message could not be deleted.")
|
||||
else:
|
||||
await data.reply("✅ The message was deleted!")
|
||||
|
||||
Using the database
|
||||
------------------------------------
|
||||
|
||||
Bots can be connected to a PostgreSQL database through a special SQLAlchemy interface called
|
||||
:class:`royalnet.alchemy.Alchemy`.
|
||||
|
||||
If the connection is established, the ``self.alchemy`` and ``data.session`` fields will be
|
||||
available for use in commands.
|
||||
|
||||
``self.alchemy`` is an instance of :class:`royalnet.alchemy.Alchemy`, which contains the
|
||||
:class:`sqlalchemy.engine.Engine`, metadata and tables, while ``data.session`` is a
|
||||
:class:`sqlalchemy.orm.session.Session`, and can be interacted in the same way as one.
|
||||
|
||||
Querying the database
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can :class:`sqlalchemy.orm.query.Query` the database using the SQLAlchemy ORM.
|
||||
|
||||
The SQLAlchemy tables can be found inside :class:`royalnet.alchemy.Alchemy` with the :meth:`royalnet.alchemy.Alchemy.get` method: ::
|
||||
|
||||
import royalnet.backpack.tables as rbt
|
||||
User = self.alchemy.get(rbt.User)
|
||||
|
||||
Adding filters to the query
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can filter the query results with the :meth:`sqlalchemy.orm.query.Query.filter` method.
|
||||
|
||||
.. note:: Remember to always use a table column as first comparision element, as it won't work otherwise.
|
||||
|
||||
::
|
||||
|
||||
query = query.filter(User.role == "Member")
|
||||
|
||||
|
||||
Ordering the results of a query
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can order the query results in **ascending order** with the :meth:`sqlalchemy.orm.query.Query.order_by` method. ::
|
||||
|
||||
query = query.order_by(User.username)
|
||||
|
||||
Additionally, you can append the `.desc()` method to a table column to sort in **descending order**: ::
|
||||
|
||||
query = query.order_by(User.username.desc())
|
||||
|
||||
Fetching the results of a query
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can fetch the query results with the :meth:`sqlalchemy.orm.query.Query.all`,
|
||||
:meth:`sqlalchemy.orm.query.Query.first`, :meth:`sqlalchemy.orm.query.Query.one` and
|
||||
:meth:`sqlalchemy.orm.query.Query.one_or_none` methods.
|
||||
|
||||
Remember to use :func:`royalnet.utils.asyncify` when fetching results, as it may take a while!
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.all` if you want a :class:`list` of **all results**: ::
|
||||
|
||||
results: list = await asyncify(query.all)
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.first` if you want **the first result** of the list, or ``None`` if
|
||||
there are no results: ::
|
||||
|
||||
result: typing.Union[..., None] = await asyncify(query.first)
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.one` if you expect to have **a single result**, and you want the command to
|
||||
raise an error if any different number of results is returned: ::
|
||||
|
||||
result: ... = await asyncify(query.one) # Raises an error if there are no results or more than a result.
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.one_or_none` if you expect to have **a single result**, or **nothing**, and
|
||||
if you want the command to raise an error if the number of results is greater than one. ::
|
||||
|
||||
result: typing.Union[..., None] = await asyncify(query.one_or_none) # Raises an error if there is more than a result.
|
||||
|
||||
More Alchemy
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can read more about :mod:`sqlalchemy` at their `website <https://www.sqlalchemy.org/>`_.
|
||||
|
||||
Calling Events
|
||||
------------------------------------
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
Displaying Keyboards
|
||||
------------------------------------
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
Running code at the initialization of the bot
|
||||
---------------------------------------------
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
Running repeating jobs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This section is not documented yet.
|
4
docs/html/_sources/packs/event.rst.txt
Normal file
4
docs/html/_sources/packs/event.rst.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
Using Events
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
12
docs/html/_sources/packs/pack.rst.txt
Normal file
12
docs/html/_sources/packs/pack.rst.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
Creating a Royalnet Pack
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 5
|
||||
|
||||
command
|
||||
star
|
||||
event
|
||||
table
|
4
docs/html/_sources/packs/star.rst.txt
Normal file
4
docs/html/_sources/packs/star.rst.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
Adding a Star to the Pack
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
4
docs/html/_sources/packs/table.rst.txt
Normal file
4
docs/html/_sources/packs/table.rst.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
Using Tables and databases
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
|
@ -1,6 +1,6 @@
|
|||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '5.3.2',
|
||||
VERSION: '5.4a2',
|
||||
LANGUAGE: 'None',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>API Reference — Royalnet 5.3.2 documentation</title>
|
||||
<title>API Reference — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
|
||||
|
||||
<div class="version">
|
||||
5.3.2
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -85,6 +85,7 @@
|
|||
|
||||
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="packs/pack.html">Creating a Royalnet Pack</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">API Reference</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#module-royalnet.alchemy">Alchemy</a></li>
|
||||
|
@ -166,7 +167,17 @@
|
|||
<p>This page is autogenerated from the docstrings inside the code.</p>
|
||||
<div class="section" id="module-royalnet.alchemy">
|
||||
<span id="alchemy"></span><h2>Alchemy<a class="headerlink" href="#module-royalnet.alchemy" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Relational database classes and methods.</p>
|
||||
<p>The subpackage providing all functions and classes related to databases and tables.</p>
|
||||
<p>It requires either the <code class="docutils literal notranslate"><span class="pre">alchemy_easy</span></code> or the <code class="docutils literal notranslate"><span class="pre">alchemy_hard</span></code> extras to be installed.</p>
|
||||
<p>You can install <code class="docutils literal notranslate"><span class="pre">alchemy_easy</span></code> with:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">royalnet</span><span class="p">[</span><span class="n">alchemy_easy</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To install <code class="docutils literal notranslate"><span class="pre">alchemy_hard</span></code>, refer to the <a href="#id5"><span class="problematic" id="id6">`psycopg2 <https://pypi.org/project/psycopg2/>}`_</span></a> installation instructions,
|
||||
then run:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">royalnet</span><span class="p">[</span><span class="n">alchemy_hard</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<dl class="class">
|
||||
<dt id="royalnet.alchemy.Alchemy">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.alchemy.</code><code class="sig-name descname">Alchemy</code><span class="sig-paren">(</span><em class="sig-param">database_uri: str</em>, <em class="sig-param">tables: Set</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.alchemy.Alchemy" title="Permalink to this definition">¶</a></dt>
|
||||
|
@ -262,10 +273,15 @@ Check the tables submodule for more details.</p></li>
|
|||
<div class="section" id="module-royalnet.backpack">
|
||||
<span id="backpack"></span><h2>Backpack<a class="headerlink" href="#module-royalnet.backpack" title="Permalink to this headline">¶</a></h2>
|
||||
<p>A Pack that is imported by default by all Royalnet instances.</p>
|
||||
<p>Keep things here to a minimum!</p>
|
||||
</div>
|
||||
<div class="section" id="module-royalnet.bard">
|
||||
<span id="bard"></span><h2>Bard<a class="headerlink" href="#module-royalnet.bard" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The subpackage providing all classes related to music files.</p>
|
||||
<p>It requires the <code class="docutils literal notranslate"><span class="pre">bard</span></code> extra to be installed (the <code class="xref py py-mod docutils literal notranslate"><span class="pre">ffmpeg_python</span></code>, <code class="xref py py-mod docutils literal notranslate"><span class="pre">youtube_dl</span></code> and <code class="xref py py-mod docutils literal notranslate"><span class="pre">eyed3</span></code> packages).</p>
|
||||
<p>You can install it with:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">royalnet</span><span class="p">[</span><span class="n">bard</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<dl class="class">
|
||||
<dt id="royalnet.bard.YtdlInfo">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.bard.</code><code class="sig-name descname">YtdlInfo</code><span class="sig-paren">(</span><em class="sig-param">info: Dict[str, Any]</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.bard.YtdlInfo" title="Permalink to this definition">¶</a></dt>
|
||||
|
@ -367,92 +383,34 @@ Check the tables submodule for more details.</p></li>
|
|||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="class">
|
||||
<dt id="royalnet.bard.YtdlMp3">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.bard.</code><code class="sig-name descname">YtdlMp3</code><span class="sig-paren">(</span><em class="sig-param">ytdl_file: royalnet.bard.ytdlfile.YtdlFile</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.bard.YtdlMp3" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>A representation of a <a class="reference internal" href="#royalnet.bard.YtdlFile" title="royalnet.bard.YtdlFile"><code class="xref py py-class docutils literal notranslate"><span class="pre">YtdlFile</span></code></a> conversion to mp3.</p>
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlMp3.convert_to_mp3">
|
||||
<em class="property">async </em><code class="sig-name descname">convert_to_mp3</code><span class="sig-paren">(</span><span class="sig-paren">)</span> → None<a class="headerlink" href="#royalnet.bard.YtdlMp3.convert_to_mp3" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Convert the file to mp3 with <a class="reference external" href="https://kkroening.github.io/ffmpeg-python/index.html#module-ffmpeg" title="(in ffmpeg-python)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ffmpeg</span></code></a>.</p>
|
||||
<dl class="exception">
|
||||
<dt id="royalnet.bard.BardError">
|
||||
<em class="property">exception </em><code class="sig-prename descclassname">royalnet.bard.</code><code class="sig-name descname">BardError</code><a class="headerlink" href="#royalnet.bard.BardError" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Base class for <code class="xref py py-mod docutils literal notranslate"><span class="pre">bard</span></code> errors.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlMp3.delete_asap">
|
||||
<em class="property">async </em><code class="sig-name descname">delete_asap</code><span class="sig-paren">(</span><span class="sig-paren">)</span> → None<a class="headerlink" href="#royalnet.bard.YtdlMp3.delete_asap" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Delete the mp3 file.</p>
|
||||
<dl class="exception">
|
||||
<dt id="royalnet.bard.YtdlError">
|
||||
<em class="property">exception </em><code class="sig-prename descclassname">royalnet.bard.</code><code class="sig-name descname">YtdlError</code><a class="headerlink" href="#royalnet.bard.YtdlError" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Base class for errors caused by <code class="xref py py-mod docutils literal notranslate"><span class="pre">youtube_dl</span></code>.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlMp3.from_url">
|
||||
<em class="property">classmethod </em><code class="sig-name descname">from_url</code><span class="sig-paren">(</span><em class="sig-param">url</em>, <em class="sig-param">**ytdl_args</em><span class="sig-paren">)</span> → List[royalnet.bard.ytdlmp3.YtdlMp3]<a class="headerlink" href="#royalnet.bard.YtdlMp3.from_url" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Create a <a class="reference external" href="https://docs.python.org/3.8/library/stdtypes.html#list" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> of <a class="reference internal" href="#royalnet.bard.YtdlMp3" title="royalnet.bard.YtdlMp3"><code class="xref py py-class docutils literal notranslate"><span class="pre">YtdlMp3</span></code></a> from a URL.</p>
|
||||
<dl class="exception">
|
||||
<dt id="royalnet.bard.NotFoundError">
|
||||
<em class="property">exception </em><code class="sig-prename descclassname">royalnet.bard.</code><code class="sig-name descname">NotFoundError</code><a class="headerlink" href="#royalnet.bard.NotFoundError" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>The requested resource wasn’t found.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlMp3.info">
|
||||
<em class="property">property </em><code class="sig-name descname">info</code><a class="headerlink" href="#royalnet.bard.YtdlMp3.info" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Shortcut to get the <a class="reference internal" href="#royalnet.bard.YtdlInfo" title="royalnet.bard.YtdlInfo"><code class="xref py py-class docutils literal notranslate"><span class="pre">YtdlInfo</span></code></a> of the object.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlMp3.is_converted">
|
||||
<em class="property">property </em><code class="sig-name descname">is_converted</code><a class="headerlink" href="#royalnet.bard.YtdlMp3.is_converted" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Has the file been converted?</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="class">
|
||||
<dt id="royalnet.bard.YtdlDiscord">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.bard.</code><code class="sig-name descname">YtdlDiscord</code><span class="sig-paren">(</span><em class="sig-param">ytdl_file: royalnet.bard.ytdlfile.YtdlFile</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.bard.YtdlDiscord" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>A representation of a <a class="reference internal" href="#royalnet.bard.YtdlFile" title="royalnet.bard.YtdlFile"><code class="xref py py-class docutils literal notranslate"><span class="pre">YtdlFile</span></code></a> conversion to the <code class="xref py py-mod docutils literal notranslate"><span class="pre">discord</span></code> PCM format.</p>
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlDiscord.convert_to_pcm">
|
||||
<em class="property">async </em><code class="sig-name descname">convert_to_pcm</code><span class="sig-paren">(</span><span class="sig-paren">)</span> → None<a class="headerlink" href="#royalnet.bard.YtdlDiscord.convert_to_pcm" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Convert the file to pcm with <a class="reference external" href="https://kkroening.github.io/ffmpeg-python/index.html#module-ffmpeg" title="(in ffmpeg-python)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ffmpeg</span></code></a>.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlDiscord.delete_asap">
|
||||
<em class="property">async </em><code class="sig-name descname">delete_asap</code><span class="sig-paren">(</span><span class="sig-paren">)</span> → None<a class="headerlink" href="#royalnet.bard.YtdlDiscord.delete_asap" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Delete the mp3 file.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlDiscord.embed">
|
||||
<code class="sig-name descname">embed</code><span class="sig-paren">(</span><span class="sig-paren">)</span> → discord.embeds.Embed<a class="headerlink" href="#royalnet.bard.YtdlDiscord.embed" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Return this info as a <a class="reference external" href="https://discordpy.readthedocs.io/en/latest/api.html#discord.Embed" title="(in discord.py v1.3.1)"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.Embed</span></code></a>.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlDiscord.from_url">
|
||||
<em class="property">classmethod </em><code class="sig-name descname">from_url</code><span class="sig-paren">(</span><em class="sig-param">url</em>, <em class="sig-param">**ytdl_args</em><span class="sig-paren">)</span> → List[royalnet.bard.ytdldiscord.YtdlDiscord]<a class="headerlink" href="#royalnet.bard.YtdlDiscord.from_url" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Create a <a class="reference external" href="https://docs.python.org/3.8/library/stdtypes.html#list" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> of <a class="reference internal" href="#royalnet.bard.YtdlMp3" title="royalnet.bard.YtdlMp3"><code class="xref py py-class docutils literal notranslate"><span class="pre">YtdlMp3</span></code></a> from a URL.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlDiscord.info">
|
||||
<em class="property">property </em><code class="sig-name descname">info</code><a class="headerlink" href="#royalnet.bard.YtdlDiscord.info" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Shortcut to get the <a class="reference internal" href="#royalnet.bard.YtdlInfo" title="royalnet.bard.YtdlInfo"><code class="xref py py-class docutils literal notranslate"><span class="pre">YtdlInfo</span></code></a> of the object.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlDiscord.is_converted">
|
||||
<em class="property">property </em><code class="sig-name descname">is_converted</code><a class="headerlink" href="#royalnet.bard.YtdlDiscord.is_converted" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Has the file been converted?</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.bard.YtdlDiscord.spawn_audiosource">
|
||||
<code class="sig-name descname">spawn_audiosource</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.bard.YtdlDiscord.spawn_audiosource" title="Permalink to this definition">¶</a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<dl class="exception">
|
||||
<dt id="royalnet.bard.MultipleFilesError">
|
||||
<em class="property">exception </em><code class="sig-prename descclassname">royalnet.bard.</code><code class="sig-name descname">MultipleFilesError</code><a class="headerlink" href="#royalnet.bard.MultipleFilesError" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>The resource contains multiple media files.</p>
|
||||
</dd></dl>
|
||||
|
||||
</div>
|
||||
<div class="section" id="module-royalnet.commands">
|
||||
<span id="commands"></span><h2>Commands<a class="headerlink" href="#module-royalnet.commands" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The subpackage providing all classes related to Royalnet commands.</p>
|
||||
<dl class="class">
|
||||
<dt id="royalnet.commands.CommandInterface">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.commands.</code><code class="sig-name descname">CommandInterface</code><span class="sig-paren">(</span><em class="sig-param">config: Dict[str, Any]</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.commands.CommandInterface" title="Permalink to this definition">¶</a></dt>
|
||||
|
@ -515,6 +473,17 @@ Check the tables submodule for more details.</p></li>
|
|||
<p>A reference to a <code class="xref py py-class docutils literal notranslate"><span class="pre">TelegramSerf</span></code>.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.commands.CommandInterface.table">
|
||||
<em class="property">property </em><code class="sig-name descname">table</code><a class="headerlink" href="#royalnet.commands.CommandInterface.table" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>A shortcut for <code class="xref py py-func docutils literal notranslate"><span class="pre">serf.alchemy.get()</span></code>.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Raises</dt>
|
||||
<dd class="field-odd"><p><a class="reference internal" href="#royalnet.commands.UnsupportedError" title="royalnet.commands.UnsupportedError"><strong>UnsupportedError</strong></a> – if <a class="reference internal" href="#royalnet.constellation.Constellation.alchemy" title="royalnet.constellation.Constellation.alchemy"><code class="xref py py-attr docutils literal notranslate"><span class="pre">alchemy</span></code></a> is <code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code>.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="class">
|
||||
|
@ -631,12 +600,14 @@ That probably means, the database row identifying the user.</p>
|
|||
<dl class="method">
|
||||
<dt id="royalnet.commands.CommandData.session_close">
|
||||
<em class="property">async </em><code class="sig-name descname">session_close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.commands.CommandData.session_close" title="Permalink to this definition">¶</a></dt>
|
||||
<dd></dd></dl>
|
||||
<dd><p>Asyncronously close the <code class="xref py py-attr docutils literal notranslate"><span class="pre">session</span></code> of this object.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.commands.CommandData.session_commit">
|
||||
<em class="property">async </em><code class="sig-name descname">session_commit</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.commands.CommandData.session_commit" title="Permalink to this definition">¶</a></dt>
|
||||
<dd></dd></dl>
|
||||
<dd><p>Asyncronously commit the <code class="xref py py-attr docutils literal notranslate"><span class="pre">session</span></code> of this object.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
|
@ -850,8 +821,17 @@ down).</p>
|
|||
</div>
|
||||
<div class="section" id="module-royalnet.constellation">
|
||||
<span id="constellation"></span><h2>Constellation<a class="headerlink" href="#module-royalnet.constellation" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The part of <code class="xref py py-mod docutils literal notranslate"><span class="pre">royalnet</span></code> that handles the webserver and webpages.</p>
|
||||
<p>It uses many features of <code class="xref py py-mod docutils literal notranslate"><span class="pre">starlette</span></code>.</p>
|
||||
<p>The subpackage providing all functions and classes that handle the webserver and the webpages.</p>
|
||||
<p>It requires the <code class="docutils literal notranslate"><span class="pre">constellation</span></code> extra to be installed (<code class="xref py py-mod docutils literal notranslate"><span class="pre">starlette</span></code>).</p>
|
||||
<p>You can install it with:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">royalnet</span><span class="p">[</span><span class="n">constellation</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>It optionally uses the <code class="docutils literal notranslate"><span class="pre">sentry</span></code> extra for error reporting.</p>
|
||||
<p>You can install them with:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">royalnet</span><span class="p">[</span><span class="n">constellation</span><span class="p">,</span><span class="n">sentry</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<dl class="class">
|
||||
<dt id="royalnet.constellation.Constellation">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.constellation.</code><code class="sig-name descname">Constellation</code><span class="sig-paren">(</span><em class="sig-param">alchemy_cfg: Dict[str, Any], herald_cfg: Dict[str, Any], packs_cfg: Dict[str, Any], constellation_cfg: Dict[str, Any], logging_cfg: Dict[str, Any]</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.constellation.Constellation" title="Permalink to this definition">¶</a></dt>
|
||||
|
@ -1075,6 +1055,13 @@ or the <a class="reference external" href="https://docs.python.org/3.8/library/f
|
|||
</div>
|
||||
<div class="section" id="module-royalnet.herald">
|
||||
<span id="herald"></span><h2>Herald<a class="headerlink" href="#module-royalnet.herald" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The subpackage providing all functions and classes to handle communication between process (even over the Internet).</p>
|
||||
<p>It is based on <code class="xref py py-mod docutils literal notranslate"><span class="pre">websockets</span></code>.</p>
|
||||
<p>It requires the <code class="docutils literal notranslate"><span class="pre">herald</span></code> extra to be installed.</p>
|
||||
<p>You can install it with:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">royalnet</span><span class="p">[</span><span class="n">herald</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<dl class="class">
|
||||
<dt id="royalnet.herald.Config">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.herald.</code><code class="sig-name descname">Config</code><span class="sig-paren">(</span><em class="sig-param">name: str</em>, <em class="sig-param">address: str</em>, <em class="sig-param">port: int</em>, <em class="sig-param">secret: str</em>, <em class="sig-param">secure: bool = False</em>, <em class="sig-param">path: str = '/'</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.herald.Config" title="Permalink to this definition">¶</a></dt>
|
||||
|
@ -1367,6 +1354,7 @@ Akin to the sequence number on IP packets.</p></li>
|
|||
</div>
|
||||
<div class="section" id="module-royalnet.serf">
|
||||
<span id="serf"></span><h2>Serf<a class="headerlink" href="#module-royalnet.serf" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The subpackage providing all Serf implementations.</p>
|
||||
<dl class="class">
|
||||
<dt id="royalnet.serf.Serf">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.serf.</code><code class="sig-name descname">Serf</code><span class="sig-paren">(</span><em class="sig-param">loop: asyncio.events.AbstractEventLoop, alchemy_cfg: Dict[str, Any], herald_cfg: Dict[str, Any], packs_cfg: Dict[str, Any], **_</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.serf.Serf" title="Permalink to this definition">¶</a></dt>
|
||||
|
@ -1691,53 +1679,6 @@ table and the identity table.</p>
|
|||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="class">
|
||||
<dt id="royalnet.utils.FileAudioSource">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">royalnet.utils.</code><code class="sig-name descname">FileAudioSource</code><span class="sig-paren">(</span><em class="sig-param">file</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.utils.FileAudioSource" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>A <a class="reference external" href="https://discordpy.readthedocs.io/en/latest/api.html#discord.AudioSource" title="(in discord.py v1.3.1)"><code class="xref py py-class docutils literal notranslate"><span class="pre">discord.AudioSource</span></code></a> that uses a <a class="reference external" href="https://docs.python.org/3.8/library/io.html#io.BufferedIOBase" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.BufferedIOBase</span></code></a> as an input instead of memory.</p>
|
||||
<p>The stream should be in the usual PCM encoding.</p>
|
||||
<div class="admonition warning">
|
||||
<p class="admonition-title">Warning</p>
|
||||
<p>This AudioSource will consume (and close) the passed stream.</p>
|
||||
</div>
|
||||
<dl class="method">
|
||||
<dt id="royalnet.utils.FileAudioSource.__init__">
|
||||
<code class="sig-name descname">__init__</code><span class="sig-paren">(</span><em class="sig-param">file</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.utils.FileAudioSource.__init__" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Create a FileAudioSource.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><p><strong>file</strong> – the file to be played back.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.utils.FileAudioSource.is_opus">
|
||||
<code class="sig-name descname">is_opus</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.utils.FileAudioSource.is_opus" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>This audio file isn’t Opus-encoded, but PCM-encoded.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Returns</dt>
|
||||
<dd class="field-odd"><p><code class="docutils literal notranslate"><span class="pre">False</span></code>.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.utils.FileAudioSource.read">
|
||||
<code class="sig-name descname">read</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.utils.FileAudioSource.read" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Reads 20ms of audio.</p>
|
||||
<p>If the stream has ended, then return an empty <a class="reference external" href="https://docs.python.org/3.8/library/stdtypes.html#bytes" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a>-like object.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="royalnet.utils.FileAudioSource.stop">
|
||||
<code class="sig-name descname">stop</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.utils.FileAudioSource.stop" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Stop the FileAudioSource. Once stopped, a FileAudioSource will immediatly stop reading more bytes from the
|
||||
file.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dt id="royalnet.utils.init_sentry">
|
||||
<code class="sig-prename descclassname">royalnet.utils.</code><code class="sig-name descname">init_sentry</code><span class="sig-paren">(</span><em class="sig-param">sentry_cfg: Dict[str, Any]</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.utils.init_sentry" title="Permalink to this definition">¶</a></dt>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Index — Royalnet 5.3.2 documentation</title>
|
||||
<title>Index — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
|
||||
|
||||
<div class="version">
|
||||
5.3.2
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -85,6 +85,7 @@
|
|||
|
||||
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="packs/pack.html">Creating a Royalnet Pack</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
@ -192,8 +193,6 @@
|
|||
<li><a href="apireference.html#royalnet.commands.Event.__init__">(royalnet.commands.Event method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Package.__init__">(royalnet.herald.Package method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.utils.FileAudioSource.__init__">(royalnet.utils.FileAudioSource method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
|
@ -240,10 +239,12 @@
|
|||
<h2 id="B">B</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.herald.Broadcast">Broadcast (class in royalnet.herald)</a>
|
||||
<li><a href="apireference.html#royalnet.bard.BardError">BardError</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.herald.Broadcast">Broadcast (class in royalnet.herald)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Link.broadcast">broadcast() (royalnet.herald.Link method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
|
@ -272,6 +273,8 @@
|
|||
</li>
|
||||
<li><a href="apireference.html#royalnet.commands.CommandInterface.config">config (royalnet.commands.CommandInterface attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.commands.Command.config">config() (royalnet.commands.Command property)</a>
|
||||
|
||||
<ul>
|
||||
|
@ -280,8 +283,6 @@
|
|||
<li><a href="apireference.html#royalnet.constellation.Star.config">(royalnet.constellation.Star property)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.commands.ConfigurationError">ConfigurationError</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Link.connect">connect() (royalnet.herald.Link method)</a>
|
||||
|
@ -293,10 +294,6 @@
|
|||
<li><a href="apireference.html#royalnet.commands.CommandInterface.constellation">constellation (royalnet.commands.CommandInterface attribute)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.constellation.Star.constellation">constellation() (royalnet.constellation.Star property)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlMp3.convert_to_mp3">convert_to_mp3() (royalnet.bard.YtdlMp3 method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord.convert_to_pcm">convert_to_pcm() (royalnet.bard.YtdlDiscord method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Config.copy">copy() (royalnet.herald.Config method)</a>
|
||||
</li>
|
||||
|
@ -308,14 +305,8 @@
|
|||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlFile.default_ytdl_args">default_ytdl_args (royalnet.bard.YtdlFile attribute)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord.delete_asap">delete_asap() (royalnet.bard.YtdlDiscord method)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlFile.delete_asap">(royalnet.bard.YtdlFile method)</a>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlFile.delete_asap">delete_asap() (royalnet.bard.YtdlFile method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlMp3.delete_asap">(royalnet.bard.YtdlMp3 method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.commands.CommandData.delete_invoking">delete_invoking() (royalnet.commands.CommandData method)</a>
|
||||
|
@ -330,8 +321,6 @@
|
|||
<h2 id="E">E</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord.embed">embed() (royalnet.bard.YtdlDiscord method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.constellation.ExceptionStar.error">error (royalnet.constellation.ExceptionStar attribute)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.commands.Event">Event (class in royalnet.commands)</a>
|
||||
|
@ -356,8 +345,6 @@
|
|||
<h2 id="F">F</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.utils.FileAudioSource">FileAudioSource (class in royalnet.utils)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Server.find_client">find_client() (royalnet.herald.Server method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Server.find_destination">find_destination() (royalnet.herald.Server method)</a>
|
||||
|
@ -380,14 +367,10 @@
|
|||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Package.from_json_string">from_json_string() (royalnet.herald.Package static method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord.from_url">from_url() (royalnet.bard.YtdlDiscord class method)</a>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlFile.from_url">from_url() (royalnet.bard.YtdlFile class method)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlFile.from_url">(royalnet.bard.YtdlFile class method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlInfo.from_url">(royalnet.bard.YtdlInfo class method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlMp3.from_url">(royalnet.bard.YtdlMp3 class method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="apireference.html#royalnet.utils.from_urluuid">from_urluuid() (in module royalnet.utils)</a>
|
||||
|
@ -440,12 +423,6 @@
|
|||
</li>
|
||||
<li><a href="apireference.html#royalnet.serf.Serf.identity_table">identity_table (royalnet.serf.Serf attribute)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord.info">info() (royalnet.bard.YtdlDiscord property)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlMp3.info">(royalnet.bard.YtdlMp3 property)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="apireference.html#royalnet.serf.Serf.init_alchemy">init_alchemy() (royalnet.serf.Serf method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.constellation.Constellation.init_herald">init_herald() (royalnet.constellation.Constellation method)</a>
|
||||
|
@ -457,11 +434,11 @@
|
|||
<li><a href="apireference.html#royalnet.utils.init_logging">init_logging() (in module royalnet.utils)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.utils.init_sentry">init_sentry() (in module royalnet.utils)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.commands.Event.interface">interface (royalnet.commands.Event attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.commands.Event.interface">interface (royalnet.commands.Event attribute)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.constellation.Constellation.Interface">Interface (royalnet.constellation.Constellation attribute)</a>
|
||||
|
||||
<ul>
|
||||
|
@ -480,15 +457,7 @@
|
|||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.InvalidServerResponseError">InvalidServerResponseError</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord.is_converted">is_converted() (royalnet.bard.YtdlDiscord property)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlMp3.is_converted">(royalnet.bard.YtdlMp3 property)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlFile.is_downloaded">is_downloaded() (royalnet.bard.YtdlFile property)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.utils.FileAudioSource.is_opus">is_opus() (royalnet.utils.FileAudioSource method)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
@ -553,6 +522,8 @@
|
|||
<li><a href="apireference.html#royalnet.constellation.PageStar.methods">methods (royalnet.constellation.PageStar attribute)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.utils.MultiLock">MultiLock (class in royalnet.utils)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.MultipleFilesError">MultipleFilesError</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
@ -568,15 +539,17 @@
|
|||
<li><a href="apireference.html#royalnet.commands.Event.name">(royalnet.commands.Event attribute)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.constellation.Constellation.network_handler">network_handler() (royalnet.constellation.Constellation method)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="apireference.html#royalnet.serf.Serf.network_handler">(royalnet.serf.Serf method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.utils.MultiLock.normal">normal() (royalnet.utils.MultiLock method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.NotFoundError">NotFoundError</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.utils.numberemojiformat">numberemojiformat() (in module royalnet.utils)</a>
|
||||
</li>
|
||||
|
@ -626,8 +599,6 @@
|
|||
<h2 id="R">R</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.utils.FileAudioSource.read">read() (royalnet.utils.FileAudioSource method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.herald.Link.receive">receive() (royalnet.herald.Link method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.serf.Serf.register_commands">register_commands() (royalnet.serf.Serf method)</a>
|
||||
|
@ -735,11 +706,11 @@
|
|||
<li><a href="apireference.html#royalnet.herald.ServerError">ServerError</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.commands.CommandData.session">session() (royalnet.commands.CommandData property)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.constellation.Star.Session">Session() (royalnet.constellation.Star property)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.constellation.Star.Session">Session() (royalnet.constellation.Star property)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.alchemy.Alchemy.session_acm">session_acm() (royalnet.alchemy.Alchemy method)</a>
|
||||
|
||||
<ul>
|
||||
|
@ -757,14 +728,10 @@
|
|||
<li><a href="apireference.html#royalnet.constellation.shoot">shoot() (in module royalnet.constellation)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.utils.sleep_until">sleep_until() (in module royalnet.utils)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord.spawn_audiosource">spawn_audiosource() (royalnet.bard.YtdlDiscord method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.constellation.Star">Star (class in royalnet.constellation)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.constellation.Constellation.starlette">starlette (royalnet.constellation.Constellation attribute)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.utils.FileAudioSource.stop">stop() (royalnet.utils.FileAudioSource method)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.commands.Command.syntax">syntax (royalnet.commands.Command attribute)</a>
|
||||
</li>
|
||||
|
@ -774,6 +741,8 @@
|
|||
<h2 id="T">T</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.commands.CommandInterface.table">table() (royalnet.commands.CommandInterface property)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.alchemy.table_dfs">table_dfs() (in module royalnet.alchemy)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.alchemy.TableNotFoundError">TableNotFoundError</a>
|
||||
|
@ -820,15 +789,13 @@
|
|||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.utils.ytdldateformat">ytdldateformat() (in module royalnet.utils)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlDiscord">YtdlDiscord (class in royalnet.bard)</a>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlError">YtdlError</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlFile">YtdlFile (class in royalnet.bard)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlInfo">YtdlInfo (class in royalnet.bard)</a>
|
||||
</li>
|
||||
<li><a href="apireference.html#royalnet.bard.YtdlMp3">YtdlMp3 (class in royalnet.bard)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
</tr></table>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>royalnet — Royalnet 5.3.2 documentation</title>
|
||||
<title>Royalnet — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
|||
<link rel="stylesheet" href="_static/rygdocs.css" type="text/css" />
|
||||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
<link rel="next" title="Random discoveries" href="randomdiscoveries.html" />
|
||||
<link rel="next" title="Creating a Royalnet Pack" href="packs/pack.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
@ -60,7 +60,7 @@
|
|||
|
||||
|
||||
<div class="version">
|
||||
5.3.2
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -85,6 +85,7 @@
|
|||
|
||||
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="packs/pack.html">Creating a Royalnet Pack</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
@ -132,7 +133,7 @@
|
|||
|
||||
<li><a href="#">Docs</a> »</li>
|
||||
|
||||
<li>royalnet</li>
|
||||
<li>Royalnet</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
@ -152,10 +153,44 @@
|
|||
<div itemprop="articleBody">
|
||||
|
||||
<div class="section" id="royalnet">
|
||||
<h1>royalnet<a class="headerlink" href="#royalnet" title="Permalink to this headline">¶</a></h1>
|
||||
<h1>Royalnet<a class="headerlink" href="#royalnet" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Welcome to the documentation of Royalnet!</p>
|
||||
<div class="toctree-wrapper compound">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="packs/pack.html">Creating a Royalnet Pack</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="packs/command.html">Adding a Command to the Pack</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#creating-a-new-command">Creating a new Command</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#command-arguments">Command arguments</a><ul>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#direct-access">Direct access</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#optional-access">Optional access</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#full-string">Full string</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#regular-expressions">Regular expressions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#raising-errors">Raising errors</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#coroutines-and-slow-operations">Coroutines and slow operations</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#delete-the-invoking-message">Delete the invoking message</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#using-the-database">Using the database</a><ul>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#querying-the-database">Querying the database</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#adding-filters-to-the-query">Adding filters to the query</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#ordering-the-results-of-a-query">Ordering the results of a query</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#fetching-the-results-of-a-query">Fetching the results of a query</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#more-alchemy">More Alchemy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#calling-events">Calling Events</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#displaying-keyboards">Displaying Keyboards</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="packs/command.html#running-code-at-the-initialization-of-the-bot">Running code at the initialization of the bot</a><ul>
|
||||
<li class="toctree-l4"><a class="reference internal" href="packs/command.html#running-repeating-jobs">Running repeating jobs</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="packs/star.html">Adding a Star to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="packs/event.html">Using Events</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="packs/table.html">Using Tables and databases</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="randomdiscoveries.html">Random discoveries</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="randomdiscoveries.html#discord-websocket-undocumented-error-codes">Discord websocket undocumented error codes</a></li>
|
||||
</ul>
|
||||
|
@ -190,7 +225,7 @@
|
|||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
<a href="randomdiscoveries.html" class="btn btn-neutral float-right" title="Random discoveries" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
<a href="packs/pack.html" class="btn btn-neutral float-right" title="Creating a Royalnet Pack" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
Binary file not shown.
555
docs/html/packs/command.html
Normal file
555
docs/html/packs/command.html
Normal file
|
@ -0,0 +1,555 @@
|
|||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Adding a Command to the Pack — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="../_static/js/modernizr.min.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/js/theme.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/rygdocs.css" type="text/css" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Adding a Star to the Pack" href="star.html" />
|
||||
<link rel="prev" title="Creating a Royalnet Pack" href="pack.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
|
||||
|
||||
|
||||
<a href="../index.html" class="icon icon-home"> Royalnet
|
||||
|
||||
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="version">
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="reference internal" href="pack.html">Creating a Royalnet Pack</a><ul class="current">
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Adding a Command to the Pack</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#creating-a-new-command">Creating a new Command</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#command-arguments">Command arguments</a><ul>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#direct-access">Direct access</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#optional-access">Optional access</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#full-string">Full string</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#regular-expressions">Regular expressions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#raising-errors">Raising errors</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#coroutines-and-slow-operations">Coroutines and slow operations</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#delete-the-invoking-message">Delete the invoking message</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#using-the-database">Using the database</a><ul>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#querying-the-database">Querying the database</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#adding-filters-to-the-query">Adding filters to the query</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#ordering-the-results-of-a-query">Ordering the results of a query</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#fetching-the-results-of-a-query">Fetching the results of a query</a></li>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#more-alchemy">More Alchemy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#calling-events">Calling Events</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#displaying-keyboards">Displaying Keyboards</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#running-code-at-the-initialization-of-the-bot">Running code at the initialization of the bot</a><ul>
|
||||
<li class="toctree-l4"><a class="reference internal" href="#running-repeating-jobs">Running repeating jobs</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="star.html">Adding a Star to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="event.html">Using Events</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="table.html">Using Tables and databases</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" aria-label="top navigation">
|
||||
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">Royalnet</a>
|
||||
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
|
||||
<div class="rst-content">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
|
||||
<ul class="wy-breadcrumbs">
|
||||
|
||||
<li><a href="../index.html">Docs</a> »</li>
|
||||
|
||||
<li><a href="pack.html">Creating a Royalnet Pack</a> »</li>
|
||||
|
||||
<li>Adding a Command to the Pack</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
|
||||
<a href="../_sources/packs/command.rst.txt" rel="nofollow"> View page source</a>
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<div class="section" id="adding-a-command-to-the-pack">
|
||||
<h1>Adding a Command to the Pack<a class="headerlink" href="#adding-a-command-to-the-pack" title="Permalink to this headline">¶</a></h1>
|
||||
<p>A Royalnet Command is a small script that is run whenever a specific message is sent to a Royalnet interface.</p>
|
||||
<p>A Command code looks like this:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">royalnet.commands</span> <span class="k">as</span> <span class="nn">rc</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">PingCommand</span><span class="p">(</span><span class="n">rc</span><span class="o">.</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="s2">"ping"</span>
|
||||
|
||||
<span class="n">description</span> <span class="o">=</span> <span class="s2">"Play ping-pong with the bot."</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">interface</span><span class="p">):</span>
|
||||
<span class="c1"># This code is run just once, while the bot is starting</span>
|
||||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
|
||||
|
||||
<span class="k">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">:</span> <span class="n">rc</span><span class="o">.</span><span class="n">CommandArgs</span><span class="p">,</span> <span class="n">data</span><span class="p">:</span> <span class="n">rc</span><span class="o">.</span><span class="n">CommandData</span><span class="p">):</span>
|
||||
<span class="c1"># This code is run every time the command is called</span>
|
||||
<span class="k">await</span> <span class="n">data</span><span class="o">.</span><span class="n">reply</span><span class="p">(</span><span class="s2">"Pong!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section" id="creating-a-new-command">
|
||||
<h2>Creating a new Command<a class="headerlink" href="#creating-a-new-command" title="Permalink to this headline">¶</a></h2>
|
||||
<p>First, think of a <code class="docutils literal notranslate"><span class="pre">name</span></code> for your command.
|
||||
It’s the name your command will be called with: for example, the “spaghetti” command will be called by typing <strong>/spaghetti</strong> in chat.
|
||||
Try to keep the name as short as possible, while staying specific enough so no other command will have the same name.</p>
|
||||
<p>Next, create a new Python file with the <code class="docutils literal notranslate"><span class="pre">name</span></code> you have thought of.
|
||||
The previously mentioned “spaghetti” command should have a file called <code class="docutils literal notranslate"><span class="pre">spaghetti.py</span></code>.</p>
|
||||
<p>Then, in the first row of the file, import the <a class="reference internal" href="../apireference.html#royalnet.commands.Command" title="royalnet.commands.Command"><code class="xref py py-class docutils literal notranslate"><span class="pre">Command</span></code></a> class from royalnet, and create a new class inheriting from it:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">royalnet.commands</span> <span class="k">as</span> <span class="nn">rc</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">SpaghettiCommand</span><span class="p">(</span><span class="n">rc</span><span class="o">.</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="o">...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Inside the class, override the attributes <code class="docutils literal notranslate"><span class="pre">name</span></code> and <code class="docutils literal notranslate"><span class="pre">description</span></code> with respectively the <strong>name of the command</strong> and a <strong>small description of what the command will do</strong>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">royalnet.commands</span> <span class="k">as</span> <span class="nn">rc</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">SpaghettiCommand</span><span class="p">(</span><span class="n">rc</span><span class="o">.</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="s2">"spaghetti"</span>
|
||||
|
||||
<span class="n">description</span> <span class="o">=</span> <span class="s2">"Send a spaghetti emoji in the chat."</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now override the <a class="reference internal" href="../apireference.html#royalnet.commands.Command.run" title="royalnet.commands.Command.run"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Command.run()</span></code></a> method, adding the code you want the bot to run when the command is called.</p>
|
||||
<p>To send a message in the chat the command was called in, you can use the <a class="reference internal" href="../apireference.html#royalnet.commands.CommandData.reply" title="royalnet.commands.CommandData.reply"><code class="xref py py-meth docutils literal notranslate"><span class="pre">CommandData.reply()</span></code></a> coroutine:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">royalnet.commands</span> <span class="k">as</span> <span class="nn">rc</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">SpaghettiCommand</span><span class="p">(</span><span class="n">rc</span><span class="o">.</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="s2">"spaghetti"</span>
|
||||
|
||||
<span class="n">description</span> <span class="o">=</span> <span class="s2">"Send a spaghetti emoji in the chat."</span>
|
||||
|
||||
<span class="k">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">:</span> <span class="n">rc</span><span class="o">.</span><span class="n">CommandArgs</span><span class="p">,</span> <span class="n">data</span><span class="p">:</span> <span class="n">rc</span><span class="o">.</span><span class="n">CommandData</span><span class="p">):</span>
|
||||
<span class="k">await</span> <span class="n">data</span><span class="o">.</span><span class="n">reply</span><span class="p">(</span><span class="s2">"🍝"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>And… it’s done! The command is ready to be <a class="reference internal" href="pack.html"><span class="doc">added to your pack</span></a>!</p>
|
||||
</div>
|
||||
<div class="section" id="command-arguments">
|
||||
<h2>Command arguments<a class="headerlink" href="#command-arguments" title="Permalink to this headline">¶</a></h2>
|
||||
<p>A command can have some arguments passed by the user: for example, on Telegram an user may type <cite>/spaghetti carbonara al-dente</cite>
|
||||
to pass the <a class="reference external" href="https://docs.python.org/3.8/library/stdtypes.html#str" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></a> <cite>“carbonara al-dente”</cite> to the command code.</p>
|
||||
<p>These arguments can be accessed in multiple ways through the <code class="docutils literal notranslate"><span class="pre">args</span></code> parameter passed to the <a class="reference internal" href="../apireference.html#royalnet.commands.Command.run" title="royalnet.commands.Command.run"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Command.run()</span></code></a>
|
||||
method.</p>
|
||||
<p>If you want your command to use arguments, override the <code class="docutils literal notranslate"><span class="pre">syntax</span></code> class attribute with a brief description of the
|
||||
syntax of your command, possibly using {curly braces} for required arguments and [square brackets] for optional
|
||||
ones.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">royalnet.commands</span> <span class="k">as</span> <span class="nn">rc</span>
|
||||
|
||||
<span class="k">class</span> <span class="nc">SpaghettiCommand</span><span class="p">(</span><span class="n">rc</span><span class="o">.</span><span class="n">Command</span><span class="p">):</span>
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="s2">"spaghetti"</span>
|
||||
|
||||
<span class="n">description</span> <span class="o">=</span> <span class="s2">"Send a spaghetti emoji in the chat."</span>
|
||||
|
||||
<span class="n">syntax</span> <span class="o">=</span> <span class="s2">"(requestedpasta)"</span>
|
||||
|
||||
<span class="k">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">:</span> <span class="n">rc</span><span class="o">.</span><span class="n">CommandArgs</span><span class="p">,</span> <span class="n">data</span><span class="p">:</span> <span class="n">rc</span><span class="o">.</span><span class="n">CommandData</span><span class="p">):</span>
|
||||
<span class="k">await</span> <span class="n">data</span><span class="o">.</span><span class="n">reply</span><span class="p">(</span><span class="sa">f</span><span class="s2">"🍝 Here's your </span><span class="si">{args[0]}</span><span class="s2">!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section" id="direct-access">
|
||||
<h3>Direct access<a class="headerlink" href="#direct-access" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can consider arguments as if they were separated by spaces.</p>
|
||||
<p>You can then access command arguments directly by number as if the args object was a list of <a class="reference external" href="https://docs.python.org/3.8/library/stdtypes.html#str" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></a>.</p>
|
||||
<p>If you request an argument with a certain number, but the argument does not exist, an
|
||||
<a class="reference internal" href="../apireference.html#royalnet.commands.InvalidInputError" title="royalnet.commands.InvalidInputError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">InvalidInputError</span></code></a> is raised, making the arguments accessed in this way <strong>required</strong>.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="c1"># "carbonara"</span>
|
||||
|
||||
<span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
||||
<span class="c1"># "al-dente"</span>
|
||||
|
||||
<span class="n">args</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
||||
<span class="c1"># raises InvalidInputError</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="optional-access">
|
||||
<h3>Optional access<a class="headerlink" href="#optional-access" title="Permalink to this headline">¶</a></h3>
|
||||
<p>If you don’t want arguments to be required, you can access them through the <a class="reference internal" href="../apireference.html#royalnet.commands.CommandArgs.optional" title="royalnet.commands.CommandArgs.optional"><code class="xref py py-meth docutils literal notranslate"><span class="pre">CommandArgs.optional()</span></code></a> method: it
|
||||
will return <code class="docutils literal notranslate"><span class="pre">None</span></code> if the argument wasn’t passed, making it <strong>optional</strong>.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">args</span><span class="o">.</span><span class="n">optional</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||||
<span class="c1"># "carbonara"</span>
|
||||
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">optional</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="c1"># "al-dente"</span>
|
||||
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">optional</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||||
<span class="c1"># None</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can specify a default result too, so that the method will return it instead of returning <code class="docutils literal notranslate"><span class="pre">None</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">args</span><span class="o">.</span><span class="n">optional</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s2">"banana"</span><span class="p">)</span>
|
||||
<span class="c1"># "banana"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="full-string">
|
||||
<h3>Full string<a class="headerlink" href="#full-string" title="Permalink to this headline">¶</a></h3>
|
||||
<p>If you want the full argument string, you can use the <a class="reference internal" href="../apireference.html#royalnet.commands.CommandArgs.joined" title="royalnet.commands.CommandArgs.joined"><code class="xref py py-meth docutils literal notranslate"><span class="pre">CommandArgs.joined()</span></code></a> method.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">args</span><span class="o">.</span><span class="n">joined</span><span class="p">()</span>
|
||||
<span class="c1"># "carbonara al-dente"</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>You can specify a minimum number of arguments too, so that an <a class="reference internal" href="../apireference.html#royalnet.commands.InvalidInputError" title="royalnet.commands.InvalidInputError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">InvalidInputError</span></code></a> will be
|
||||
raised if not enough arguments are present:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">args</span><span class="o">.</span><span class="n">joined</span><span class="p">(</span><span class="n">require_at_least</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
|
||||
<span class="c1"># raises InvalidInputError</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="regular-expressions">
|
||||
<h3>Regular expressions<a class="headerlink" href="#regular-expressions" title="Permalink to this headline">¶</a></h3>
|
||||
<p>For more complex commands, you may want to get arguments through <a class="reference external" href="https://regexr.com/">regular expressions</a>.</p>
|
||||
<p>You can then use the <a class="reference internal" href="../apireference.html#royalnet.commands.CommandArgs.match" title="royalnet.commands.CommandArgs.match"><code class="xref py py-meth docutils literal notranslate"><span class="pre">CommandArgs.match()</span></code></a> method, which tries to match a pattern to the command argument string,
|
||||
which returns a tuple of the matched groups and raises an <a class="reference internal" href="../apireference.html#royalnet.commands.InvalidInputError" title="royalnet.commands.InvalidInputError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">InvalidInputError</span></code></a> if there is no match.</p>
|
||||
<p>To match a pattern, <a class="reference external" href="https://docs.python.org/3.8/library/re.html#re.match" title="(in Python v3.8)"><code class="xref py py-func docutils literal notranslate"><span class="pre">re.match()</span></code></a> is used, meaning that Python will try to match only at the beginning of the string.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">args</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s2">"(carb\w+)"</span><span class="p">)</span>
|
||||
<span class="c1"># ("carbonara",)</span>
|
||||
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s2">"(al-\w+)"</span><span class="p">)</span>
|
||||
<span class="c1"># raises InvalidInputError</span>
|
||||
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s2">"\s*(al-\w+)"</span><span class="p">)</span>
|
||||
<span class="c1"># ("al-dente",)</span>
|
||||
|
||||
<span class="n">args</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">r</span><span class="s2">"\s*(carb\w+)\s*(al-\w+)"</span><span class="p">)</span>
|
||||
<span class="c1"># ("carbonara", "al-dente")</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="raising-errors">
|
||||
<h2>Raising errors<a class="headerlink" href="#raising-errors" title="Permalink to this headline">¶</a></h2>
|
||||
<p>If you want to display an error message to the user, you can raise a <a class="reference internal" href="../apireference.html#royalnet.commands.CommandError" title="royalnet.commands.CommandError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CommandError</span></code></a> using the error message as argument:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="ow">not</span> <span class="n">kitchen</span><span class="o">.</span><span class="n">is_open</span><span class="p">():</span>
|
||||
<span class="k">raise</span> <span class="n">CommandError</span><span class="p">(</span><span class="s2">"The kitchen is closed. Come back later!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>There are some subclasses of <a class="reference internal" href="../apireference.html#royalnet.commands.CommandError" title="royalnet.commands.CommandError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">CommandError</span></code></a> that can be used for some more specific cases:</p>
|
||||
<dl class="simple">
|
||||
<dt><a class="reference internal" href="../apireference.html#royalnet.commands.UserError" title="royalnet.commands.UserError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">UserError</span></code></a></dt><dd><p>The user did something wrong, it is not a problem with the bot.</p>
|
||||
</dd>
|
||||
<dt><a class="reference internal" href="../apireference.html#royalnet.commands.InvalidInputError" title="royalnet.commands.InvalidInputError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">InvalidInputError</span></code></a></dt><dd><p>The arguments the user passed to the command by the user are invalid.
|
||||
Displays the command syntax in the error message.</p>
|
||||
</dd>
|
||||
<dt><a class="reference internal" href="../apireference.html#royalnet.commands.UnsupportedError" title="royalnet.commands.UnsupportedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">UnsupportedError</span></code></a></dt><dd><p>The command is not supported on the interface it is being called.</p>
|
||||
</dd>
|
||||
<dt><a class="reference internal" href="../apireference.html#royalnet.commands.ConfigurationError" title="royalnet.commands.ConfigurationError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ConfigurationError</span></code></a></dt><dd><p>The <code class="docutils literal notranslate"><span class="pre">config.toml</span></code> file was misconfigured (a value is missing or invalid).</p>
|
||||
</dd>
|
||||
<dt><a class="reference internal" href="../apireference.html#royalnet.commands.ExternalError" title="royalnet.commands.ExternalError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ExternalError</span></code></a></dt><dd><p>An external API the command depends on is unavailable or returned an error.</p>
|
||||
</dd>
|
||||
<dt><a class="reference internal" href="../apireference.html#royalnet.commands.ProgramError" title="royalnet.commands.ProgramError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ProgramError</span></code></a></dt><dd><p>An error caused by a programming mistake. Equivalent to <a class="reference external" href="https://docs.python.org/3.8/library/exceptions.html#AssertionError" title="(in Python v3.8)"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AssertionError</span></code></a>, but includes a message to facilitate debugging.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" id="coroutines-and-slow-operations">
|
||||
<h2>Coroutines and slow operations<a class="headerlink" href="#coroutines-and-slow-operations" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You may have noticed that in the previous examples we used <code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">data.reply("🍝")</span></code> instead of just <code class="docutils literal notranslate"><span class="pre">data.reply("🍝")</span></code>.</p>
|
||||
<p>This is because <a class="reference internal" href="../apireference.html#royalnet.commands.CommandData.reply" title="royalnet.commands.CommandData.reply"><code class="xref py py-meth docutils literal notranslate"><span class="pre">CommandData.reply()</span></code></a> isn’t a simple method: it is a coroutine, a special kind of function that
|
||||
can be executed separately from the rest of the code, allowing the bot to do other things in the meantime.</p>
|
||||
<p>By adding the <code class="docutils literal notranslate"><span class="pre">await</span></code> keyword before the <code class="docutils literal notranslate"><span class="pre">data.reply("🍝")</span></code>, we tell the bot that it can do other things, like
|
||||
receiving new messages, while the message is being sent.</p>
|
||||
<p>You should avoid running slow normal functions inside bot commands, as they will stop the bot from working until they
|
||||
are finished and may cause bugs in other parts of the code!</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||||
<span class="c1"># Don't do this!</span>
|
||||
<span class="n">image</span> <span class="o">=</span> <span class="n">download_1_terabyte_of_spaghetti</span><span class="p">(</span><span class="s2">"right_now"</span><span class="p">,</span> <span class="n">from</span><span class="o">=</span><span class="s2">"italy"</span><span class="p">)</span>
|
||||
<span class="o">...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>If the slow function you want does not cause any side effect, you can wrap it with the <a class="reference internal" href="../apireference.html#royalnet.utils.asyncify" title="royalnet.utils.asyncify"><code class="xref py py-func docutils literal notranslate"><span class="pre">royalnet.utils.asyncify()</span></code></a>
|
||||
function:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||||
<span class="c1"># If the called function has no side effect, you can do this!</span>
|
||||
<span class="n">image</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncify</span><span class="p">(</span><span class="n">download_1_terabyte_of_spaghetti</span><span class="p">,</span> <span class="s2">"right_now"</span><span class="p">,</span> <span class="n">from</span><span class="o">=</span><span class="s2">"italy"</span><span class="p">)</span>
|
||||
<span class="o">...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Avoid using <a class="reference external" href="https://docs.python.org/3.8/library/time.html#time.sleep" title="(in Python v3.8)"><code class="xref py py-func docutils literal notranslate"><span class="pre">time.sleep()</span></code></a> function, as it is considered a slow operation: use instead <a class="reference external" href="https://docs.python.org/3.8/library/asyncio-task.html#asyncio.sleep" title="(in Python v3.8)"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.sleep()</span></code></a>,
|
||||
a coroutine that does the same exact thing but in an asyncronous way.</p>
|
||||
</div>
|
||||
<div class="section" id="delete-the-invoking-message">
|
||||
<h2>Delete the invoking message<a class="headerlink" href="#delete-the-invoking-message" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The invoking message of a command is the message that the user sent that the bot recognized as a command; for example,
|
||||
the message <code class="docutils literal notranslate"><span class="pre">/spaghetti</span> <span class="pre">carbonara</span></code> is the invoking message for the <code class="docutils literal notranslate"><span class="pre">spaghetti</span></code> command run.</p>
|
||||
<p>You can have the bot delete the invoking message for a command by calling the <a class="reference internal" href="../apireference.html#royalnet.commands.CommandData.delete_invoking" title="royalnet.commands.CommandData.delete_invoking"><code class="xref py py-class docutils literal notranslate"><span class="pre">CommandData.delete_invoking</span></code></a>
|
||||
method:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||||
<span class="k">await</span> <span class="n">data</span><span class="o">.</span><span class="n">delete_invoking</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Not all interfaces support deleting messages; by default, if the interface does not support deletions, the call is
|
||||
ignored.</p>
|
||||
<p>You can have the method raise an error if the message can’t be deleted by setting the <code class="docutils literal notranslate"><span class="pre">error_if_unavailable</span></code> parameter
|
||||
to True:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">await</span> <span class="n">data</span><span class="o">.</span><span class="n">delete_invoking</span><span class="p">(</span><span class="n">error_if_unavailable</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="n">royalnet</span><span class="o">.</span><span class="n">error</span><span class="o">.</span><span class="n">UnsupportedError</span><span class="p">:</span>
|
||||
<span class="k">await</span> <span class="n">data</span><span class="o">.</span><span class="n">reply</span><span class="p">(</span><span class="s2">"🚫 The message could not be deleted."</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">await</span> <span class="n">data</span><span class="o">.</span><span class="n">reply</span><span class="p">(</span><span class="s2">"✅ The message was deleted!"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="using-the-database">
|
||||
<h2>Using the database<a class="headerlink" href="#using-the-database" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Bots can be connected to a PostgreSQL database through a special SQLAlchemy interface called
|
||||
<a class="reference internal" href="../apireference.html#royalnet.alchemy.Alchemy" title="royalnet.alchemy.Alchemy"><code class="xref py py-class docutils literal notranslate"><span class="pre">royalnet.alchemy.Alchemy</span></code></a>.</p>
|
||||
<p>If the connection is established, the <code class="docutils literal notranslate"><span class="pre">self.alchemy</span></code> and <code class="docutils literal notranslate"><span class="pre">data.session</span></code> fields will be
|
||||
available for use in commands.</p>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">self.alchemy</span></code> is an instance of <a class="reference internal" href="../apireference.html#royalnet.alchemy.Alchemy" title="royalnet.alchemy.Alchemy"><code class="xref py py-class docutils literal notranslate"><span class="pre">royalnet.alchemy.Alchemy</span></code></a>, which contains the
|
||||
<a class="reference external" href="https://docs.sqlalchemy.org/en/13/core/connections.html#sqlalchemy.engine.Engine" title="(in SQLAlchemy v1.3)"><code class="xref py py-class docutils literal notranslate"><span class="pre">sqlalchemy.engine.Engine</span></code></a>, metadata and tables, while <code class="docutils literal notranslate"><span class="pre">data.session</span></code> is a
|
||||
<a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.Session" title="(in SQLAlchemy v1.3)"><code class="xref py py-class docutils literal notranslate"><span class="pre">sqlalchemy.orm.session.Session</span></code></a>, and can be interacted in the same way as one.</p>
|
||||
<div class="section" id="querying-the-database">
|
||||
<h3>Querying the database<a class="headerlink" href="#querying-the-database" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query" title="(in SQLAlchemy v1.3)"><code class="xref py py-class docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query</span></code></a> the database using the SQLAlchemy ORM.</p>
|
||||
<p>The SQLAlchemy tables can be found inside <a class="reference internal" href="../apireference.html#royalnet.alchemy.Alchemy" title="royalnet.alchemy.Alchemy"><code class="xref py py-class docutils literal notranslate"><span class="pre">royalnet.alchemy.Alchemy</span></code></a> with the <a class="reference internal" href="../apireference.html#royalnet.alchemy.Alchemy.get" title="royalnet.alchemy.Alchemy.get"><code class="xref py py-meth docutils literal notranslate"><span class="pre">royalnet.alchemy.Alchemy.get()</span></code></a> method:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">royalnet.backpack.tables</span> <span class="k">as</span> <span class="nn">rbt</span>
|
||||
<span class="n">User</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">alchemy</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">rbt</span><span class="o">.</span><span class="n">User</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="adding-filters-to-the-query">
|
||||
<h3>Adding filters to the query<a class="headerlink" href="#adding-filters-to-the-query" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can filter the query results with the <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.filter" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.filter()</span></code></a> method.</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">Note</p>
|
||||
<p>Remember to always use a table column as first comparision element, as it won’t work otherwise.</p>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">role</span> <span class="o">==</span> <span class="s2">"Member"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="ordering-the-results-of-a-query">
|
||||
<h3>Ordering the results of a query<a class="headerlink" href="#ordering-the-results-of-a-query" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can order the query results in <strong>ascending order</strong> with the <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.order_by" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.order_by()</span></code></a> method.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">username</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Additionally, you can append the <cite>.desc()</cite> method to a table column to sort in <strong>descending order</strong>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">query</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">order_by</span><span class="p">(</span><span class="n">User</span><span class="o">.</span><span class="n">username</span><span class="o">.</span><span class="n">desc</span><span class="p">())</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="fetching-the-results-of-a-query">
|
||||
<h3>Fetching the results of a query<a class="headerlink" href="#fetching-the-results-of-a-query" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can fetch the query results with the <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.all" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.all()</span></code></a>,
|
||||
<a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.first" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.first()</span></code></a>, <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.one()</span></code></a> and
|
||||
<a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one_or_none" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.one_or_none()</span></code></a> methods.</p>
|
||||
<p>Remember to use <a class="reference internal" href="../apireference.html#royalnet.utils.asyncify" title="royalnet.utils.asyncify"><code class="xref py py-func docutils literal notranslate"><span class="pre">royalnet.utils.asyncify()</span></code></a> when fetching results, as it may take a while!</p>
|
||||
<p>Use <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.all" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.all()</span></code></a> if you want a <a class="reference external" href="https://docs.python.org/3.8/library/stdtypes.html#list" title="(in Python v3.8)"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> of <strong>all results</strong>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">results</span><span class="p">:</span> <span class="nb">list</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncify</span><span class="p">(</span><span class="n">query</span><span class="o">.</span><span class="n">all</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Use <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.first" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.first()</span></code></a> if you want <strong>the first result</strong> of the list, or <code class="docutils literal notranslate"><span class="pre">None</span></code> if
|
||||
there are no results:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">result</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncify</span><span class="p">(</span><span class="n">query</span><span class="o">.</span><span class="n">first</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Use <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.one()</span></code></a> if you expect to have <strong>a single result</strong>, and you want the command to
|
||||
raise an error if any different number of results is returned:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">result</span><span class="p">:</span> <span class="o">...</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncify</span><span class="p">(</span><span class="n">query</span><span class="o">.</span><span class="n">one</span><span class="p">)</span> <span class="c1"># Raises an error if there are no results or more than a result.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Use <a class="reference external" href="https://docs.sqlalchemy.org/en/13/orm/query.html#sqlalchemy.orm.query.Query.one_or_none" title="(in SQLAlchemy v1.3)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sqlalchemy.orm.query.Query.one_or_none()</span></code></a> if you expect to have <strong>a single result</strong>, or <strong>nothing</strong>, and
|
||||
if you want the command to raise an error if the number of results is greater than one.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">result</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Union</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="kc">None</span><span class="p">]</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncify</span><span class="p">(</span><span class="n">query</span><span class="o">.</span><span class="n">one_or_none</span><span class="p">)</span> <span class="c1"># Raises an error if there is more than a result.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="more-alchemy">
|
||||
<h3>More Alchemy<a class="headerlink" href="#more-alchemy" title="Permalink to this headline">¶</a></h3>
|
||||
<p>You can read more about <code class="xref py py-mod docutils literal notranslate"><span class="pre">sqlalchemy</span></code> at their <a class="reference external" href="https://www.sqlalchemy.org/">website</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="calling-events">
|
||||
<h2>Calling Events<a class="headerlink" href="#calling-events" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This section is not documented yet.</p>
|
||||
</div>
|
||||
<div class="section" id="displaying-keyboards">
|
||||
<h2>Displaying Keyboards<a class="headerlink" href="#displaying-keyboards" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This section is not documented yet.</p>
|
||||
</div>
|
||||
<div class="section" id="running-code-at-the-initialization-of-the-bot">
|
||||
<h2>Running code at the initialization of the bot<a class="headerlink" href="#running-code-at-the-initialization-of-the-bot" title="Permalink to this headline">¶</a></h2>
|
||||
<p>This section is not documented yet.</p>
|
||||
<div class="section" id="running-repeating-jobs">
|
||||
<h3>Running repeating jobs<a class="headerlink" href="#running-repeating-jobs" title="Permalink to this headline">¶</a></h3>
|
||||
<p>This section is not documented yet.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
<a href="star.html" class="btn btn-neutral float-right" title="Adding a Star to the Pack" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
|
||||
|
||||
<a href="pack.html" class="btn btn-neutral float-left" title="Creating a Royalnet Pack" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>
|
||||
© Copyright 2019, Stefano Pigozzi
|
||||
|
||||
</p>
|
||||
</div>
|
||||
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
218
docs/html/packs/event.html
Normal file
218
docs/html/packs/event.html
Normal file
|
@ -0,0 +1,218 @@
|
|||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Using Events — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="../_static/js/modernizr.min.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/js/theme.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/rygdocs.css" type="text/css" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Using Tables and databases" href="table.html" />
|
||||
<link rel="prev" title="Adding a Star to the Pack" href="star.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
|
||||
|
||||
|
||||
<a href="../index.html" class="icon icon-home"> Royalnet
|
||||
|
||||
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="version">
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="reference internal" href="pack.html">Creating a Royalnet Pack</a><ul class="current">
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html">Adding a Command to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="star.html">Adding a Star to the Pack</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Using Events</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="table.html">Using Tables and databases</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" aria-label="top navigation">
|
||||
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">Royalnet</a>
|
||||
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
|
||||
<div class="rst-content">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
|
||||
<ul class="wy-breadcrumbs">
|
||||
|
||||
<li><a href="../index.html">Docs</a> »</li>
|
||||
|
||||
<li><a href="pack.html">Creating a Royalnet Pack</a> »</li>
|
||||
|
||||
<li>Using Events</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
|
||||
<a href="../_sources/packs/event.rst.txt" rel="nofollow"> View page source</a>
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<div class="section" id="using-events">
|
||||
<h1>Using Events<a class="headerlink" href="#using-events" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This section is not documented yet.</p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
<a href="table.html" class="btn btn-neutral float-right" title="Using Tables and databases" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
|
||||
|
||||
<a href="star.html" class="btn btn-neutral float-left" title="Adding a Star to the Pack" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>
|
||||
© Copyright 2019, Stefano Pigozzi
|
||||
|
||||
</p>
|
||||
</div>
|
||||
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
251
docs/html/packs/pack.html
Normal file
251
docs/html/packs/pack.html
Normal file
|
@ -0,0 +1,251 @@
|
|||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Creating a Royalnet Pack — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="../_static/js/modernizr.min.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/js/theme.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/rygdocs.css" type="text/css" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Adding a Command to the Pack" href="command.html" />
|
||||
<link rel="prev" title="Royalnet" href="../index.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
|
||||
|
||||
|
||||
<a href="../index.html" class="icon icon-home"> Royalnet
|
||||
|
||||
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="version">
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Creating a Royalnet Pack</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html">Adding a Command to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="star.html">Adding a Star to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="event.html">Using Events</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="table.html">Using Tables and databases</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" aria-label="top navigation">
|
||||
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">Royalnet</a>
|
||||
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
|
||||
<div class="rst-content">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
|
||||
<ul class="wy-breadcrumbs">
|
||||
|
||||
<li><a href="../index.html">Docs</a> »</li>
|
||||
|
||||
<li>Creating a Royalnet Pack</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
|
||||
<a href="../_sources/packs/pack.rst.txt" rel="nofollow"> View page source</a>
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<div class="section" id="creating-a-royalnet-pack">
|
||||
<h1>Creating a Royalnet Pack<a class="headerlink" href="#creating-a-royalnet-pack" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This section is not documented yet.</p>
|
||||
<div class="toctree-wrapper compound">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="command.html">Adding a Command to the Pack</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#creating-a-new-command">Creating a new Command</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#command-arguments">Command arguments</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#direct-access">Direct access</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#optional-access">Optional access</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#full-string">Full string</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#regular-expressions">Regular expressions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#raising-errors">Raising errors</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#coroutines-and-slow-operations">Coroutines and slow operations</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#delete-the-invoking-message">Delete the invoking message</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#using-the-database">Using the database</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#querying-the-database">Querying the database</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#adding-filters-to-the-query">Adding filters to the query</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#ordering-the-results-of-a-query">Ordering the results of a query</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#fetching-the-results-of-a-query">Fetching the results of a query</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#more-alchemy">More Alchemy</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#calling-events">Calling Events</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#displaying-keyboards">Displaying Keyboards</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html#running-code-at-the-initialization-of-the-bot">Running code at the initialization of the bot</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="command.html#running-repeating-jobs">Running repeating jobs</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="star.html">Adding a Star to the Pack</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="event.html">Using Events</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="table.html">Using Tables and databases</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
<a href="command.html" class="btn btn-neutral float-right" title="Adding a Command to the Pack" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
|
||||
|
||||
<a href="../index.html" class="btn btn-neutral float-left" title="Royalnet" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>
|
||||
© Copyright 2019, Stefano Pigozzi
|
||||
|
||||
</p>
|
||||
</div>
|
||||
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
218
docs/html/packs/star.html
Normal file
218
docs/html/packs/star.html
Normal file
|
@ -0,0 +1,218 @@
|
|||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Adding a Star to the Pack — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="../_static/js/modernizr.min.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/js/theme.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/rygdocs.css" type="text/css" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Using Events" href="event.html" />
|
||||
<link rel="prev" title="Adding a Command to the Pack" href="command.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
|
||||
|
||||
|
||||
<a href="../index.html" class="icon icon-home"> Royalnet
|
||||
|
||||
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="version">
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="reference internal" href="pack.html">Creating a Royalnet Pack</a><ul class="current">
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html">Adding a Command to the Pack</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Adding a Star to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="event.html">Using Events</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="table.html">Using Tables and databases</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" aria-label="top navigation">
|
||||
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">Royalnet</a>
|
||||
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
|
||||
<div class="rst-content">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
|
||||
<ul class="wy-breadcrumbs">
|
||||
|
||||
<li><a href="../index.html">Docs</a> »</li>
|
||||
|
||||
<li><a href="pack.html">Creating a Royalnet Pack</a> »</li>
|
||||
|
||||
<li>Adding a Star to the Pack</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
|
||||
<a href="../_sources/packs/star.rst.txt" rel="nofollow"> View page source</a>
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<div class="section" id="adding-a-star-to-the-pack">
|
||||
<h1>Adding a Star to the Pack<a class="headerlink" href="#adding-a-star-to-the-pack" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This section is not documented yet.</p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
<a href="event.html" class="btn btn-neutral float-right" title="Using Events" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
|
||||
|
||||
<a href="command.html" class="btn btn-neutral float-left" title="Adding a Command to the Pack" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>
|
||||
© Copyright 2019, Stefano Pigozzi
|
||||
|
||||
</p>
|
||||
</div>
|
||||
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
218
docs/html/packs/table.html
Normal file
218
docs/html/packs/table.html
Normal file
|
@ -0,0 +1,218 @@
|
|||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Using Tables and databases — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript" src="../_static/js/modernizr.min.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../_static/js/theme.js"></script>
|
||||
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/rygdocs.css" type="text/css" />
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Random discoveries" href="../randomdiscoveries.html" />
|
||||
<link rel="prev" title="Using Events" href="event.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
|
||||
|
||||
|
||||
<a href="../index.html" class="icon icon-home"> Royalnet
|
||||
|
||||
|
||||
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="version">
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="reference internal" href="pack.html">Creating a Royalnet Pack</a><ul class="current">
|
||||
<li class="toctree-l2"><a class="reference internal" href="command.html">Adding a Command to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="star.html">Adding a Star to the Pack</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="event.html">Using Events</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Using Tables and databases</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
|
||||
<nav class="wy-nav-top" aria-label="top navigation">
|
||||
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">Royalnet</a>
|
||||
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="wy-nav-content">
|
||||
|
||||
<div class="rst-content">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
|
||||
<ul class="wy-breadcrumbs">
|
||||
|
||||
<li><a href="../index.html">Docs</a> »</li>
|
||||
|
||||
<li><a href="pack.html">Creating a Royalnet Pack</a> »</li>
|
||||
|
||||
<li>Using Tables and databases</li>
|
||||
|
||||
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
|
||||
|
||||
<a href="../_sources/packs/table.rst.txt" rel="nofollow"> View page source</a>
|
||||
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<div class="section" id="using-tables-and-databases">
|
||||
<h1>Using Tables and databases<a class="headerlink" href="#using-tables-and-databases" title="Permalink to this headline">¶</a></h1>
|
||||
<p>This section is not documented yet.</p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
|
||||
<a href="../randomdiscoveries.html" class="btn btn-neutral float-right" title="Random discoveries" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
|
||||
|
||||
<a href="event.html" class="btn btn-neutral float-left" title="Using Events" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>
|
||||
© Copyright 2019, Stefano Pigozzi
|
||||
|
||||
</p>
|
||||
</div>
|
||||
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Python Module Index — Royalnet 5.3.2 documentation</title>
|
||||
<title>Python Module Index — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
|||
|
||||
|
||||
<div class="version">
|
||||
5.3.2
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
|||
|
||||
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="packs/pack.html">Creating a Royalnet Pack</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Random discoveries — Royalnet 5.3.2 documentation</title>
|
||||
<title>Random discoveries — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
<link rel="index" title="Index" href="genindex.html" />
|
||||
<link rel="search" title="Search" href="search.html" />
|
||||
<link rel="next" title="API Reference" href="apireference.html" />
|
||||
<link rel="prev" title="royalnet" href="index.html" />
|
||||
<link rel="prev" title="Using Tables and databases" href="packs/table.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
|
||||
<div class="version">
|
||||
5.3.2
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -86,6 +86,7 @@
|
|||
|
||||
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="packs/pack.html">Creating a Royalnet Pack</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Random discoveries</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#discord-websocket-undocumented-error-codes">Discord websocket undocumented error codes</a></li>
|
||||
</ul>
|
||||
|
@ -196,7 +197,7 @@
|
|||
<a href="apireference.html" class="btn btn-neutral float-right" title="API Reference" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
|
||||
|
||||
<a href="index.html" class="btn btn-neutral float-left" title="royalnet" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
<a href="packs/table.html" class="btn btn-neutral float-left" title="Using Tables and databases" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>Search — Royalnet 5.3.2 documentation</title>
|
||||
<title>Search — Royalnet 5.4a2 documentation</title>
|
||||
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
|
||||
|
||||
<div class="version">
|
||||
5.3.2
|
||||
5.4a2
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -85,6 +85,7 @@
|
|||
|
||||
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="packs/pack.html">Creating a Royalnet Pack</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="randomdiscoveries.html">Random discoveries</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="apireference.html">API Reference</a></li>
|
||||
</ul>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
royalnet
|
||||
Royalnet
|
||||
====================================
|
||||
|
||||
Welcome to the documentation of Royalnet!
|
||||
|
@ -6,6 +6,7 @@ Welcome to the documentation of Royalnet!
|
|||
.. toctree::
|
||||
:maxdepth: 5
|
||||
|
||||
packs/pack
|
||||
randomdiscoveries
|
||||
apireference
|
||||
|
||||
|
|
350
docs_source/packs/command.rst
Normal file
350
docs_source/packs/command.rst
Normal file
|
@ -0,0 +1,350 @@
|
|||
.. currentmodule:: royalnet.commands
|
||||
|
||||
Adding a Command to the Pack
|
||||
====================================
|
||||
|
||||
A Royalnet Command is a small script that is run whenever a specific message is sent to a Royalnet interface.
|
||||
|
||||
A Command code looks like this: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class PingCommand(rc.Command):
|
||||
name = "ping"
|
||||
|
||||
description = "Play ping-pong with the bot."
|
||||
|
||||
def __init__(self, interface):
|
||||
# This code is run just once, while the bot is starting
|
||||
super().__init__()
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData):
|
||||
# This code is run every time the command is called
|
||||
await data.reply("Pong!")
|
||||
|
||||
Creating a new Command
|
||||
------------------------------------
|
||||
|
||||
First, think of a ``name`` for your command.
|
||||
It's the name your command will be called with: for example, the "spaghetti" command will be called by typing **/spaghetti** in chat.
|
||||
Try to keep the name as short as possible, while staying specific enough so no other command will have the same name.
|
||||
|
||||
Next, create a new Python file with the ``name`` you have thought of.
|
||||
The previously mentioned "spaghetti" command should have a file called ``spaghetti.py``.
|
||||
|
||||
Then, in the first row of the file, import the :class:`Command` class from royalnet, and create a new class inheriting from it: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
...
|
||||
|
||||
Inside the class, override the attributes ``name`` and ``description`` with respectively the **name of the command** and a **small description of what the command will do**: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
name = "spaghetti"
|
||||
|
||||
description = "Send a spaghetti emoji in the chat."
|
||||
|
||||
Now override the :meth:`Command.run` method, adding the code you want the bot to run when the command is called.
|
||||
|
||||
To send a message in the chat the command was called in, you can use the :meth:`CommandData.reply` coroutine: ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
name = "spaghetti"
|
||||
|
||||
description = "Send a spaghetti emoji in the chat."
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData):
|
||||
await data.reply("🍝")
|
||||
|
||||
And... it's done! The command is ready to be :doc:`added to your pack <pack>`!
|
||||
|
||||
Command arguments
|
||||
------------------------------------
|
||||
|
||||
A command can have some arguments passed by the user: for example, on Telegram an user may type `/spaghetti carbonara al-dente`
|
||||
to pass the :class:`str` `"carbonara al-dente"` to the command code.
|
||||
|
||||
These arguments can be accessed in multiple ways through the ``args`` parameter passed to the :meth:`Command.run`
|
||||
method.
|
||||
|
||||
If you want your command to use arguments, override the ``syntax`` class attribute with a brief description of the
|
||||
syntax of your command, possibly using {curly braces} for required arguments and [square brackets] for optional
|
||||
ones. ::
|
||||
|
||||
import royalnet.commands as rc
|
||||
|
||||
class SpaghettiCommand(rc.Command):
|
||||
name = "spaghetti"
|
||||
|
||||
description = "Send a spaghetti emoji in the chat."
|
||||
|
||||
syntax = "(requestedpasta)"
|
||||
|
||||
async def run(self, args: rc.CommandArgs, data: rc.CommandData):
|
||||
await data.reply(f"🍝 Here's your {args[0]}!")
|
||||
|
||||
|
||||
Direct access
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can consider arguments as if they were separated by spaces.
|
||||
|
||||
You can then access command arguments directly by number as if the args object was a list of :class:`str`.
|
||||
|
||||
If you request an argument with a certain number, but the argument does not exist, an
|
||||
:exc:`.InvalidInputError` is raised, making the arguments accessed in this way **required**. ::
|
||||
|
||||
args[0]
|
||||
# "carbonara"
|
||||
|
||||
args[1]
|
||||
# "al-dente"
|
||||
|
||||
args[2]
|
||||
# raises InvalidInputError
|
||||
|
||||
Optional access
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you don't want arguments to be required, you can access them through the :meth:`CommandArgs.optional` method: it
|
||||
will return ``None`` if the argument wasn't passed, making it **optional**. ::
|
||||
|
||||
args.optional(0)
|
||||
# "carbonara"
|
||||
|
||||
args.optional(1)
|
||||
# "al-dente"
|
||||
|
||||
args.optional(2)
|
||||
# None
|
||||
|
||||
You can specify a default result too, so that the method will return it instead of returning ``None``: ::
|
||||
|
||||
args.optional(2, default="banana")
|
||||
# "banana"
|
||||
|
||||
Full string
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want the full argument string, you can use the :meth:`CommandArgs.joined` method. ::
|
||||
|
||||
args.joined()
|
||||
# "carbonara al-dente"
|
||||
|
||||
You can specify a minimum number of arguments too, so that an :exc:`.InvalidInputError` will be
|
||||
raised if not enough arguments are present: ::
|
||||
|
||||
args.joined(require_at_least=3)
|
||||
# raises InvalidInputError
|
||||
|
||||
Regular expressions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For more complex commands, you may want to get arguments through `regular expressions <https://regexr.com/>`_.
|
||||
|
||||
You can then use the :meth:`CommandArgs.match` method, which tries to match a pattern to the command argument string,
|
||||
which returns a tuple of the matched groups and raises an :exc:`.InvalidInputError` if there is no match.
|
||||
|
||||
To match a pattern, :func:`re.match` is used, meaning that Python will try to match only at the beginning of the string. ::
|
||||
|
||||
args.match(r"(carb\w+)")
|
||||
# ("carbonara",)
|
||||
|
||||
args.match(r"(al-\w+)")
|
||||
# raises InvalidInputError
|
||||
|
||||
args.match(r"\s*(al-\w+)")
|
||||
# ("al-dente",)
|
||||
|
||||
args.match(r"\s*(carb\w+)\s*(al-\w+)")
|
||||
# ("carbonara", "al-dente")
|
||||
|
||||
Raising errors
|
||||
---------------------------------------------
|
||||
|
||||
If you want to display an error message to the user, you can raise a :exc:`.CommandError` using the error message as argument: ::
|
||||
|
||||
if not kitchen.is_open():
|
||||
raise CommandError("The kitchen is closed. Come back later!")
|
||||
|
||||
There are some subclasses of :exc:`.CommandError` that can be used for some more specific cases:
|
||||
|
||||
:exc:`.UserError`
|
||||
The user did something wrong, it is not a problem with the bot.
|
||||
|
||||
:exc:`.InvalidInputError`
|
||||
The arguments the user passed to the command by the user are invalid.
|
||||
Displays the command syntax in the error message.
|
||||
|
||||
:exc:`.UnsupportedError`
|
||||
The command is not supported on the interface it is being called.
|
||||
|
||||
:exc:`.ConfigurationError`
|
||||
The ``config.toml`` file was misconfigured (a value is missing or invalid).
|
||||
|
||||
:exc:`.ExternalError`
|
||||
An external API the command depends on is unavailable or returned an error.
|
||||
|
||||
:exc:`.ProgramError`
|
||||
An error caused by a programming mistake. Equivalent to :exc:`AssertionError`, but includes a message to facilitate debugging.
|
||||
|
||||
Coroutines and slow operations
|
||||
------------------------------------
|
||||
|
||||
You may have noticed that in the previous examples we used ``await data.reply("🍝")`` instead of just ``data.reply("🍝")``.
|
||||
|
||||
This is because :meth:`CommandData.reply` isn't a simple method: it is a coroutine, a special kind of function that
|
||||
can be executed separately from the rest of the code, allowing the bot to do other things in the meantime.
|
||||
|
||||
By adding the ``await`` keyword before the ``data.reply("🍝")``, we tell the bot that it can do other things, like
|
||||
receiving new messages, while the message is being sent.
|
||||
|
||||
You should avoid running slow normal functions inside bot commands, as they will stop the bot from working until they
|
||||
are finished and may cause bugs in other parts of the code! ::
|
||||
|
||||
async def run(self, args, data):
|
||||
# Don't do this!
|
||||
image = download_1_terabyte_of_spaghetti("right_now", from="italy")
|
||||
...
|
||||
|
||||
If the slow function you want does not cause any side effect, you can wrap it with the :func:`royalnet.utils.asyncify`
|
||||
function: ::
|
||||
|
||||
async def run(self, args, data):
|
||||
# If the called function has no side effect, you can do this!
|
||||
image = await asyncify(download_1_terabyte_of_spaghetti, "right_now", from="italy")
|
||||
...
|
||||
|
||||
Avoid using :func:`time.sleep` function, as it is considered a slow operation: use instead :func:`asyncio.sleep`,
|
||||
a coroutine that does the same exact thing but in an asyncronous way.
|
||||
|
||||
Delete the invoking message
|
||||
------------------------------------
|
||||
|
||||
The invoking message of a command is the message that the user sent that the bot recognized as a command; for example,
|
||||
the message ``/spaghetti carbonara`` is the invoking message for the ``spaghetti`` command run.
|
||||
|
||||
You can have the bot delete the invoking message for a command by calling the :class:`CommandData.delete_invoking`
|
||||
method: ::
|
||||
|
||||
async def run(self, args, data):
|
||||
await data.delete_invoking()
|
||||
|
||||
Not all interfaces support deleting messages; by default, if the interface does not support deletions, the call is
|
||||
ignored.
|
||||
|
||||
You can have the method raise an error if the message can't be deleted by setting the ``error_if_unavailable`` parameter
|
||||
to True: ::
|
||||
|
||||
async def run(self, args, data):
|
||||
try:
|
||||
await data.delete_invoking(error_if_unavailable=True)
|
||||
except royalnet.error.UnsupportedError:
|
||||
await data.reply("🚫 The message could not be deleted.")
|
||||
else:
|
||||
await data.reply("✅ The message was deleted!")
|
||||
|
||||
Using the database
|
||||
------------------------------------
|
||||
|
||||
Bots can be connected to a PostgreSQL database through a special SQLAlchemy interface called
|
||||
:class:`royalnet.alchemy.Alchemy`.
|
||||
|
||||
If the connection is established, the ``self.alchemy`` and ``data.session`` fields will be
|
||||
available for use in commands.
|
||||
|
||||
``self.alchemy`` is an instance of :class:`royalnet.alchemy.Alchemy`, which contains the
|
||||
:class:`sqlalchemy.engine.Engine`, metadata and tables, while ``data.session`` is a
|
||||
:class:`sqlalchemy.orm.session.Session`, and can be interacted in the same way as one.
|
||||
|
||||
Querying the database
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can :class:`sqlalchemy.orm.query.Query` the database using the SQLAlchemy ORM.
|
||||
|
||||
The SQLAlchemy tables can be found inside :class:`royalnet.alchemy.Alchemy` with the :meth:`royalnet.alchemy.Alchemy.get` method: ::
|
||||
|
||||
import royalnet.backpack.tables as rbt
|
||||
User = self.alchemy.get(rbt.User)
|
||||
|
||||
Adding filters to the query
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can filter the query results with the :meth:`sqlalchemy.orm.query.Query.filter` method.
|
||||
|
||||
.. note:: Remember to always use a table column as first comparision element, as it won't work otherwise.
|
||||
|
||||
::
|
||||
|
||||
query = query.filter(User.role == "Member")
|
||||
|
||||
|
||||
Ordering the results of a query
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can order the query results in **ascending order** with the :meth:`sqlalchemy.orm.query.Query.order_by` method. ::
|
||||
|
||||
query = query.order_by(User.username)
|
||||
|
||||
Additionally, you can append the `.desc()` method to a table column to sort in **descending order**: ::
|
||||
|
||||
query = query.order_by(User.username.desc())
|
||||
|
||||
Fetching the results of a query
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can fetch the query results with the :meth:`sqlalchemy.orm.query.Query.all`,
|
||||
:meth:`sqlalchemy.orm.query.Query.first`, :meth:`sqlalchemy.orm.query.Query.one` and
|
||||
:meth:`sqlalchemy.orm.query.Query.one_or_none` methods.
|
||||
|
||||
Remember to use :func:`royalnet.utils.asyncify` when fetching results, as it may take a while!
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.all` if you want a :class:`list` of **all results**: ::
|
||||
|
||||
results: list = await asyncify(query.all)
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.first` if you want **the first result** of the list, or ``None`` if
|
||||
there are no results: ::
|
||||
|
||||
result: typing.Union[..., None] = await asyncify(query.first)
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.one` if you expect to have **a single result**, and you want the command to
|
||||
raise an error if any different number of results is returned: ::
|
||||
|
||||
result: ... = await asyncify(query.one) # Raises an error if there are no results or more than a result.
|
||||
|
||||
Use :meth:`sqlalchemy.orm.query.Query.one_or_none` if you expect to have **a single result**, or **nothing**, and
|
||||
if you want the command to raise an error if the number of results is greater than one. ::
|
||||
|
||||
result: typing.Union[..., None] = await asyncify(query.one_or_none) # Raises an error if there is more than a result.
|
||||
|
||||
More Alchemy
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can read more about :mod:`sqlalchemy` at their `website <https://www.sqlalchemy.org/>`_.
|
||||
|
||||
Calling Events
|
||||
------------------------------------
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
Displaying Keyboards
|
||||
------------------------------------
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
Running code at the initialization of the bot
|
||||
---------------------------------------------
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
Running repeating jobs
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This section is not documented yet.
|
4
docs_source/packs/event.rst
Normal file
4
docs_source/packs/event.rst
Normal file
|
@ -0,0 +1,4 @@
|
|||
Using Events
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
12
docs_source/packs/pack.rst
Normal file
12
docs_source/packs/pack.rst
Normal file
|
@ -0,0 +1,12 @@
|
|||
Creating a Royalnet Pack
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 5
|
||||
|
||||
command
|
||||
star
|
||||
event
|
||||
table
|
4
docs_source/packs/star.rst
Normal file
4
docs_source/packs/star.rst
Normal file
|
@ -0,0 +1,4 @@
|
|||
Adding a Star to the Pack
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
4
docs_source/packs/table.rst
Normal file
4
docs_source/packs/table.rst
Normal file
|
@ -0,0 +1,4 @@
|
|||
Using Tables and databases
|
||||
====================================
|
||||
|
||||
This section is not documented yet.
|
80
poetry.lock
generated
80
poetry.lock
generated
|
@ -162,7 +162,7 @@ tzlocal = "*"
|
|||
category = "main"
|
||||
description = "A library to handle automated deprecations"
|
||||
name = "deprecation"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
version = "2.0.7"
|
||||
|
||||
|
@ -197,7 +197,7 @@ version = "0.16"
|
|||
category = "main"
|
||||
description = "Python audio data toolkit (ID3 and MP3)"
|
||||
name = "eyed3"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
version = "0.9"
|
||||
|
||||
|
@ -228,7 +228,7 @@ dev = ["future (0.17.1)", "numpy (1.16.4)", "pytest-mock (1.10.4)", "pytest (4.6
|
|||
category = "main"
|
||||
description = "Infer file type and MIME type of any file/buffer. No external dependencies."
|
||||
name = "filetype"
|
||||
optional = false
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
version = "1.0.5"
|
||||
|
||||
|
@ -318,7 +318,7 @@ description = "A very fast and expressive template engine."
|
|||
name = "jinja2"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
version = "2.11.0"
|
||||
version = "2.11.1"
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=0.23"
|
||||
|
@ -473,7 +473,7 @@ description = "Cryptographic library for Python"
|
|||
name = "pycryptodome"
|
||||
optional = true
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
version = "3.9.4"
|
||||
version = "3.9.6"
|
||||
|
||||
[[package]]
|
||||
category = "dev"
|
||||
|
@ -915,7 +915,7 @@ version = "2020.1.24"
|
|||
[extras]
|
||||
alchemy_easy = ["sqlalchemy", "psycopg2_binary"]
|
||||
alchemy_hard = ["sqlalchemy", "psycopg2"]
|
||||
bard = ["ffmpeg_python", "youtube_dl"]
|
||||
bard = ["ffmpeg_python", "youtube_dl", "eyed3"]
|
||||
coloredlogs = ["coloredlogs"]
|
||||
constellation = ["starlette", "uvicorn", "python-multipart"]
|
||||
discord = ["discord.py", "pynacl"]
|
||||
|
@ -925,7 +925,7 @@ sentry = ["sentry_sdk"]
|
|||
telegram = ["python_telegram_bot"]
|
||||
|
||||
[metadata]
|
||||
content-hash = "e46d65bd8228040eb92de09eb31a8a0987a1afbc6f39e62656f9a306df049ba4"
|
||||
content-hash = "f275cd948fe28423a90d37d2825eabfec97e8ac0cdf52ee2d20f803d61987b40"
|
||||
python-versions = "^3.8"
|
||||
|
||||
[metadata.files]
|
||||
|
@ -1104,8 +1104,8 @@ imagesize = [
|
|||
{file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"},
|
||||
]
|
||||
jinja2 = [
|
||||
{file = "Jinja2-2.11.0-py2.py3-none-any.whl", hash = "sha256:6e7a3c2934694d59ad334c93dd1b6c96699cf24c53fdb8ec848ac6b23e685734"},
|
||||
{file = "Jinja2-2.11.0.tar.gz", hash = "sha256:d6609ae5ec3d56212ca7d802eda654eaf2310000816ce815361041465b108be4"},
|
||||
{file = "Jinja2-2.11.1-py2.py3-none-any.whl", hash = "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49"},
|
||||
{file = "Jinja2-2.11.1.tar.gz", hash = "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250"},
|
||||
]
|
||||
jsonschema = [
|
||||
{file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"},
|
||||
|
@ -1248,38 +1248,36 @@ pycparser = [
|
|||
{file = "pycparser-2.19.tar.gz", hash = "sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"},
|
||||
]
|
||||
pycryptodome = [
|
||||
{file = "pycryptodome-3.9.4-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:6c2720696b10ae356040e888bde1239b8957fe18885ccf5e7b4e8dec882f0856"},
|
||||
{file = "pycryptodome-3.9.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:5c485ed6e9718ebcaa81138fa70ace9c563d202b56a8cee119b4085b023931f5"},
|
||||
{file = "pycryptodome-3.9.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:56fdd0e425f1b8fd3a00b6d96351f86226674974814c50534864d0124d48871f"},
|
||||
{file = "pycryptodome-3.9.4-cp27-cp27m-win32.whl", hash = "sha256:2de33ed0a95855735d5a0fc0c39603314df9e78ee8bbf0baa9692fb46b3b8bbb"},
|
||||
{file = "pycryptodome-3.9.4-cp27-cp27m-win_amd64.whl", hash = "sha256:eec0689509389f19875f66ae8dedd59f982240cdab31b9f78a8dc266011df93a"},
|
||||
{file = "pycryptodome-3.9.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:68fab8455efcbfe87c5d75015476f9b606227ffe244d57bfd66269451706e899"},
|
||||
{file = "pycryptodome-3.9.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4b9533d4166ca07abdd49ce9d516666b1df944997fe135d4b21ac376aa624aff"},
|
||||
{file = "pycryptodome-3.9.4-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:d3fe3f33ad52bf0c19ee6344b695ba44ffbfa16f3c29ca61116b48d97bd970fb"},
|
||||
{file = "pycryptodome-3.9.4-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:319e568baf86620b419d53063b18c216abf924875966efdfe06891b987196a45"},
|
||||
{file = "pycryptodome-3.9.4-cp34-cp34m-win32.whl", hash = "sha256:042ae873baadd0c33b4d699a5c5b976ade3233a979d972f98ca82314632d868c"},
|
||||
{file = "pycryptodome-3.9.4-cp34-cp34m-win_amd64.whl", hash = "sha256:a30f501bbb32e01a49ef9e09ca1260e5ab49bf33a257080ec553e08997acc487"},
|
||||
{file = "pycryptodome-3.9.4-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:b55c60c321ac91945c60a40ac9896ac7a3d432bb3e8c14006dfd82ad5871c331"},
|
||||
{file = "pycryptodome-3.9.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:9d9945ac8375d5d8e60bd2a2e1df5882eaa315522eedf3ca868b1546dfa34eba"},
|
||||
{file = "pycryptodome-3.9.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:4372ec7518727172e1605c0843cdc5375d4771e447b8148c787b860260aae151"},
|
||||
{file = "pycryptodome-3.9.4-cp35-cp35m-win32.whl", hash = "sha256:0502876279772b1384b660ccc91563d04490d562799d8e2e06b411e2d81128a9"},
|
||||
{file = "pycryptodome-3.9.4-cp35-cp35m-win_amd64.whl", hash = "sha256:72166c2ac520a5dbd2d90208b9c279161ec0861662a621892bd52fb6ca13ab91"},
|
||||
{file = "pycryptodome-3.9.4-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:b4af098f2a50f8d048ab12cabb59456585c0acf43d90ee79782d2d6d0ed59dba"},
|
||||
{file = "pycryptodome-3.9.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:8a799bea3c6617736e914a2e77c409f52893d382f619f088f8a80e2e21f573c1"},
|
||||
{file = "pycryptodome-3.9.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:7c52308ac5b834331b2f107a490b2c27de024a229b61df4cdc5c131d563dfe98"},
|
||||
{file = "pycryptodome-3.9.4-cp36-cp36m-win32.whl", hash = "sha256:63c103a22cbe9752f6ea9f1a0de129995bad91c4d03a66c67cffcf6ee0c9f1e1"},
|
||||
{file = "pycryptodome-3.9.4-cp36-cp36m-win_amd64.whl", hash = "sha256:54456cf85130e01674d21fb1ab89ffccacb138a8ade88d72fa2b0ac898d2798b"},
|
||||
{file = "pycryptodome-3.9.4-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:aec4d42deb836b8fb3ba32f2ba1ef0d33dd3dc9d430b1479ee7a914490d15b5e"},
|
||||
{file = "pycryptodome-3.9.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:896e9b6fd0762aa07b203c993fbbee7a1f1a4674c6886afd7bfa86f3d1be98a8"},
|
||||
{file = "pycryptodome-3.9.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:57b1b707363490c495ad0eeb38bd1b0e1697c497af25fad78d3a1ebf0477fd5b"},
|
||||
{file = "pycryptodome-3.9.4-cp37-cp37m-win32.whl", hash = "sha256:87d8d85b4792ca5e730fb7a519fbc3ed976c59dcf79c5204589c59afd56b9926"},
|
||||
{file = "pycryptodome-3.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:e3a79a30d15d9c7c284a7734036ee8abdb5ca3a6f5774d293cdc9e1358c1dc10"},
|
||||
{file = "pycryptodome-3.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:48821950ffb9c836858d8fa09d7840b6df52eadd387a3c5acece55cb387743f9"},
|
||||
{file = "pycryptodome-3.9.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cbfd97f9e060f0d30245cd29fa267a9a84de9da97559366fca0a3f7655acc63f"},
|
||||
{file = "pycryptodome-3.9.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9ef966c727de942de3e41aa8462c4b7b4bca70f19af5a3f99e31376589c11aac"},
|
||||
{file = "pycryptodome-3.9.4-cp38-cp38-win32.whl", hash = "sha256:a8ca2450394d3699c9f15ef25e8de9a24b401933716a1e39d37fa01f5fe3c58b"},
|
||||
{file = "pycryptodome-3.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:c53348358408d94869059e16fba5ff3bef8c52c25b18421472aba272b9bb450f"},
|
||||
{file = "pycryptodome-3.9.4.tar.gz", hash = "sha256:a168e73879619b467072509a223282a02c8047d932a48b74fbd498f27224aa04"},
|
||||
{file = "pycryptodome-3.9.6-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:5029c46b0d41dfb763c3981c0af68eab029f06fe2b94f2299112fc18cf9e8d6d"},
|
||||
{file = "pycryptodome-3.9.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:95d324e603c5cec5d89e8595236bbf59ade5fe3a72d100ce61eebb323d598750"},
|
||||
{file = "pycryptodome-3.9.6-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2a57daef18a2022a5e4b6f7376c9ddd0c2d946e4b1f1e59b837f5bf295be7380"},
|
||||
{file = "pycryptodome-3.9.6-cp27-cp27m-win32.whl", hash = "sha256:a719bd708207fa219fcbf4c8ebbcbc52846045f78179d00445b429fdabdbc1c4"},
|
||||
{file = "pycryptodome-3.9.6-cp27-cp27m-win_amd64.whl", hash = "sha256:39e5ca2f66d1eac7abcba5ce1a03370d123dc6085620f1cd532dfee27e650178"},
|
||||
{file = "pycryptodome-3.9.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f4d2174e168d0eabd1fffaf88b4f62c2b6f30a67b8816f31024b8e48be3e2d75"},
|
||||
{file = "pycryptodome-3.9.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ec7d39589f9cfc2a8b83b1d2fc673441757c99d43283e97b2dd46e0e23730db8"},
|
||||
{file = "pycryptodome-3.9.6-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:9163fec630495c10c767991e3f8dab32f4427bfb2dfeaa59bb28fe3e52ba66f2"},
|
||||
{file = "pycryptodome-3.9.6-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:0a8d5f2dbb4bbe830ace54286b829bfa529f0853bedaab6225fcb2e6d1f7e356"},
|
||||
{file = "pycryptodome-3.9.6-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:5817c0b3c263025d851da96b90cbc7e95348008f88b990e90d10683dba376666"},
|
||||
{file = "pycryptodome-3.9.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c41b7e10b72cef00cd63410f31fe50e72dc3a40eafbd146e288384fbe4208064"},
|
||||
{file = "pycryptodome-3.9.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f3204006869ab037604b1d9f045c4e84882ddd365e4ee8caa5eb1ff47a59188e"},
|
||||
{file = "pycryptodome-3.9.6-cp35-cp35m-win32.whl", hash = "sha256:cdb0ad83a5d6bac986a37fcb7562bcbef0aabae8ea19505bab5cf83c4d18af12"},
|
||||
{file = "pycryptodome-3.9.6-cp35-cp35m-win_amd64.whl", hash = "sha256:1259b8ca49662b8a941177357f08147d858595c0042e63ff81e9628e925b5c9d"},
|
||||
{file = "pycryptodome-3.9.6-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:09bf05a489fe10f9280a5e0163f195e7b9630cafb15f7d72fb9c8f5eb2afa84f"},
|
||||
{file = "pycryptodome-3.9.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:fcff8c9d88d58880f7eda2139c7c444552a38f98a9e77ba5970b6e78f54ac358"},
|
||||
{file = "pycryptodome-3.9.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:9948c2d5c5c0ee45ed44cee0e2eba2ce60a03be006ed3074521f3da3be162e72"},
|
||||
{file = "pycryptodome-3.9.6-cp36-cp36m-win32.whl", hash = "sha256:79320f1fc5c9ca682869087c565bb29ca6f334692e940d7365771e9a94382e12"},
|
||||
{file = "pycryptodome-3.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:d8e480f65ac7105cbc288eec2417dc61eaac6ed6e75595aa15b8c7c77c53a68b"},
|
||||
{file = "pycryptodome-3.9.6-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:07daddb98f98f771ba027f8f835bdb675aeb84effe41ed5221f520b267429354"},
|
||||
{file = "pycryptodome-3.9.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:da2d581da279bc7408d38e16ff77754f5448c4352f2acfe530a5d14d8fc6934a"},
|
||||
{file = "pycryptodome-3.9.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:012ca77c2105600e3c6aef43188101ac1d95052c633a4ae8fbebffab20c25f8a"},
|
||||
{file = "pycryptodome-3.9.6-cp37-cp37m-win32.whl", hash = "sha256:05b4d865710f9a6378d3ada28195ff78e52642d3ecffe6fa9d379d870b9bf29d"},
|
||||
{file = "pycryptodome-3.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:9927aa8a8cb4af681279b6f28a1dcb14e0eb556c1aea8413a1e27608a8516e0c"},
|
||||
{file = "pycryptodome-3.9.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:de61091dd68326b600422cf731eb4810c4c6363f18a65bccd6061784b7454f5b"},
|
||||
{file = "pycryptodome-3.9.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:238d8b6dd27bd1a04816a68aa90a739e6dd23b192fcd83b50f9360958bff192a"},
|
||||
{file = "pycryptodome-3.9.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:3d516df693c195b8da3795e381429bd420e87081b7e6c2871c62c9897c812cda"},
|
||||
{file = "pycryptodome-3.9.6-cp38-cp38-win32.whl", hash = "sha256:3e486c5b7228e864665fc479e9f596b2547b5fe29c6f5c8ed3807784d06faed7"},
|
||||
{file = "pycryptodome-3.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:887d08beca6368d3d70dc75126607ad76317a9fd07fe61323d8c3cb42add12b6"},
|
||||
{file = "pycryptodome-3.9.6.tar.gz", hash = "sha256:bc22ced26ebc46546798fa0141f4418f1db116dec517f0aeaecec87cf7b2416c"},
|
||||
]
|
||||
pygments = [
|
||||
{file = "Pygments-2.5.2-py2.py3-none-any.whl", hash = "sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b"},
|
||||
|
|
Loading…
Reference in a new issue