1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-26 21:14:19 +00:00

Create Command class (#4)

*  Create Command class

*  Create Command class
This commit is contained in:
Steffo 2020-12-27 11:17:39 +01:00 committed by GitHub
parent 66fd4c65f9
commit c375ae0e10
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 0 deletions

View file

@ -34,6 +34,7 @@ release = '6.0.0a12'
extensions = [ extensions = [
"sphinx.ext.autodoc", "sphinx.ext.autodoc",
"sphinx.ext.intersphinx", "sphinx.ext.intersphinx",
'sphinx.ext.todo',
] ]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
@ -91,3 +92,7 @@ autodoc_default_options = {
'special-members': '__init__', 'special-members': '__init__',
'undoc-members': True, 'undoc-members': True,
} }
# -- Automodule settings -----------------------------------------------------
todo_include_todos = True

View file

@ -25,3 +25,8 @@ Indices and tables
* :ref:`genindex` * :ref:`genindex`
* :ref:`modindex` * :ref:`modindex`
* :ref:`search` * :ref:`search`
To do
-----
.. todolist::

View file

@ -0,0 +1,77 @@
"""
Commands are used to quickly create single-message conversations
"""
from __future__ import annotations
import royalnet.royaltyping as t
import logging
import functools
import re
from . import bullet
from . import teleporter
log = logging.getLogger(__name__)
class Command:
"""
A decorator to create a command that can be called from the chat by entering a certain :attr:`.pattern` of
characters:
.. code-block:: text
/echo Hello!
# Hello!
"""
def __init__(self,
prefix: str,
name: str,
syntax: str,
*,
pattern: str = r"^{prefix}{name} {syntax}",
doc: str = ""):
self.prefix: str = prefix
"""
The prefix used in the command (usually ``/`` or ``!``).
"""
self.name: str = name
"""
The name of the command, usually all lowercase.
"""
self.syntax: str = syntax
"""
A regex describing the syntax of the command, using named capture groups ``(?P<name>...)`` to capture arguments
that should be passed to the function.
"""
self.pattern: re.Pattern = re.compile(pattern.format(prefix=prefix, name=name, syntax=syntax))
"""
The compiled regex pattern.
By default, it :meth:`str.format` the passed string with the ``prefix``, ``name`` and ``syntax`` keyword
arguments, but this behaviour can be changed by passing a different ``pattern`` to :meth:`__init__`.
"""
self.doc: str = doc
"""
A string explaining how this command should be used. Useful for command lists or help commands.
"""
def __call__(self, f):
"""
The decorator interface of the command.
"""
@functools.wraps(f)
async def decorated(_msg: bullet.Message, **original_kwargs) -> t.Conversation:
text: str = await _msg.text()
match: re.Match = self.pattern.search(text)
match_kwargs: dict = match.groupdict()
teleported: t.Callable = teleporter.teleporter(is_async=True, validate_output=False)(f)
return await teleported(_msg=_msg, **original_kwargs, **match_kwargs)
return decorated