1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00

Update docs

This commit is contained in:
Steffo 2019-09-27 14:19:11 +02:00
parent 44703c9028
commit d9e543cf35
20 changed files with 649 additions and 878 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -229,6 +229,32 @@ function: ::
Avoid using :py:func:`time.sleep` function, as it is considered a slow operation: use instead :py:func:`asyncio.sleep`,
a coroutine that does the same exact thing.
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 :py: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
------------------------------------

View file

@ -520,15 +520,14 @@ dl.citation > dd:after {
}
dl.field-list {
display: grid;
grid-template-columns: fit-content(30%) auto;
display: flex;
flex-wrap: wrap;
}
dl.field-list > dt {
flex-basis: 20%;
font-weight: bold;
word-break: break-word;
padding-left: 0.5em;
padding-right: 5px;
}
dl.field-list > dt:after {
@ -536,8 +535,8 @@ dl.field-list > dt:after {
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
flex-basis: 70%;
padding-left: 1em;
margin-left: 0em;
margin-bottom: 0em;
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -393,7 +393,7 @@
<dl class="method">
<dt id="royalnet.bots.TelegramBot._init_client">
<code class="sig-name descname">_init_client</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.bots.TelegramBot._init_client" title="Permalink to this definition"></a></dt>
<dd><p>Create the <a class="reference external" href="https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot" title="(in Python Telegram Bot v12.0)"><code class="xref py py-class docutils literal notranslate"><span class="pre">telegram.Bot</span></code></a>, and set the starting offset.</p>
<dd><p>Create the <a class="reference external" href="https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot" title="(in Python Telegram Bot v12.1)"><code class="xref py py-class docutils literal notranslate"><span class="pre">telegram.Bot</span></code></a>, and set the starting offset.</p>
</dd></dl>
<dl class="method">
@ -412,6 +412,11 @@
<dd><p>A blocking coroutine that should make the bot start listening to commands and requests.</p>
</dd></dl>
<dl class="method">
<dt id="royalnet.bots.TelegramBot.safe_api_call">
<em class="property">static </em><code class="sig-name descname">safe_api_call</code><span class="sig-paren">(</span><em class="sig-param">f: Callable</em>, <em class="sig-param">*args</em>, <em class="sig-param">**kwargs</em><span class="sig-paren">)</span> &#x2192; Optional<a class="headerlink" href="#royalnet.bots.TelegramBot.safe_api_call" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
<dl class="class">
@ -659,6 +664,18 @@ in the format <code class="docutils literal notranslate"><span class="pre">(requ
<dt id="royalnet.commands.CommandData">
<em class="property">class </em><code class="sig-prename descclassname">royalnet.commands.</code><code class="sig-name descname">CommandData</code><a class="headerlink" href="#royalnet.commands.CommandData" title="Permalink to this definition"></a></dt>
<dd><dl class="method">
<dt id="royalnet.commands.CommandData.delete_invoking">
<em class="property">async </em><code class="sig-name descname">delete_invoking</code><span class="sig-paren">(</span><em class="sig-param">error_if_unavailable=False</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.commands.CommandData.delete_invoking" title="Permalink to this definition"></a></dt>
<dd><p>Delete the invoking message, if supported by the interface.</p>
<p>The invoking message is the message send by the user that contains the command.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>error_if_unavailable</strong> if True, raise NotImplementedError() if the message cannot been deleted</p>
</dd>
</dl>
</dd></dl>
<dl class="method">
<dt id="royalnet.commands.CommandData.get_author">
<em class="property">async </em><code class="sig-name descname">get_author</code><span class="sig-paren">(</span><em class="sig-param">error_if_none: bool = False</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.commands.CommandData.get_author" title="Permalink to this definition"></a></dt>
<dd><p>Try to find the identifier of the user that sent the message.
@ -727,7 +744,7 @@ That probably means, the database row identifying the user.</p>
<dl class="method">
<dt id="royalnet.commands.CommandArgs.match">
<code class="sig-name descname">match</code><span class="sig-paren">(</span><em class="sig-param">pattern: Union[str, Pattern]</em><span class="sig-paren">)</span> &#x2192; Sequence[AnyStr]<a class="headerlink" href="#royalnet.commands.CommandArgs.match" title="Permalink to this definition"></a></dt>
<code class="sig-name descname">match</code><span class="sig-paren">(</span><em class="sig-param">pattern: Union[str, Pattern], *flags</em><span class="sig-paren">)</span> &#x2192; Sequence[AnyStr]<a class="headerlink" href="#royalnet.commands.CommandArgs.match" title="Permalink to this definition"></a></dt>
<dd><p>Match the <code class="xref py py-func docutils literal notranslate"><span class="pre">royalnet.utils.commandargs.joined()</span></code> to a regex pattern.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
@ -1089,7 +1106,7 @@ Contains info about the source and the destination.</p>
<dl class="function">
<dt id="royalnet.utils.safeformat">
<code class="sig-prename descclassname">royalnet.utils.</code><code class="sig-name descname">safeformat</code><span class="sig-paren">(</span><em class="sig-param">string: str</em>, <em class="sig-param">**words: str</em><span class="sig-paren">)</span> &#x2192; str<a class="headerlink" href="#royalnet.utils.safeformat" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">royalnet.utils.</code><code class="sig-name descname">safeformat</code><span class="sig-paren">(</span><em class="sig-param">string: str</em>, <em class="sig-param">**words</em><span class="sig-paren">)</span> &#x2192; str<a class="headerlink" href="#royalnet.utils.safeformat" title="Permalink to this definition"></a></dt>
<dd><p><code class="xref py py-func docutils literal notranslate"><span class="pre">str.format()</span></code> something, but ignore missing keys instead of raising an error.</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
@ -1343,6 +1360,11 @@ Use with caution?</p>
<em class="property">exception </em><code class="sig-prename descclassname">royalnet.error.</code><code class="sig-name descname">RoyalnetRequestError</code><span class="sig-paren">(</span><em class="sig-param">error: ResponseError</em><span class="sig-paren">)</span><a class="headerlink" href="#royalnet.error.RoyalnetRequestError" title="Permalink to this definition"></a></dt>
<dd><p>An error was raised while handling the Royalnet request.</p>
<p>This exception contains the <a class="reference internal" href="#royalnet.network.ResponseError" title="royalnet.network.ResponseError"><code class="xref py py-class docutils literal notranslate"><span class="pre">royalnet.network.ResponseError</span></code></a> that was returned by the other Link.</p>
<dl class="method">
<dt id="royalnet.error.RoyalnetRequestError.args">
<em class="property">property </em><code class="sig-name descname">args</code><a class="headerlink" href="#royalnet.error.RoyalnetRequestError.args" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
</dd></dl>
<dl class="exception">

View file

@ -93,6 +93,7 @@
</li>
<li class="toctree-l2"><a class="reference internal" href="#running-code-at-the-initialization-of-the-bot">Running code at the initialization of the bot</a></li>
<li class="toctree-l2"><a class="reference internal" href="#coroutines-and-slow-operations">Coroutines and slow operations</a></li>
<li class="toctree-l2"><a class="reference internal" href="#delete-the-invoking-message">Delete the invoking message</a></li>
<li class="toctree-l2"><a class="reference internal" href="#using-the-database">Using the database</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#querying-the-database">Querying the database</a></li>
<li class="toctree-l3"><a class="reference internal" href="#adding-filters-to-the-query">Adding filters to the query</a></li>
@ -378,6 +379,30 @@ function:</p>
<p>Avoid using <a class="reference external" href="https://docs.python.org/3.7/library/time.html#time.sleep" title="(in Python v3.7)"><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.7/library/asyncio-task.html#asyncio.sleep" title="(in Python v3.7)"><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.</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 cant 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">&quot;🚫 The message could not be deleted.&quot;</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">&quot;✅ The message was deleted!&quot;</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

View file

@ -253,6 +253,8 @@
<li><a href="apireference.html#royalnet.commands.CommandInterface.alchemy">alchemy (royalnet.commands.CommandInterface attribute)</a>
</li>
<li><a href="apireference.html#royalnet.utils.andformat">andformat() (in module royalnet.utils)</a>
</li>
<li><a href="apireference.html#royalnet.error.RoyalnetRequestError.args">args() (royalnet.error.RoyalnetRequestError property)</a>
</li>
<li><a href="apireference.html#royalnet.utils.asyncify">asyncify() (in module royalnet.utils)</a>
</li>
@ -322,10 +324,12 @@
<li><a href="apireference.html#royalnet.audio.YtdlMp3.delete">(royalnet.audio.YtdlMp3 method)</a>
</li>
</ul></li>
<li><a href="apireference.html#royalnet.commands.Command.description">description (royalnet.commands.Command attribute)</a>
<li><a href="apireference.html#royalnet.commands.CommandData.delete_invoking">delete_invoking() (royalnet.commands.CommandData method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="apireference.html#royalnet.commands.Command.description">description (royalnet.commands.Command attribute)</a>
</li>
<li><a href="apireference.html#royalnet.utils.discord_escape">discord_escape() (in module royalnet.utils)</a>
</li>
<li><a href="apireference.html#royalnet.bots.DiscordBot">DiscordBot (class in royalnet.bots)</a>
@ -634,6 +638,8 @@
<h2 id="S">S</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="apireference.html#royalnet.bots.TelegramBot.safe_api_call">safe_api_call() (royalnet.bots.TelegramBot static method)</a>
</li>
<li><a href="apireference.html#royalnet.utils.safeformat">safeformat() (in module royalnet.utils)</a>
</li>
<li><a href="apireference.html#royalnet.network.RoyalnetLink.send">send() (royalnet.network.RoyalnetLink method)</a>
@ -641,11 +647,11 @@
<li><a href="apireference.html#royalnet.network.RoyalnetServer.serve">serve() (royalnet.network.RoyalnetServer method)</a>
</li>
<li><a href="apireference.html#royalnet.database.Alchemy.session_acm">session_acm() (royalnet.database.Alchemy method)</a>
</li>
<li><a href="apireference.html#royalnet.database.Alchemy.session_cm">session_cm() (royalnet.database.Alchemy method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="apireference.html#royalnet.database.Alchemy.session_cm">session_cm() (royalnet.database.Alchemy method)</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.audio.YtdlDiscord.spawn_audiosource">spawn_audiosource() (royalnet.audio.YtdlDiscord method)</a>

View file

@ -163,6 +163,7 @@
</li>
<li class="toctree-l2"><a class="reference internal" href="creatingacommand.html#running-code-at-the-initialization-of-the-bot">Running code at the initialization of the bot</a></li>
<li class="toctree-l2"><a class="reference internal" href="creatingacommand.html#coroutines-and-slow-operations">Coroutines and slow operations</a></li>
<li class="toctree-l2"><a class="reference internal" href="creatingacommand.html#delete-the-invoking-message">Delete the invoking message</a></li>
<li class="toctree-l2"><a class="reference internal" href="creatingacommand.html#using-the-database">Using the database</a><ul>
<li class="toctree-l3"><a class="reference internal" href="creatingacommand.html#querying-the-database">Querying the database</a></li>
<li class="toctree-l3"><a class="reference internal" href="creatingacommand.html#adding-filters-to-the-query">Adding filters to the query</a></li>

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -229,6 +229,32 @@ function: ::
Avoid using :py:func:`time.sleep` function, as it is considered a slow operation: use instead :py:func:`asyncio.sleep`,
a coroutine that does the same exact thing.
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 :py: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
------------------------------------

View file

@ -32,7 +32,10 @@ class GenericBot:
for SelectedCommand in commands:
log.debug(f"Binding {SelectedCommand.name}...")
interface = self._Interface()
try:
self.commands[f"{interface.prefix}{SelectedCommand.name}"] = SelectedCommand(interface)
except Exception as e:
log.error(f"{e} during the initialization of {SelectedCommand.name}, skipping...")
log.debug(f"Successfully bound commands")
def _interface_factory(self) -> typing.Type[CommandInterface]:

View file

@ -1,5 +1,6 @@
import typing
import asyncio
from ..error import UnsupportedError
if typing.TYPE_CHECKING:
from ..database import Alchemy
from ..bots import GenericBot
@ -13,15 +14,18 @@ class CommandInterface:
loop: asyncio.AbstractEventLoop = NotImplemented
def __init__(self):
if self.alchemy:
self.session = self.alchemy.Session()
else:
self.session = None
def register_net_handler(self, message_type: str, network_handler: typing.Callable):
"""Register a new handler for messages received through Royalnet."""
raise NotImplementedError()
raise UnsupportedError()
def unregister_net_handler(self, message_type: str):
"""Remove a Royalnet handler."""
raise NotImplementedError()
raise UnsupportedError()
async def net_request(self, message, destination: str) -> dict:
"""Send data through a :py:class:`royalnet.network.RoyalnetLink` and wait for a
@ -30,10 +34,10 @@ class CommandInterface:
Parameters:
message: The data to be sent. Must be :py:mod:`pickle`-able.
destination: The destination of the request, either in UUID format or node name."""
raise NotImplementedError()
raise UnsupportedError()
def register_keyboard_key(self, key_name: str, callback: typing.Callable):
raise NotImplementedError()
raise UnsupportedError()
def unregister_keyboard_key(self, key_name: str):
raise NotImplementedError()
raise UnsupportedError()

View file

@ -1,4 +1,5 @@
from .debug_error import DebugErrorCommand
from .debug_keyboard import DebugKeyboardCommand
from .debug_invoking import DebugInvokingCommand
__all__ = ["DebugErrorCommand", "DebugKeyboardCommand"]
__all__ = ["DebugErrorCommand", "DebugKeyboardCommand", "DebugInvokingCommand"]

View file

@ -4,7 +4,7 @@ from ..commandargs import CommandArgs
from ..commanddata import CommandData
class DebugKeyboardCommand(Command):
class DebugInvokingCommand(Command):
name: str = "debug_invoking"
description: str = "Elimina il messaggio di invocazione."

View file

@ -43,7 +43,8 @@ if __debug__:
VideochannelCommand,
TriviaCommand,
MmCommand,
ZawarudoCommand
ZawarudoCommand,
DebugInvokingCommand
]
log.setLevel(logging.DEBUG)
else:
@ -82,12 +83,12 @@ loop.run_until_complete(master.start())
print("Starting bots...")
ds_bot = DiscordBot(discord_config=DiscordConfig(os.environ["DS_AK"]),
royalnet_config=RoyalnetConfig(f"ws://{address}:{port}", os.environ["MASTER_KEY"]),
database_config=DatabaseConfig(os.environ["DB_PATH"], Royal, Discord, "discord_id"),
database_config=None,
sentry_dsn=sentry_dsn,
commands=commands)
tg_bot = TelegramBot(telegram_config=TelegramConfig(os.environ["TG_AK"]),
royalnet_config=RoyalnetConfig(f"ws://{address}:{port}", os.environ["MASTER_KEY"]),
database_config=DatabaseConfig(os.environ["DB_PATH"], Royal, Telegram, "tg_id"),
database_config=None,
sentry_dsn=sentry_dsn,
commands=commands)
loop.create_task(tg_bot.run())