diff --git a/docs/doctrees/audio.doctree b/docs/doctrees/audio.doctree index 258cd466..82e89ce7 100644 Binary files a/docs/doctrees/audio.doctree and b/docs/doctrees/audio.doctree differ diff --git a/docs/doctrees/bots.doctree b/docs/doctrees/bots.doctree index d47f949f..373f899b 100644 Binary files a/docs/doctrees/bots.doctree and b/docs/doctrees/bots.doctree differ diff --git a/docs/doctrees/database.doctree b/docs/doctrees/database.doctree index a4fea25a..7882c6f9 100644 Binary files a/docs/doctrees/database.doctree and b/docs/doctrees/database.doctree differ diff --git a/docs/doctrees/environment.pickle b/docs/doctrees/environment.pickle index c0f57990..a14acc47 100644 Binary files a/docs/doctrees/environment.pickle and b/docs/doctrees/environment.pickle differ diff --git a/docs/doctrees/network.doctree b/docs/doctrees/network.doctree index 3ff65c0d..8ae8522f 100644 Binary files a/docs/doctrees/network.doctree and b/docs/doctrees/network.doctree differ diff --git a/docs/doctrees/utils.doctree b/docs/doctrees/utils.doctree index 2058f3a8..835a7550 100644 Binary files a/docs/doctrees/utils.doctree and b/docs/doctrees/utils.doctree differ diff --git a/docs/html/audio.html b/docs/html/audio.html index dbed40c7..db5fac60 100644 --- a/docs/html/audio.html +++ b/docs/html/audio.html @@ -335,12 +335,6 @@
class royalnet.audio.YtdlFile(info: royalnet.audio.youtubedl.YtdlInfo, outtmpl='%(title)s-%(id)s.%(ext)s', **ytdl_args)

A wrapper around a youtube_dl downloaded file.

-
-
-__init__(info: royalnet.audio.youtubedl.YtdlInfo, outtmpl='%(title)s-%(id)s.%(ext)s', **ytdl_args)
-

Initialize self. See help(type(self)) for accurate signature.

-
-
_stop_download()
@@ -392,13 +386,7 @@
class royalnet.audio.RoyalPCMFile(info: royalnet.audio.youtubedl.YtdlInfo, **ytdl_args)
-
-
-__init__(info: royalnet.audio.youtubedl.YtdlInfo, **ytdl_args)
-

Initialize self. See help(type(self)) for accurate signature.

-
- -
+
audio_filename

Returns: diff --git a/docs/html/bots.html b/docs/html/bots.html index cce4e2ca..641763e0 100644 --- a/docs/html/bots.html +++ b/docs/html/bots.html @@ -161,16 +161,10 @@

class royalnet.bots.TelegramBot(*, telegram_config: royalnet.bots.telegram.TelegramConfig, royalnet_config: Optional[royalnet.network.royalnetconfig.RoyalnetConfig] = None, database_config: Optional[royalnet.database.databaseconfig.DatabaseConfig] = None, command_prefix: str = '/', commands: List[Type[royalnet.utils.command.Command]] = None, missing_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>, error_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>)

A bot that connects to Telegram.

-
-
-__init__(*, telegram_config: royalnet.bots.telegram.TelegramConfig, royalnet_config: Optional[royalnet.network.royalnetconfig.RoyalnetConfig] = None, database_config: Optional[royalnet.database.databaseconfig.DatabaseConfig] = None, command_prefix: str = '/', commands: List[Type[royalnet.utils.command.Command]] = None, missing_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>, error_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>)
-

Initialize self. See help(type(self)) for accurate signature.

-
-
_call_factory() → Type[royalnet.utils.call.Call]
-

Create the Call class, representing a Call command. It should inherit from the utils.Call class.

+

Create the TelegramCall class, representing a command call. It should inherit from :py:class`royalnet.utils.Call`.

@@ -181,7 +175,8 @@
_init_client()
-
+

Create the telegram.Bot, and set the starting offset.

+
@@ -204,51 +199,40 @@
class royalnet.bots.TelegramConfig(token: str)
-

The specific configuration to be used for royalnet.database.TelegramBot.

-
-
-__init__(token: str)
-

Initialize self. See help(type(self)) for accurate signature.

-
- +

The specific configuration to be used for royalnet.database.TelegramBot.

class royalnet.bots.DiscordBot(*, discord_config: royalnet.bots.discord.DiscordConfig, royalnet_config: Optional[royalnet.network.royalnetconfig.RoyalnetConfig] = None, database_config: Optional[royalnet.database.databaseconfig.DatabaseConfig] = None, command_prefix: str = '!', commands: List[Type[royalnet.utils.command.Command]] = None, missing_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>, error_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>)

A bot that connects to Discord.

-
-
-__init__(*, discord_config: royalnet.bots.discord.DiscordConfig, royalnet_config: Optional[royalnet.network.royalnetconfig.RoyalnetConfig] = None, database_config: Optional[royalnet.database.databaseconfig.DatabaseConfig] = None, command_prefix: str = '!', commands: List[Type[royalnet.utils.command.Command]] = None, missing_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>, error_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>)
-

Initialize self. See help(type(self)) for accurate signature.

-
-
_bot_factory() → Type[discord.client.Client]
-

Create a new DiscordClient class based on this DiscordBot.

+

Create a custom DiscordClient class inheriting from discord.Client.

_call_factory() → Type[royalnet.utils.call.Call]
-

Create the Call class, representing a Call command. It should inherit from the utils.Call class.

+

Create the TelegramCall class, representing a command call. It should inherit from :py:class`royalnet.utils.Call`.

_init_client()
-

Create a bot instance.

+

Create an instance of the DiscordClient class created in royalnet.bots.discord._bot_factory().

_init_voice()
-
+

Initialize the variables needed for the connection to voice chat.

+
-add_to_music_data(audio_sources: List[discord.player.AudioSource], guild: discord.guild.Guild)
+add_to_music_data(audio_sources: List[royalnet.audio.royalpcmaudio.RoyalPCMAudio], guild: discord.guild.Guild)

Add a file to the corresponding music_data object.

@@ -266,72 +250,64 @@
run()
-

A blocking coroutine that should make the bot start listening to commands and requests.

+

Login to Discord, then run the bot.

-update_activity_with_source_title(rpa: Optional[royalnet.audio.royalpcmaudio.RoyalPCMAudio] = None)
-
+update_activity_with_source_title() +

Change the bot’s presence (using discord.Client.change_presence()) to match the current listening status.

+

If multiple guilds are using the bot, the bot will always have an empty presence.

+
class royalnet.bots.DiscordConfig(token: str)
-

The specific configuration to be used for royalnet.database.DiscordBot.

-
-
-__init__(token: str)
-

Initialize self. See help(type(self)) for accurate signature.

-
- +

The specific configuration to be used for royalnet.database.DiscordBot.

class royalnet.bots.GenericBot(*, royalnet_config: Optional[royalnet.network.royalnetconfig.RoyalnetConfig] = None, database_config: Optional[royalnet.database.databaseconfig.DatabaseConfig] = None, command_prefix: str, commands: List[Type[royalnet.utils.command.Command]] = None, missing_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>, error_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>)

A generic bot class, to be used as base for the other more specific classes, such as royalnet.bots.TelegramBot and royalnet.bots.DiscordBot.

-
-
-__init__(*, royalnet_config: Optional[royalnet.network.royalnetconfig.RoyalnetConfig] = None, database_config: Optional[royalnet.database.databaseconfig.DatabaseConfig] = None, command_prefix: str, commands: List[Type[royalnet.utils.command.Command]] = None, missing_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>, error_command: Type[royalnet.utils.command.Command] = <class 'royalnet.commands.null.NullCommand'>)
-

Initialize self. See help(type(self)) for accurate signature.

-
-
_call_factory() → Type[royalnet.utils.call.Call]
-

Create the Call class, representing a Call command. It should inherit from the utils.Call class.

+

Create the TelegramCall class, representing a command call. It should inherit from :py:class`royalnet.utils.Call`.

_init_commands(command_prefix: str, commands: List[Type[royalnet.utils.command.Command]], missing_command: Type[royalnet.utils.command.Command], error_command: Type[royalnet.utils.command.Command])
-

Generate the commands dictionary required to handle incoming messages, and the network_handlers dictionary required to handle incoming requests.

+

Generate the commands dictionary required to handle incoming messages, and the network_handlers dictionary required to handle incoming requests.

_init_database(commands: List[Type[royalnet.utils.command.Command]], database_config: royalnet.database.databaseconfig.DatabaseConfig)
-

Connect to the database, and create the missing tables required by the selected commands.

+

Create an royalnet.network.Alchemy with the tables required by the commands. Then, find the chain that links the master_table to the identity_table.

_init_royalnet(royalnet_config: royalnet.network.royalnetconfig.RoyalnetConfig)
-

Create a RoyalnetLink, and run it as a task.

+

Create a royalnet.network.RoyalnetLink, and run it as a asyncio.Task.

_network_handler(message: royalnet.network.messages.Message) → royalnet.network.messages.Message
-

Handle a single Message received from the RoyalnetLink

+

Handle a single royalnet.network.Message received from the royalnet.network.RoyalnetLink

call(command_name: str, channel, parameters: List[str] = None, **kwargs)
-

Call a command by its string, or missing_command if it doesn’t exists, or error_command if an exception is raised during the execution.

+

Call the command with the specified name.

+

If it doesn’t exist, call self.missing_command.

+

If an exception is raised during the execution of the command, call self.error_command.

diff --git a/docs/html/database.html b/docs/html/database.html index 924c28d2..b6d99cbb 100644 --- a/docs/html/database.html +++ b/docs/html/database.html @@ -205,12 +205,6 @@
class royalnet.database.DatabaseConfig(database_uri: str, master_table: Type[CT_co], identity_table: Type[CT_co], identity_column_name: str)

The configuration to be used for the royalnet.database.Alchemy component of royalnet.bots.GenericBot.

-
-
-__init__(database_uri: str, master_table: Type[CT_co], identity_table: Type[CT_co], identity_column_name: str)
-

Initialize self. See help(type(self)) for accurate signature.

-
-
@@ -265,7 +259,7 @@
-royal = <RelationshipProperty at 0x6fa26f0; no key>
+royal = <RelationshipProperty at 0x7a70300; no key>
@@ -295,7 +289,7 @@
-creator = <RelationshipProperty at 0x6fa2270; no key>
+creator = <RelationshipProperty at 0x7a70348; no key>
@@ -320,7 +314,7 @@
-quoted_account = <RelationshipProperty at 0x6fa2c90; no key>
+quoted_account = <RelationshipProperty at 0x7a70978; no key>
@@ -355,7 +349,7 @@
-royal = <RelationshipProperty at 0x6fa2588; no key>
+royal = <RelationshipProperty at 0x7a70198; no key>
@@ -370,7 +364,7 @@ class royalnet.database.tables.ActiveKvGroup
-group = <RelationshipProperty at 0x6fa2fa8; no key>
+group = <RelationshipProperty at 0x7a701e0; no key>
@@ -380,7 +374,7 @@
-royal = <RelationshipProperty at 0x6fa2d20; no key>
+royal = <RelationshipProperty at 0x7a70b70; no key>
@@ -395,7 +389,7 @@ class royalnet.database.tables.Keyvalue
-group = <RelationshipProperty at 0x6fa2270; no key>
+group = <RelationshipProperty at 0x7a709c0; no key>
@@ -450,7 +444,7 @@
-royal = <RelationshipProperty at 0x6fa2f18; no key>
+royal = <RelationshipProperty at 0x7a70a08; no key>
diff --git a/docs/html/genindex.html b/docs/html/genindex.html index d21b0a41..023f1643 100644 --- a/docs/html/genindex.html +++ b/docs/html/genindex.html @@ -187,46 +187,16 @@
  • (royalnet.audio.Pool method)
  • (royalnet.audio.RoyalPCMAudio method) -
  • -
  • (royalnet.audio.RoyalPCMFile method) -
  • -
  • (royalnet.audio.YtdlFile method)
  • (royalnet.audio.YtdlInfo method) -
  • -
  • (royalnet.bots.DiscordBot method) -
  • -
  • (royalnet.bots.DiscordConfig method) -
  • -
  • (royalnet.bots.GenericBot method) -
  • -
  • (royalnet.bots.TelegramBot method) -
  • -
  • (royalnet.bots.TelegramConfig method)
  • (royalnet.database.Alchemy method) -
  • -
  • (royalnet.database.DatabaseConfig method) -
  • -
  • (royalnet.network.NetworkError method)
  • (royalnet.network.Package method)
  • (royalnet.network.RequestError method) -
  • -
  • (royalnet.network.RoyalnetConfig method) -
  • -
  • (royalnet.network.RoyalnetLink method) -
  • -
  • (royalnet.network.RoyalnetServer method) -
  • -
  • (royalnet.network.ServerErrorMessage method) -
  • -
  • (royalnet.utils.Call method)
  • - - + +
    @@ -198,12 +192,6 @@
    -
    -__init__(master_uri: str, secret: str, link_type: str, request_handler, *, loop: asyncio.events.AbstractEventLoop = <_WindowsSelectorEventLoop running=False closed=False debug=False>)
    -

    Initialize self. See help(type(self)) for accurate signature.

    -
    - -
    connect()
    @@ -238,18 +226,13 @@
    exception royalnet.network.NetworkError(error_msg: royalnet.network.messages.ServerErrorMessage, *args)
    -
    -
    -__init__(error_msg: royalnet.network.messages.ServerErrorMessage, *args)
    -

    Initialize self. See help(type(self)) for accurate signature.

    -
    - -
    +
    exception royalnet.network.NotConnectedError
    -
    +

    The royalnet.network.RoyalnetLink is not connected to a royalnet.network.RoyalnetServer.

    +
    @@ -308,12 +291,6 @@
    class royalnet.network.RoyalnetServer(address: str, port: int, required_secret: str, *, loop: asyncio.events.AbstractEventLoop = <_WindowsSelectorEventLoop running=False closed=False debug=False>)
    -
    -__init__(address: str, port: int, required_secret: str, *, loop: asyncio.events.AbstractEventLoop = <_WindowsSelectorEventLoop running=False closed=False debug=False>)
    -

    Initialize self. See help(type(self)) for accurate signature.

    -
    - -
    find_client(*, nid: str = None, link_type: str = None) → List[royalnet.network.royalnetserver.ConnectedClient]
    @@ -395,10 +372,17 @@
    class royalnet.network.RoyalnetConfig(master_uri: str, master_secret: str)
    -
    -
    -__init__(master_uri: str, master_secret: str)
    -

    Initialize self. See help(type(self)) for accurate signature.

    +
    + +
    +
    +class royalnet.network.Reply
    +

    A reply to a request sent through the Royalnet.

    +
    +
    +raise_on_error() → None
    +

    If the reply is an error, raise an error, otherwise, do nothing.

    +

    :raises A RoyalnetError, if the Reply is an error, otherwise, nothing.:

    diff --git a/docs/html/objects.inv b/docs/html/objects.inv index 258fa7d9..4a2407b5 100644 Binary files a/docs/html/objects.inv and b/docs/html/objects.inv differ diff --git a/docs/html/searchindex.js b/docs/html/searchindex.js index 2ee1e738..5d4d124d 100644 --- a/docs/html/searchindex.js +++ b/docs/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["audio","bots","commands","database","index","network","utils"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["audio.rst","bots.rst","commands.rst","database.rst","index.rst","network.rst","utils.rst"],objects:{"royalnet.audio":{PlayMode:[0,1,1,""],Playlist:[0,1,1,""],Pool:[0,1,1,""],RoyalPCMAudio:[0,1,1,""],RoyalPCMFile:[0,1,1,""],YtdlFile:[0,1,1,""],YtdlInfo:[0,1,1,""]},"royalnet.audio.PlayMode":{"delete":[0,2,1,""],__init__:[0,2,1,""],_generate_generator:[0,2,1,""],add:[0,2,1,""],next:[0,2,1,""],videos_left:[0,2,1,""]},"royalnet.audio.Playlist":{"delete":[0,2,1,""],__init__:[0,2,1,""],_generate_generator:[0,2,1,""],add:[0,2,1,""],videos_left:[0,2,1,""]},"royalnet.audio.Pool":{"delete":[0,2,1,""],__init__:[0,2,1,""],_generate_generator:[0,2,1,""],add:[0,2,1,""],videos_left:[0,2,1,""]},"royalnet.audio.RoyalPCMAudio":{"delete":[0,2,1,""],__init__:[0,2,1,""],create_from_url:[0,3,1,""],create_from_ytsearch:[0,3,1,""],is_opus:[0,2,1,""],read:[0,2,1,""]},"royalnet.audio.RoyalPCMFile":{__init__:[0,2,1,""],audio_filename:[0,4,1,""],create_from_url:[0,3,1,""],create_from_ytsearch:[0,3,1,""],delete_audio_file:[0,2,1,""],ytdl_args:[0,4,1,""],ytdl_filename:[0,4,1,""]},"royalnet.audio.YtdlFile":{__init__:[0,2,1,""],_stop_download:[0,2,1,""],create_from_url:[0,3,1,""],delete_video_file:[0,2,1,""],ytdl_args:[0,4,1,""]},"royalnet.audio.YtdlInfo":{__init__:[0,2,1,""],create_from_url:[0,3,1,""],download:[0,2,1,""]},"royalnet.bots":{DiscordBot:[1,1,1,""],DiscordConfig:[1,1,1,""],GenericBot:[1,1,1,""],TelegramBot:[1,1,1,""],TelegramConfig:[1,1,1,""]},"royalnet.bots.DiscordBot":{__init__:[1,2,1,""],_bot_factory:[1,2,1,""],_call_factory:[1,2,1,""],_init_client:[1,2,1,""],_init_voice:[1,2,1,""],add_to_music_data:[1,2,1,""],advance_music_data:[1,2,1,""],interface_name:[1,4,1,""],run:[1,2,1,""],update_activity_with_source_title:[1,2,1,""]},"royalnet.bots.DiscordConfig":{__init__:[1,2,1,""]},"royalnet.bots.GenericBot":{__init__:[1,2,1,""],_call_factory:[1,2,1,""],_init_commands:[1,2,1,""],_init_database:[1,2,1,""],_init_royalnet:[1,2,1,""],_network_handler:[1,2,1,""],call:[1,2,1,""],interface_name:[1,4,1,""],run:[1,2,1,""]},"royalnet.bots.TelegramBot":{__init__:[1,2,1,""],_call_factory:[1,2,1,""],_handle_update:[1,2,1,""],_init_client:[1,2,1,""],botfather_command_string:[1,4,1,""],interface_name:[1,4,1,""],run:[1,2,1,""]},"royalnet.bots.TelegramConfig":{__init__:[1,2,1,""]},"royalnet.commands":{AuthorCommand:[2,1,1,""],CiaoruoziCommand:[2,1,1,""],ColorCommand:[2,1,1,""],DateparserCommand:[2,1,1,""],DiarioCommand:[2,1,1,""],KvCommand:[2,1,1,""],KvactiveCommand:[2,1,1,""],KvrollCommand:[2,1,1,""],NullCommand:[2,1,1,""],PingCommand:[2,1,1,""],PlayCommand:[2,1,1,""],PlaymodeCommand:[2,1,1,""],RageCommand:[2,1,1,""],ReminderCommand:[2,1,1,""],ShipCommand:[2,1,1,""],SkipCommand:[2,1,1,""],SmecdsCommand:[2,1,1,""],SummonCommand:[2,1,1,""],SyncCommand:[2,1,1,""],VideoinfoCommand:[2,1,1,""]},"royalnet.database":{Alchemy:[3,1,1,""],DatabaseConfig:[3,1,1,""],relationshiplinkchain:[3,5,1,""],tables:[3,0,0,"-"]},"royalnet.database.Alchemy":{__init__:[3,2,1,""],_create_tables:[3,2,1,""],session_acm:[3,2,1,""],session_cm:[3,2,1,""]},"royalnet.database.DatabaseConfig":{__init__:[3,2,1,""]},"royalnet.database.tables":{ActiveKvGroup:[3,1,1,""],Alias:[3,1,1,""],Diario:[3,1,1,""],Discord:[3,1,1,""],Keygroup:[3,1,1,""],Keyvalue:[3,1,1,""],Royal:[3,1,1,""],Telegram:[3,1,1,""]},"royalnet.database.tables.ActiveKvGroup":{group:[3,4,1,""],group_name:[3,4,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""]},"royalnet.database.tables.Alias":{alias:[3,4,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""]},"royalnet.database.tables.Diario":{context:[3,4,1,""],creator:[3,4,1,""],creator_id:[3,4,1,""],diario_id:[3,4,1,""],media_url:[3,4,1,""],quoted:[3,4,1,""],quoted_account:[3,4,1,""],quoted_account_id:[3,4,1,""],spoiler:[3,4,1,""],text:[3,4,1,""],timestamp:[3,4,1,""]},"royalnet.database.tables.Discord":{avatar_hash:[3,4,1,""],discord_id:[3,4,1,""],discriminator:[3,4,1,""],full_username:[3,2,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""],username:[3,4,1,""]},"royalnet.database.tables.Keygroup":{group_name:[3,4,1,""]},"royalnet.database.tables.Keyvalue":{group:[3,4,1,""],group_name:[3,4,1,""],key:[3,4,1,""],value:[3,4,1,""]},"royalnet.database.tables.Royal":{avatar:[3,4,1,""],password:[3,4,1,""],role:[3,4,1,""],uid:[3,4,1,""],username:[3,4,1,""]},"royalnet.database.tables.Telegram":{first_name:[3,4,1,""],last_name:[3,4,1,""],mention:[3,2,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""],tg_id:[3,4,1,""],username:[3,4,1,""]},"royalnet.network":{InvalidDestinationEM:[5,1,1,""],InvalidPackageEM:[5,1,1,""],InvalidSecretEM:[5,1,1,""],Message:[5,1,1,""],NetworkError:[5,6,1,""],NotConnectedError:[5,6,1,""],NotIdentifiedError:[5,6,1,""],Package:[5,1,1,""],RequestError:[5,1,1,""],RequestSuccessful:[5,1,1,""],RoyalnetConfig:[5,1,1,""],RoyalnetLink:[5,1,1,""],RoyalnetServer:[5,1,1,""],ServerErrorMessage:[5,1,1,""]},"royalnet.network.NetworkError":{__init__:[5,2,1,""]},"royalnet.network.Package":{__init__:[5,2,1,""],pickle:[5,2,1,""],reply:[5,2,1,""]},"royalnet.network.RequestError":{__init__:[5,2,1,""],raise_on_error:[5,2,1,""]},"royalnet.network.RequestSuccessful":{raise_on_error:[5,2,1,""]},"royalnet.network.RoyalnetConfig":{__init__:[5,2,1,""]},"royalnet.network.RoyalnetLink":{__init__:[5,2,1,""],connect:[5,2,1,""],identify:[5,2,1,""],receive:[5,2,1,""],request:[5,2,1,""],run:[5,2,1,""],send:[5,2,1,""]},"royalnet.network.RoyalnetServer":{__init__:[5,2,1,""],find_client:[5,2,1,""],find_destination:[5,2,1,""],listener:[5,2,1,""],route_package:[5,2,1,""],serve:[5,2,1,""],start:[5,2,1,""]},"royalnet.network.ServerErrorMessage":{__init__:[5,2,1,""]},"royalnet.utils":{Call:[6,1,1,""],Command:[6,1,1,""],CommandArgs:[6,1,1,""],NetworkHandler:[6,1,1,""],asyncify:[6,5,1,""],cdj:[6,5,1,""],plusformat:[6,5,1,""],safefilename:[6,5,1,""],safeformat:[6,5,1,""],sleep_until:[6,5,1,""]},"royalnet.utils.Call":{__init__:[6,2,1,""],alchemy:[6,4,1,""],get_author:[6,2,1,""],interface_name:[6,4,1,""],interface_obj:[6,4,1,""],interface_prefix:[6,4,1,""],net_request:[6,2,1,""],reply:[6,2,1,""],run:[6,2,1,""],session_end:[6,2,1,""],session_init:[6,2,1,""]},"royalnet.utils.Command":{command_description:[6,4,1,""],command_name:[6,4,1,""],command_syntax:[6,4,1,""],common:[6,7,1,""],network_handler_dict:[6,7,1,""],network_handlers:[6,4,1,""],require_alchemy_tables:[6,4,1,""]},"royalnet.utils.CommandArgs":{joined:[6,2,1,""],match:[6,2,1,""],optional:[6,2,1,""]},"royalnet.utils.NetworkHandler":{message_type:[6,4,1,""]},royalnet:{audio:[0,0,0,"-"],bots:[1,0,0,"-"],commands:[2,0,0,"-"],database:[3,0,0,"-"],network:[5,0,0,"-"],utils:[6,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","staticmethod","Python static method"],"4":["py","attribute","Python attribute"],"5":["py","function","Python function"],"6":["py","exception","Python exception"],"7":["py","classmethod","Python class method"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:staticmethod","4":"py:attribute","5":"py:function","6":"py:exception","7":"py:classmethod"},terms:{"0x6fa2270":3,"0x6fa2588":3,"0x6fa26f0":3,"0x6fa2c90":3,"0x6fa2d20":3,"0x6fa2f18":3,"0x6fa2fa8":3,"20m":0,"48khz":0,"abstract":6,"boolean":3,"byte":[0,5],"class":[0,1,2,3,5,6],"default":[0,3,6],"float":0,"function":[0,6],"int":[0,5,6],"new":[0,1,3,6],"null":[1,5],"return":[0,1,5,6],"static":0,"true":[0,3,6],"try":[1,6],"while":[0,1,3],Not:0,That:6,The:[0,1,3,5,6],Use:3,__init__:[0,1,3,5,6],_bot_factori:1,_call_factori:1,_create_t:3,_generate_gener:0,_handle_upd:1,_init_cli:1,_init_command:1,_init_databas:1,_init_royalnet:1,_init_voic:1,_network_handl:1,_stop_download:0,_windowsselectoreventloop:5,about:0,abstracteventloop:5,accur:[0,1,3,5,6],activekvgroup:3,add:[0,1],add_to_music_data:1,address:5,advanc:0,advance_music_data:1,akin:5,alchemi:[3,6],alia:3,all:0,allow:3,alreadi:0,also:[0,5],altern:5,alwai:5,amount:0,ani:[0,6],anoth:5,answer:6,anystr:6,arg:[5,6],argument:[0,6],around:[0,3],async:[0,3],asyncifi:6,asyncio:5,asyncron:3,attribut:6,audio:[1,4],audio_filenam:0,audio_sourc:1,audiosourc:[0,1],author:6,authorcommand:2,avatar:3,avatar_hash:3,base:[0,1],been:0,bestaudio:0,biginteg:3,bit:0,block:1,bool:6,bot:[3,4],botfather_command_str:1,both:3,call:[1,6],callabl:6,can:5,caus:5,cdj:6,chang:0,channel:[1,6],check:[0,3],ciaoruozicommand:2,class_:6,classmethod:6,clean:6,client:1,close:5,colorcommand:2,column:3,columndefault:3,command:[1,4,6],command_arg:6,command_descript:6,command_nam:[1,6],command_prefix:1,command_syntax:6,commandarg:6,common:6,commun:5,compat:0,complet:0,compon:3,configur:[1,3],connect:[1,5],connectedcli:5,contain:[0,5],context:3,convers:5,convert:0,core:3,coroutin:1,correspond:[0,1],creat:[0,1,3,5,6],create_from_url:0,create_from_ytsearch:0,creator:3,creator_id:3,ct_co:3,custom:0,data:[0,5,6],databas:[1,4,6],database_config:1,database_uri:3,databaseconfig:[1,3],dateparsercommand:2,datetim:[3,6],debug:5,declar:3,delet:0,delete_audio_fil:0,delete_video_fil:0,describ:3,destin:[5,6],destination_conv_id:5,detail:3,diario:3,diario_id:3,diariocommand:2,dict:[0,6],dictionari:1,discord:[0,1,3],discord_config:1,discord_id:3,discordbot:1,discordcli:1,discordconfig:1,discrimin:3,doc:3,doe:[0,5,6],doesn:1,download:0,dure:1,each:0,either:0,empti:0,encod:0,end:3,ending_class:3,engin:3,error:5,error_command:1,error_if_non:6,error_msg:5,event:5,everi:[0,5],exc:5,except:[1,5],execut:[1,5],exist:[1,6],ext:0,extra:0,extract:0,extract_info:0,factori:0,fals:[0,3,5,6],file:[0,1],find:[3,5,6],find_client:5,find_destin:5,first:0,first_nam:3,follow:3,foreignkei:3,form:5,format:0,found:[5,6],frame:0,from:[0,1,3,6],full_usernam:3,gener:[0,1,6],genericbot:[1,3],get:[0,3],get_author:6,going:0,group:3,group_nam:3,guild:1,handl:1,has:0,help:[0,1,3,5,6],html:3,http:3,identifi:[5,6],identity_column_nam:3,identity_t:3,ignore_escap:6,implement:0,incom:1,incorrect:5,index:[4,6],inf:0,infinit:0,info:0,inherit:[0,1],initi:[0,1,3,5,6],insid:0,instanc:1,instead:0,integ:3,interface_nam:[1,6],interface_obj:6,interface_prefix:6,invalid:5,invaliddestinationem:5,invalidinputerror:6,invalidpackageem:5,invalidsecretem:5,is_opu:0,item:0,its:1,join:6,just:1,keep:0,kei:3,keygroup:3,keyvalu:3,kvactivecommand:2,kvcommand:2,kvrollcommand:2,kwarg:[1,6],largebinari:3,last_nam:3,least:0,left:0,like:0,link:5,link_typ:5,list:[0,1,5,6],listen:[1,5],logger:0,loop:5,made:6,mai:0,maintain:3,make:1,manag:3,master_secret:5,master_t:3,master_uri:5,match:6,math:0,mean:6,media_url:3,memori:0,mention:3,messag:[1,5,6],message_typ:6,method:0,miss:1,missing_command:1,modul:4,more:[1,3],multipl:3,music_data:1,must:[0,5,6],name:0,net_request:6,network:[1,4,6],network_handl:[1,6],network_handler_dict:6,networkerror:5,networkhandl:6,next:[0,1],nid:5,no_warn:0,nobodi:5,node:5,none:[0,1,3,5,6],noplaylist:0,notconnectederror:5,noth:5,notidentifiederror:5,notimpl:[1,6],now_plai:0,nullabl:3,nullcommand:[1,2],number:[0,5],object:[0,1,3],onc:[0,3],option:[0,1,3,6],opu:0,order:0,org:3,other:1,otherwis:[0,1,5],outtmpl:0,packag:5,packet:5,page:4,paramet:[0,1,3,5],pass:0,password:3,path:3,pattern:6,pcm:0,per:0,perman:0,pickl:5,pickleabl:6,pingcommand:2,plai:[0,1],playcommand:2,player:1,playlist:0,playmod:0,playmodecommand:2,plusformat:6,pool:0,port:5,primary_kei:3,probabl:[0,6],properti:0,quiet:0,quot:3,quoted_account:3,quoted_account_id:3,ragecommand:2,rais:[1,5,6],raise_on_error:5,random:0,read:0,reason:5,receiv:[1,5,6],recommend:0,relationshiplinkchain:3,relationshipproperti:3,remindercommand:2,remov:0,repeat:0,repli:[5,6],repres:[0,1],request:[1,5,6],request_handl:5,request_uri:5,requesterror:5,requestsuccess:5,requir:1,require_alchemy_t:6,require_at_least:6,required_secret:5,rest:6,role:3,rout:5,route_packag:5,row:6,royal:3,royal_id:3,royalnet_config:1,royalnetconfig:[1,5],royalneterror:5,royalnetlink:[1,5],royalnetserv:5,royalpcmaudio:[0,1],royalpcmfil:0,rpa:1,rpf:0,run:[1,5,6],safefilenam:6,safeformat:6,search:[0,4],secret:5,see:[0,1,3,5,6],select:[0,1,3],self:[0,1,3,5,6],send:[5,6],sent:[5,6],sequenc:[5,6],serv:5,server:5,servererrormessag:5,session_acm:3,session_cm:3,session_end:6,session_init:6,set:[3,6],shipcommand:2,should:[1,5,6],signal:0,signatur:[0,1,3,5,6],singl:[1,3],skipcommand:2,sleep_until:6,smecdscommand:2,someth:5,somewher:5,song:[0,1],soon:0,sourc:[0,5,6],source_conv_id:5,specif:[1,6],spoiler:3,sqlalchemi:3,start:[1,3,5],starting_class:3,starting_list:0,starting_pool:0,statement:3,stereo:0,still:6,str:[0,1,3,5,6],string:[0,1,3,6],subbot:6,subclass:0,submodul:3,success:5,summoncommand:2,synccommand:2,tabl:1,task:1,telegram:[1,3],telegram_config:1,telegrambot:1,telegramconfig:1,termin:5,text:[3,6],tg_id:3,them:3,thi:[0,1,5,6],those:0,through:5,time:5,timestamp:3,titl:0,token:1,tupl:3,type:[0,1,3,5,6],uid:3,union:0,univers:6,unregisterederror:6,until:0,updat:1,update_activity_with_source_titl:1,uri:3,url:0,use:[0,3],used:[1,3],useful:0,user:6,usernam:3,usual:[0,5],util:[1,4],valu:[0,3,5],veri:0,video:0,videoinfocommand:2,videos_left:0,wai:0,wait:6,want:0,warn:0,wasn:5,websocket:5,websocketserverprotocol:5,went:5,when:6,which:[0,5],word:6,worth:0,wrapper:[0,3],wrong:5,yield:0,you:0,youtub:0,youtube_dl:0,youtubedl:0,ytdl_arg:0,ytdl_filenam:0,ytdlfile:0,ytdlinfo:0},titles:["royalnet.audio","royalnet.bots","royalnet.commands","royalnet.database","royalnet","royalnet.network","royalnet.utils"],titleterms:{audio:0,bot:1,command:2,databas:3,indic:4,network:5,royalnet:[0,1,2,3,4,5,6],tabl:[3,4],util:6}}) \ No newline at end of file +Search.setIndex({docnames:["audio","bots","commands","database","index","network","utils"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,sphinx:56},filenames:["audio.rst","bots.rst","commands.rst","database.rst","index.rst","network.rst","utils.rst"],objects:{"royalnet.audio":{PlayMode:[0,1,1,""],Playlist:[0,1,1,""],Pool:[0,1,1,""],RoyalPCMAudio:[0,1,1,""],RoyalPCMFile:[0,1,1,""],YtdlFile:[0,1,1,""],YtdlInfo:[0,1,1,""]},"royalnet.audio.PlayMode":{"delete":[0,2,1,""],__init__:[0,2,1,""],_generate_generator:[0,2,1,""],add:[0,2,1,""],next:[0,2,1,""],videos_left:[0,2,1,""]},"royalnet.audio.Playlist":{"delete":[0,2,1,""],__init__:[0,2,1,""],_generate_generator:[0,2,1,""],add:[0,2,1,""],videos_left:[0,2,1,""]},"royalnet.audio.Pool":{"delete":[0,2,1,""],__init__:[0,2,1,""],_generate_generator:[0,2,1,""],add:[0,2,1,""],videos_left:[0,2,1,""]},"royalnet.audio.RoyalPCMAudio":{"delete":[0,2,1,""],__init__:[0,2,1,""],create_from_url:[0,3,1,""],create_from_ytsearch:[0,3,1,""],is_opus:[0,2,1,""],read:[0,2,1,""]},"royalnet.audio.RoyalPCMFile":{audio_filename:[0,4,1,""],create_from_url:[0,3,1,""],create_from_ytsearch:[0,3,1,""],delete_audio_file:[0,2,1,""],ytdl_args:[0,4,1,""],ytdl_filename:[0,4,1,""]},"royalnet.audio.YtdlFile":{_stop_download:[0,2,1,""],create_from_url:[0,3,1,""],delete_video_file:[0,2,1,""],ytdl_args:[0,4,1,""]},"royalnet.audio.YtdlInfo":{__init__:[0,2,1,""],create_from_url:[0,3,1,""],download:[0,2,1,""]},"royalnet.bots":{DiscordBot:[1,1,1,""],DiscordConfig:[1,1,1,""],GenericBot:[1,1,1,""],TelegramBot:[1,1,1,""],TelegramConfig:[1,1,1,""]},"royalnet.bots.DiscordBot":{_bot_factory:[1,2,1,""],_call_factory:[1,2,1,""],_init_client:[1,2,1,""],_init_voice:[1,2,1,""],add_to_music_data:[1,2,1,""],advance_music_data:[1,2,1,""],interface_name:[1,4,1,""],run:[1,2,1,""],update_activity_with_source_title:[1,2,1,""]},"royalnet.bots.GenericBot":{_call_factory:[1,2,1,""],_init_commands:[1,2,1,""],_init_database:[1,2,1,""],_init_royalnet:[1,2,1,""],_network_handler:[1,2,1,""],call:[1,2,1,""],interface_name:[1,4,1,""],run:[1,2,1,""]},"royalnet.bots.TelegramBot":{_call_factory:[1,2,1,""],_handle_update:[1,2,1,""],_init_client:[1,2,1,""],botfather_command_string:[1,4,1,""],interface_name:[1,4,1,""],run:[1,2,1,""]},"royalnet.commands":{AuthorCommand:[2,1,1,""],CiaoruoziCommand:[2,1,1,""],ColorCommand:[2,1,1,""],DateparserCommand:[2,1,1,""],DiarioCommand:[2,1,1,""],KvCommand:[2,1,1,""],KvactiveCommand:[2,1,1,""],KvrollCommand:[2,1,1,""],NullCommand:[2,1,1,""],PingCommand:[2,1,1,""],PlayCommand:[2,1,1,""],PlaymodeCommand:[2,1,1,""],RageCommand:[2,1,1,""],ReminderCommand:[2,1,1,""],ShipCommand:[2,1,1,""],SkipCommand:[2,1,1,""],SmecdsCommand:[2,1,1,""],SummonCommand:[2,1,1,""],SyncCommand:[2,1,1,""],VideoinfoCommand:[2,1,1,""]},"royalnet.database":{Alchemy:[3,1,1,""],DatabaseConfig:[3,1,1,""],relationshiplinkchain:[3,5,1,""],tables:[3,0,0,"-"]},"royalnet.database.Alchemy":{__init__:[3,2,1,""],_create_tables:[3,2,1,""],session_acm:[3,2,1,""],session_cm:[3,2,1,""]},"royalnet.database.tables":{ActiveKvGroup:[3,1,1,""],Alias:[3,1,1,""],Diario:[3,1,1,""],Discord:[3,1,1,""],Keygroup:[3,1,1,""],Keyvalue:[3,1,1,""],Royal:[3,1,1,""],Telegram:[3,1,1,""]},"royalnet.database.tables.ActiveKvGroup":{group:[3,4,1,""],group_name:[3,4,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""]},"royalnet.database.tables.Alias":{alias:[3,4,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""]},"royalnet.database.tables.Diario":{context:[3,4,1,""],creator:[3,4,1,""],creator_id:[3,4,1,""],diario_id:[3,4,1,""],media_url:[3,4,1,""],quoted:[3,4,1,""],quoted_account:[3,4,1,""],quoted_account_id:[3,4,1,""],spoiler:[3,4,1,""],text:[3,4,1,""],timestamp:[3,4,1,""]},"royalnet.database.tables.Discord":{avatar_hash:[3,4,1,""],discord_id:[3,4,1,""],discriminator:[3,4,1,""],full_username:[3,2,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""],username:[3,4,1,""]},"royalnet.database.tables.Keygroup":{group_name:[3,4,1,""]},"royalnet.database.tables.Keyvalue":{group:[3,4,1,""],group_name:[3,4,1,""],key:[3,4,1,""],value:[3,4,1,""]},"royalnet.database.tables.Royal":{avatar:[3,4,1,""],password:[3,4,1,""],role:[3,4,1,""],uid:[3,4,1,""],username:[3,4,1,""]},"royalnet.database.tables.Telegram":{first_name:[3,4,1,""],last_name:[3,4,1,""],mention:[3,2,1,""],royal:[3,4,1,""],royal_id:[3,4,1,""],tg_id:[3,4,1,""],username:[3,4,1,""]},"royalnet.network":{InvalidDestinationEM:[5,1,1,""],InvalidPackageEM:[5,1,1,""],InvalidSecretEM:[5,1,1,""],Message:[5,1,1,""],NetworkError:[5,6,1,""],NotConnectedError:[5,6,1,""],NotIdentifiedError:[5,6,1,""],Package:[5,1,1,""],Reply:[5,1,1,""],RequestError:[5,1,1,""],RequestSuccessful:[5,1,1,""],RoyalnetConfig:[5,1,1,""],RoyalnetLink:[5,1,1,""],RoyalnetServer:[5,1,1,""],ServerErrorMessage:[5,1,1,""]},"royalnet.network.Package":{__init__:[5,2,1,""],pickle:[5,2,1,""],reply:[5,2,1,""]},"royalnet.network.Reply":{raise_on_error:[5,2,1,""]},"royalnet.network.RequestError":{__init__:[5,2,1,""],raise_on_error:[5,2,1,""]},"royalnet.network.RequestSuccessful":{raise_on_error:[5,2,1,""]},"royalnet.network.RoyalnetLink":{connect:[5,2,1,""],identify:[5,2,1,""],receive:[5,2,1,""],request:[5,2,1,""],run:[5,2,1,""],send:[5,2,1,""]},"royalnet.network.RoyalnetServer":{find_client:[5,2,1,""],find_destination:[5,2,1,""],listener:[5,2,1,""],route_package:[5,2,1,""],serve:[5,2,1,""],start:[5,2,1,""]},"royalnet.utils":{Call:[6,1,1,""],Command:[6,1,1,""],CommandArgs:[6,1,1,""],NetworkHandler:[6,1,1,""],asyncify:[6,5,1,""],cdj:[6,5,1,""],plusformat:[6,5,1,""],safefilename:[6,5,1,""],safeformat:[6,5,1,""],sleep_until:[6,5,1,""]},"royalnet.utils.Call":{alchemy:[6,4,1,""],get_author:[6,2,1,""],interface_name:[6,4,1,""],interface_obj:[6,4,1,""],interface_prefix:[6,4,1,""],net_request:[6,2,1,""],reply:[6,2,1,""],run:[6,2,1,""],session_end:[6,2,1,""],session_init:[6,2,1,""]},"royalnet.utils.Command":{command_description:[6,4,1,""],command_name:[6,4,1,""],command_syntax:[6,4,1,""],common:[6,7,1,""],network_handler_dict:[6,7,1,""],network_handlers:[6,4,1,""],require_alchemy_tables:[6,4,1,""]},"royalnet.utils.CommandArgs":{joined:[6,2,1,""],match:[6,2,1,""],optional:[6,2,1,""]},"royalnet.utils.NetworkHandler":{message_type:[6,4,1,""]},royalnet:{audio:[0,0,0,"-"],bots:[1,0,0,"-"],commands:[2,0,0,"-"],database:[3,0,0,"-"],network:[5,0,0,"-"],utils:[6,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","staticmethod","Python static method"],"4":["py","attribute","Python attribute"],"5":["py","function","Python function"],"6":["py","exception","Python exception"],"7":["py","classmethod","Python class method"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:staticmethod","4":"py:attribute","5":"py:function","6":"py:exception","7":"py:classmethod"},terms:{"0x7a70198":3,"0x7a701e0":3,"0x7a70300":3,"0x7a70348":3,"0x7a70978":3,"0x7a709c0":3,"0x7a70a08":3,"0x7a70b70":3,"20m":0,"48khz":0,"abstract":6,"boolean":3,"byte":[0,5],"class":[0,1,2,3,5,6],"default":[0,3,6],"float":0,"function":[0,6],"int":[0,5,6],"new":[0,3,6],"null":[1,5],"return":[0,1,5,6],"static":0,"true":[0,3,6],"try":[1,6],"while":[0,1,3],Not:0,That:6,The:[0,1,3,5,6],Then:1,Use:3,__init__:[0,3,5],_bot_factori:1,_call_factori:1,_create_t:3,_generate_gener:0,_handle_upd:1,_init_cli:1,_init_command:1,_init_databas:1,_init_royalnet:1,_init_voic:1,_network_handl:1,_stop_download:0,_windowsselectoreventloop:5,about:0,abstracteventloop:5,activekvgroup:3,add:[0,1],add_to_music_data:1,address:5,advanc:0,advance_music_data:1,akin:5,alchemi:[1,3,6],alia:3,all:0,allow:3,alreadi:0,also:[0,5],altern:5,alwai:[1,5],amount:0,ani:[0,6],anoth:5,answer:6,anystr:6,arg:[5,6],argument:[0,6],around:[0,3],async:[0,3],asyncifi:6,asyncio:[1,5],asyncron:3,attribut:6,audio:[1,4],audio_filenam:0,audio_sourc:1,audiosourc:0,author:6,authorcommand:2,avatar:3,avatar_hash:3,base:[0,1],been:0,bestaudio:0,biginteg:3,bit:0,block:1,bool:6,bot:[3,4],botfather_command_str:1,both:3,call:[1,6],callabl:6,can:5,caus:5,cdj:6,chain:1,chang:[0,1],change_pres:1,channel:[1,6],chat:1,check:[0,3],ciaoruozicommand:2,class_:6,classmethod:6,clean:6,client:1,close:5,colorcommand:2,column:3,columndefault:3,command:[1,4,6],command_arg:6,command_descript:6,command_nam:[1,6],command_prefix:1,command_syntax:6,commandarg:6,common:6,commun:5,compat:0,complet:0,compon:3,configur:[1,3],connect:[1,5],connectedcli:5,contain:[0,5],context:3,convers:5,convert:0,core:3,coroutin:1,correspond:[0,1],creat:[0,1,3,5,6],create_from_url:0,create_from_ytsearch:0,creator:3,creator_id:3,ct_co:3,current:1,custom:[0,1],data:[0,5,6],databas:[1,4,6],database_config:1,database_uri:3,databaseconfig:[1,3],dateparsercommand:2,datetim:[3,6],debug:5,declar:3,delet:0,delete_audio_fil:0,delete_video_fil:0,describ:3,destin:[5,6],destination_conv_id:5,detail:3,diario:3,diario_id:3,diariocommand:2,dict:[0,6],dictionari:1,discord:[0,1,3],discord_config:1,discord_id:3,discordbot:1,discordcli:1,discordconfig:1,discrimin:3,doc:3,doe:[0,5,6],doesn:1,download:0,dure:1,each:0,either:0,empti:[0,1],encod:0,end:3,ending_class:3,engin:3,error:5,error_command:1,error_if_non:6,error_msg:5,event:5,everi:[0,5],exc:5,except:[1,5],execut:[1,5],exist:[1,6],ext:0,extra:0,extract:0,extract_info:0,factori:0,fals:[0,3,5,6],file:[0,1],find:[1,3,5,6],find_client:5,find_destin:5,first:0,first_nam:3,follow:3,foreignkei:3,form:5,format:0,found:[5,6],frame:0,from:[0,1,3,6],full_usernam:3,gener:[0,1,6],genericbot:[1,3],get:[0,3],get_author:6,going:0,group:3,group_nam:3,guild:1,handl:1,has:0,have:1,html:3,http:3,identifi:[5,6],identity_column_nam:3,identity_t:[1,3],ignore_escap:6,implement:0,incom:1,incorrect:5,index:[4,6],inf:0,infinit:0,info:0,inherit:[0,1],initi:[0,1],insid:0,instanc:1,instead:0,integ:3,interface_nam:[1,6],interface_obj:6,interface_prefix:6,invalid:5,invaliddestinationem:5,invalidinputerror:6,invalidpackageem:5,invalidsecretem:5,is_opu:0,item:0,join:6,just:1,keep:0,kei:3,keygroup:3,keyvalu:3,kvactivecommand:2,kvcommand:2,kvrollcommand:2,kwarg:[1,6],largebinari:3,last_nam:3,least:0,left:0,like:0,link:[1,5],link_typ:5,list:[0,1,5,6],listen:[1,5],logger:0,login:1,loop:5,made:6,mai:0,maintain:3,make:1,manag:3,master_secret:5,master_t:[1,3],master_uri:5,match:[1,6],math:0,mean:6,media_url:3,memori:0,mention:3,messag:[1,5,6],message_typ:6,method:0,missing_command:1,modul:4,more:[1,3],multipl:[1,3],music_data:1,must:[0,5,6],name:[0,1],need:1,net_request:6,network:[1,4,6],network_handl:[1,6],network_handler_dict:6,networkerror:5,networkhandl:6,next:[0,1],nid:5,no_warn:0,nobodi:5,node:5,none:[0,1,3,5,6],noplaylist:0,notconnectederror:5,noth:5,notidentifiederror:5,notimpl:[1,6],now_plai:0,nullabl:3,nullcommand:[1,2],number:[0,5],object:[0,1,3],offset:1,onc:[0,3],option:[0,1,3,6],opu:0,order:0,org:3,other:1,otherwis:[0,1,5],outtmpl:0,packag:5,packet:5,page:4,paramet:[0,1,3,5],pass:0,password:3,path:3,pattern:6,pcm:0,per:0,perman:0,pickl:5,pickleabl:6,pingcommand:2,plai:[0,1],playcommand:2,playlist:0,playmod:0,playmodecommand:2,plusformat:6,pool:0,port:5,presenc:1,primary_kei:3,probabl:[0,6],properti:0,quiet:0,quot:3,quoted_account:3,quoted_account_id:3,ragecommand:2,rais:[1,5,6],raise_on_error:5,random:0,read:0,reason:5,receiv:[1,5,6],recommend:0,relationshiplinkchain:3,relationshipproperti:3,remindercommand:2,remov:0,repeat:0,repli:[5,6],repres:[0,1],request:[1,5,6],request_handl:5,request_uri:5,requesterror:5,requestsuccess:5,requir:1,require_alchemy_t:6,require_at_least:6,required_secret:5,rest:6,role:3,rout:5,route_packag:5,row:6,royal:3,royal_id:3,royalnet_config:1,royalnetconfig:[1,5],royalneterror:5,royalnetlink:[1,5],royalnetserv:5,royalpcmaudio:[0,1],royalpcmfil:0,rpf:0,run:[1,5,6],safefilenam:6,safeformat:6,search:[0,4],secret:5,select:[0,3],self:1,send:[5,6],sent:[5,6],sequenc:[5,6],serv:5,server:5,servererrormessag:5,session_acm:3,session_cm:3,session_end:6,session_init:6,set:[1,3,6],shipcommand:2,should:[1,5,6],signal:0,singl:[1,3],skipcommand:2,sleep_until:6,smecdscommand:2,someth:5,somewher:5,song:[0,1],soon:0,sourc:[0,5,6],source_conv_id:5,specif:[1,6],specifi:1,spoiler:3,sqlalchemi:3,start:[1,3,5],starting_class:3,starting_list:0,starting_pool:0,statement:3,statu:1,stereo:0,still:6,str:[0,1,3,5,6],string:[0,3,6],subbot:6,subclass:0,submodul:3,success:5,summoncommand:2,synccommand:2,tabl:1,task:1,telegram:[1,3],telegram_config:1,telegrambot:1,telegramcal:1,telegramconfig:1,termin:5,text:[3,6],tg_id:3,them:3,thi:[0,5,6],those:0,through:5,time:5,timestamp:3,titl:0,token:1,tupl:3,type:[0,1,3,5,6],uid:3,union:0,univers:6,unregisterederror:6,until:0,updat:1,update_activity_with_source_titl:1,uri:3,url:0,use:[0,3],used:[1,3],useful:0,user:6,usernam:3,using:1,usual:[0,5],util:[1,4],valu:[0,3,5],variabl:1,veri:0,video:0,videoinfocommand:2,videos_left:0,voic:1,wai:0,wait:6,want:0,warn:0,wasn:5,websocket:5,websocketserverprotocol:5,went:5,when:6,which:[0,5],word:6,worth:0,wrapper:[0,3],wrong:5,yield:0,you:0,youtub:0,youtube_dl:0,youtubedl:0,ytdl_arg:0,ytdl_filenam:0,ytdlfile:0,ytdlinfo:0},titles:["royalnet.audio","royalnet.bots","royalnet.commands","royalnet.database","royalnet","royalnet.network","royalnet.utils"],titleterms:{audio:0,bot:1,command:2,databas:3,indic:4,network:5,royalnet:[0,1,2,3,4,5,6],tabl:[3,4],util:6}}) \ No newline at end of file diff --git a/docs/html/utils.html b/docs/html/utils.html index a6eec118..383725fe 100644 --- a/docs/html/utils.html +++ b/docs/html/utils.html @@ -165,12 +165,6 @@
    class royalnet.utils.Call(channel, command: Type[royalnet.utils.command.Command], command_args: List[str] = None, **kwargs)

    A command call. Still an abstract class, subbots should create a new call from this.

    -
    -
    -__init__(channel, command: Type[royalnet.utils.command.Command], command_args: List[str] = None, **kwargs)
    -

    Initialize self. See help(type(self)) for accurate signature.

    -
    -
    alchemy = NotImplemented
    diff --git a/docs_source/conf.py b/docs_source/conf.py index ce54d06b..25b7baa8 100644 --- a/docs_source/conf.py +++ b/docs_source/conf.py @@ -30,12 +30,13 @@ author = 'Stefano Pigozzi' extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon", "sphinx.ext.intersphinx"] intersphinx_mapping = {'python': ('https://docs.python.org/3.7', None), - 'discord': ('https://discordpy.readthedocs.io/en/latest/', None)} + 'discord': ('https://discordpy.readthedocs.io/en/latest/', None), + "telegram": ("https://python-telegram-bot.readthedocs.io/en/stable/", None)} def skip(app, what, name, obj, would_skip, options): if name == "__init__": - return False + return not bool(obj.__doc__) return would_skip diff --git a/royalnet/__init__.py b/royalnet/__init__.py index e69de29b..77d348d3 100644 --- a/royalnet/__init__.py +++ b/royalnet/__init__.py @@ -0,0 +1,3 @@ +from . import audio, bots, commands, database, network, utils + +__all__ = ["audio", "bots", "commands", "database", "network", "utils"] diff --git a/royalnet/bots/discord.py b/royalnet/bots/discord.py index 6fe796b1..ad072485 100644 --- a/royalnet/bots/discord.py +++ b/royalnet/bots/discord.py @@ -6,7 +6,7 @@ from .generic import GenericBot from ..commands import NullCommand from ..utils import asyncify, Call, Command from ..error import UnregisteredError, NoneFoundError, TooManyFoundError, InvalidConfigError -from ..network import Message, RoyalnetConfig +from ..network import Message, Reply, RoyalnetConfig from ..database import DatabaseConfig from ..audio import PlayMode, Playlist, RoyalPCMAudio @@ -19,7 +19,7 @@ if not discord.opus.is_loaded(): class DiscordConfig: - """The specific configuration to be used for :ref:`royalnet.database.DiscordBot`.""" + """The specific configuration to be used for :py:class:`royalnet.bots.DiscordBot`.""" def __init__(self, token: str): self.token = token @@ -30,6 +30,7 @@ class DiscordBot(GenericBot): interface_name = "discord" def _init_voice(self): + """Initialize the variables needed for the connection to voice chat.""" log.debug(f"Creating music_data dict") self.music_data: typing.Dict[discord.Guild, PlayMode] = {} @@ -64,7 +65,7 @@ class DiscordBot(GenericBot): async def net_request(call, message: Message, destination: str): if self.network is None: raise InvalidConfigError("Royalnet is not enabled on this bot") - response: Message = await self.network.request(message, destination) + response: Reply = await self.network.request(message, destination) response.raise_on_error() return response @@ -83,7 +84,7 @@ class DiscordBot(GenericBot): return DiscordCall def _bot_factory(self) -> typing.Type[discord.Client]: - """Create a new DiscordClient class based on this DiscordBot.""" + """Create a custom DiscordClient class inheriting from :py:class:`discord.Client`.""" log.debug(f"Creating DiscordClient") # noinspection PyMethodParameters @@ -129,8 +130,11 @@ class DiscordBot(GenericBot): await cli.change_presence(status=discord.Status.online) def find_guild_by_name(cli, name: str) -> discord.Guild: - """Find the Guild with the specified name. Case-insensitive. - Will raise a NoneFoundError if no channels are found, or a TooManyFoundError if more than one is found.""" + """Find the :py:class:`discord.Guild` with the specified name. Case-insensitive. + + Raises: + :py:exc:`NoneFoundError` if no channels are found. + :py:exc:`TooManyFoundError` if more than one is found.""" all_guilds: typing.List[discord.Guild] = cli.guilds matching_channels: typing.List[discord.Guild] = [] for guild in all_guilds: @@ -145,9 +149,9 @@ class DiscordBot(GenericBot): def find_channel_by_name(cli, name: str, guild: typing.Optional[discord.Guild] = None) -> discord.abc.GuildChannel: - """Find the TextChannel, VoiceChannel or CategoryChannel with the specified name. Case-insensitive. - Guild is optional, but the method will raise a TooManyFoundError if none is specified and there is more than one channel with the same name. - Will also raise a NoneFoundError if no channels are found.""" + """Find the :py:class:`TextChannel`, :py:class:`VoiceChannel` or :py:class:`CategoryChannel` with the specified name. Case-insensitive. + Guild is optional, but the method will raise a :py:exc:`TooManyFoundError` if none is specified and there is more than one channel with the same name. + Will also raise a :py:exc:`NoneFoundError` if no channels are found.""" if guild is not None: all_channels = guild.channels else: @@ -167,10 +171,11 @@ class DiscordBot(GenericBot): return matching_channels[0] def find_voice_client_by_guild(cli, guild: discord.Guild): - """Find the VoiceClient belonging to a specific Guild. - Raises a NoneFoundError if the Guild currently has no VoiceClient.""" + """Find the :py:class:`discord.VoiceClient` belonging to a specific :py:class:`discord.Guild`. + + Raises: + :py:exc:`NoneFoundError` if the :py:class:`discord.Guild` currently has no :py:class:`discord.VoiceClient`.""" for voice_client in cli.voice_clients: - voice_client: discord.VoiceClient if voice_client.guild == guild: return voice_client raise NoneFoundError("No voice clients found") @@ -178,7 +183,7 @@ class DiscordBot(GenericBot): return DiscordClient def _init_client(self): - """Create a bot instance.""" + """Create an instance of the DiscordClient class created in :py:func:`royalnet.bots.DiscordBot._bot_factory`.""" log.debug(f"Creating DiscordClient instance") self._Client = self._bot_factory() self.client = self._Client() @@ -202,13 +207,14 @@ class DiscordBot(GenericBot): self._init_voice() async def run(self): + """Login to Discord, then run the bot.""" log.debug(f"Logging in to Discord") await self.client.login(self._discord_config.token) log.debug(f"Connecting to Discord") await self.client.connect() # TODO: how to stop? - async def add_to_music_data(self, audio_sources: typing.List[discord.AudioSource], guild: discord.Guild): + async def add_to_music_data(self, audio_sources: typing.List[RoyalPCMAudio], guild: discord.Guild): """Add a file to the corresponding music_data object.""" guild_music_data = self.music_data[guild] for audio_source in audio_sources: @@ -222,7 +228,7 @@ class DiscordBot(GenericBot): guild_music_data = self.music_data[guild] voice_client = self.client.find_voice_client_by_guild(guild) next_source: RoyalPCMAudio = await guild_music_data.next() - await self.update_activity_with_source_title(next_source) + await self.update_activity_with_source_title() if next_source is None: log.debug(f"Ending playback chain") return @@ -235,18 +241,25 @@ class DiscordBot(GenericBot): log.debug(f"Starting playback of {next_source}") voice_client.play(next_source, after=advance) - async def update_activity_with_source_title(self, rpa: typing.Optional[RoyalPCMAudio] = None): - if len(self.music_data) > 1: + async def update_activity_with_source_title(self): + """Change the bot's presence (using :py:func:`discord.Client.change_presence`) to match the current listening status. + + If multiple guilds are using the bot, the bot will always have an empty presence.""" + if len(self.music_data) != 1: # Multiple guilds are using the bot, do not display anything log.debug(f"Updating current Activity: setting to None, as multiple guilds are using the bot") await self.client.change_presence(status=discord.Status.online) return - if rpa is None: + # FIXME: PyCharm faulty inspection? + # noinspection PyUnresolvedReferences + play_mode: PlayMode = list(self.music_data.items())[0][1] + now_playing = play_mode.now_playing + if now_playing is None: # No songs are playing now log.debug(f"Updating current Activity: setting to None, as nothing is currently being played") await self.client.change_presence(status=discord.Status.online) return - log.debug(f"Updating current Activity: listening to {rpa.rpf.info.title}") - await self.client.change_presence(activity=discord.Activity(name=rpa.rpf.info.title, + log.debug(f"Updating current Activity: listening to {now_playing.rpf.info.title}") + await self.client.change_presence(activity=discord.Activity(name=now_playing.rpf.info.title, type=discord.ActivityType.listening), status=discord.Status.online) diff --git a/royalnet/bots/generic.py b/royalnet/bots/generic.py index 305ec234..52574c55 100644 --- a/royalnet/bots/generic.py +++ b/royalnet/bots/generic.py @@ -19,8 +19,8 @@ class GenericBot: command_prefix: str, commands: typing.List[typing.Type[Command]], missing_command: typing.Type[Command], - error_command: typing.Type[Command]): - """Generate the commands dictionary required to handle incoming messages, and the network_handlers dictionary required to handle incoming requests.""" + error_command: typing.Type[Command]) -> None: + """Generate the ``commands`` dictionary required to handle incoming messages, and the ``network_handlers`` dictionary required to handle incoming requests.""" log.debug(f"Now generating commands") self.commands: typing.Dict[str, typing.Type[Command]] = {} self.network_handlers: typing.Dict[typing.Type[Message], typing.Type[NetworkHandler]] = {} @@ -33,18 +33,24 @@ class GenericBot: log.debug(f"Successfully generated commands") def _call_factory(self) -> typing.Type[Call]: - """Create the Call class, representing a Call command. It should inherit from the utils.Call class.""" + """Create the TelegramCall class, representing a command call. It should inherit from :py:class:`royalnet.utils.Call`. + + Returns: + The created TelegramCall class.""" raise NotImplementedError() def _init_royalnet(self, royalnet_config: RoyalnetConfig): - """Create a RoyalnetLink, and run it as a task.""" + """Create a :py:class:`royalnet.network.RoyalnetLink`, and run it as a :py:class:`asyncio.Task`.""" self.network: RoyalnetLink = RoyalnetLink(royalnet_config.master_uri, royalnet_config.master_secret, self.interface_name, self._network_handler) log.debug(f"Running RoyalnetLink {self.network}") loop.create_task(self.network.run()) async def _network_handler(self, message: Message) -> Message: - """Handle a single Message received from the RoyalnetLink""" + """Handle a single :py:class:`royalnet.network.Message` received from the :py:class:`royalnet.network.RoyalnetLink`. + + Returns: + Another message, to be sent as :py:class:`royalnet.network.Reply`.""" log.debug(f"Received {message} from the RoyalnetLink") try: network_handler = self.network_handlers[message.__class__] @@ -61,7 +67,7 @@ class GenericBot: return RequestError(exc=exc) def _init_database(self, commands: typing.List[typing.Type[Command]], database_config: DatabaseConfig): - """Connect to the database, and create the missing tables required by the selected commands.""" + """Create an :py:class:`royalnet.database.Alchemy` with the tables required by the commands. Then, find the chain that links the ``master_table`` to the ``identity_table``.""" log.debug(f"Initializing database") required_tables = set() for command in commands: @@ -99,7 +105,11 @@ class GenericBot: self._init_royalnet(royalnet_config=royalnet_config) async def call(self, command_name: str, channel, parameters: typing.List[str] = None, **kwargs): - """Call a command by its string, or missing_command if it doesn't exists, or error_command if an exception is raised during the execution.""" + """Call the command with the specified name. + + If it doesn't exist, call ``self.missing_command``. + + If an exception is raised during the execution of the command, call ``self.error_command``.""" log.debug(f"Trying to call {command_name}") if parameters is None: parameters = [] diff --git a/royalnet/bots/telegram.py b/royalnet/bots/telegram.py index c30a75be..6ee40566 100644 --- a/royalnet/bots/telegram.py +++ b/royalnet/bots/telegram.py @@ -14,7 +14,7 @@ log = _logging.getLogger(__name__) class TelegramConfig: - """The specific configuration to be used for :ref:`royalnet.database.TelegramBot`.""" + """The specific configuration to be used for :py:class:`royalnet.database.TelegramBot`.""" def __init__(self, token: str): self.token: str = token @@ -24,6 +24,7 @@ class TelegramBot(GenericBot): interface_name = "telegram" def _init_client(self): + """Create the :py:class:`telegram.Bot`, and set the starting offset.""" self.client = telegram.Bot(self._telegram_config.token) self._offset: int = -100 diff --git a/royalnet/network/__init__.py b/royalnet/network/__init__.py index 93081500..bf588ced 100644 --- a/royalnet/network/__init__.py +++ b/royalnet/network/__init__.py @@ -1,4 +1,4 @@ -from .messages import Message, ServerErrorMessage, InvalidSecretEM, InvalidDestinationEM, InvalidPackageEM, RequestSuccessful, RequestError +from .messages import Message, ServerErrorMessage, InvalidSecretEM, InvalidDestinationEM, InvalidPackageEM, RequestSuccessful, RequestError, Reply from .packages import Package from .royalnetlink import RoyalnetLink, NetworkError, NotConnectedError, NotIdentifiedError from .royalnetserver import RoyalnetServer @@ -17,4 +17,5 @@ __all__ = ["Message", "RoyalnetServer", "RequestSuccessful", "RequestError", - "RoyalnetConfig"] + "RoyalnetConfig", + "Reply"] diff --git a/royalnet/network/royalnetlink.py b/royalnet/network/royalnetlink.py index ff4783a0..2b6c2479 100644 --- a/royalnet/network/royalnetlink.py +++ b/royalnet/network/royalnetlink.py @@ -13,7 +13,7 @@ log = _logging.getLogger(__name__) class NotConnectedError(Exception): - pass + """The :py:class:`royalnet.network.RoyalnetLink` is not connected to a :py:class:`royalnet.network.RoyalnetServer`.""" class NotIdentifiedError(Exception): @@ -67,7 +67,7 @@ class RoyalnetLink: self.secret: str = secret self.websocket: typing.Optional[websockets.WebSocketClientProtocol] = None self.request_handler = request_handler - self._pending_requests: typing.Dict[typing.Optional[Message]] = {} + self._pending_requests: typing.Dict[str, typing.Optional[Message]] = {} self._loop: asyncio.AbstractEventLoop = loop self._connect_event: asyncio.Event = asyncio.Event(loop=self._loop) self.identify_event: asyncio.Event = asyncio.Event(loop=self._loop)