mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
cose
This commit is contained in:
parent
3f1c8a57d3
commit
3f68729bc3
13 changed files with 22 additions and 605 deletions
|
@ -53,12 +53,12 @@ class LinkerCommand(rc.Command, metaclass=abc.ABCMeta):
|
|||
@abc.abstractmethod
|
||||
async def get_updatables_of_user(self, session, user: rbt.User) -> List[Updatable]:
|
||||
"""Get the updatables of a specific user."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def get_updatables(self, session) -> List[Updatable]:
|
||||
"""Return a list of all objects that should be updated at this updater cycle."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def create(self,
|
||||
|
@ -69,37 +69,37 @@ class LinkerCommand(rc.Command, metaclass=abc.ABCMeta):
|
|||
"""Create a new updatable object for a user.
|
||||
|
||||
This function is responsible for adding the object to the session."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def update(self, session, obj, change: Callable[[str, Any], Awaitable[None]]):
|
||||
"""Update a single updatable object. Use the change method to change values on the object!"""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def on_increase(self, session, obj: Updatable, attribute: str, old: Any, new: Any) -> None:
|
||||
"""Called when the attribute has increased from the old value."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def on_unchanged(self, session, obj: Updatable, attribute: str, old: Any, new: Any) -> None:
|
||||
"""Called when the attribute stayed the same as the old value."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def on_decrease(self, session, obj: Updatable, attribute: str, old: Any, new: Any) -> None:
|
||||
"""Called when the attribute has decreased from the old value."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def on_first(self, session, obj: Updatable, attribute: str, old: None, new: Any) -> None:
|
||||
"""Called when the attribute changed from None."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
@abc.abstractmethod
|
||||
async def on_reset(self, session, obj: Updatable, attribute: str, old: Any, new: None) -> None:
|
||||
"""Called when the attribute changed to None."""
|
||||
...
|
||||
raise NotImplementedError()
|
||||
|
||||
async def _change(self,
|
||||
session,
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
import discord
|
||||
from typing import *
|
||||
from royalnet.serf.discord.discordserf import DiscordSerf
|
||||
from royalnet.commands import *
|
||||
import royalnet.commands as rc
|
||||
|
||||
|
||||
class DiscordCvEvent(Event):
|
||||
class DiscordCvEvent(rc.HeraldEvent):
|
||||
name = "discord_cv"
|
||||
|
||||
async def run(self, guild_id: Optional[int] = None, **kwargs) -> dict:
|
||||
if not self.interface.name == "discord":
|
||||
raise UnsupportedError()
|
||||
if not isinstance(self.parent, DiscordSerf):
|
||||
raise rc.UnsupportedError()
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
serf: DiscordSerf = self.interface.serf
|
||||
serf: DiscordSerf = self.parent
|
||||
|
||||
client: discord.Client = serf.client
|
||||
|
||||
if guild_id is None:
|
||||
guilds: List[discord.Guild] = client.guilds
|
||||
if len(guilds) == 0:
|
||||
raise ConfigurationError("Il bot non è in nessun Server.")
|
||||
raise rc.ConfigurationError("Il bot non è in nessun Server.")
|
||||
elif len(guilds) > 1:
|
||||
raise UserError("Non hai specificato di quale Server vuoi vedere le informazioni!")
|
||||
raise rc.UserError("Non hai specificato di quale Server vuoi vedere le informazioni!")
|
||||
else:
|
||||
guild = guilds[0]
|
||||
else:
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
import datetime
|
||||
from typing import *
|
||||
|
||||
import discord
|
||||
import royalnet.commands as rc
|
||||
import royalnet.serf.discord as rsd
|
||||
import royalnet.bard.discord as rbd
|
||||
|
||||
from ..utils import RoyalQueue, RoyalPool
|
||||
|
||||
|
||||
class DiscordLazyPlayEvent(rc.Event):
|
||||
name = "discord_lazy_play"
|
||||
|
||||
async def run(self,
|
||||
urls: List[str],
|
||||
guild_id: Optional[int] = None,
|
||||
user: Optional[str] = None,
|
||||
force_color: Optional[int] = None,
|
||||
**kwargs) -> dict:
|
||||
if not isinstance(self.serf, rsd.DiscordSerf):
|
||||
raise rc.UnsupportedError()
|
||||
|
||||
serf: rsd.DiscordSerf = self.serf
|
||||
client: discord.Client = self.serf.client
|
||||
guild: discord.Guild = client.get_guild(guild_id) if guild_id is not None else None
|
||||
candidate_players: List[rsd.VoicePlayer] = serf.find_voice_players(guild)
|
||||
|
||||
if len(candidate_players) == 0:
|
||||
raise rc.UserError("Il bot non è in nessun canale vocale.\n"
|
||||
"Evocalo prima con [c]summon[/c]!")
|
||||
elif len(candidate_players) == 1:
|
||||
voice_player = candidate_players[0]
|
||||
else:
|
||||
raise rc.CommandError("Non so in che Server riprodurre questo file...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
|
||||
added: List[rbd.YtdlDiscord] = []
|
||||
too_long: List[rbd.YtdlDiscord] = []
|
||||
|
||||
for url in urls:
|
||||
ytds = await rbd.YtdlDiscord.from_url(url)
|
||||
if isinstance(voice_player.playing, RoyalQueue):
|
||||
for index, ytd in enumerate(ytds):
|
||||
if ytd.info.duration >= datetime.timedelta(seconds=self.config["Play"]["max_song_duration"]):
|
||||
too_long.append(ytd)
|
||||
continue
|
||||
added.append(ytd)
|
||||
voice_player.playing.contents.append(ytd)
|
||||
if not voice_player.voice_client.is_playing():
|
||||
await voice_player.start()
|
||||
elif isinstance(voice_player.playing, RoyalPool):
|
||||
for index, ytd in enumerate(ytds):
|
||||
if ytd.info.duration >= datetime.timedelta(seconds=self.config["Play"]["max_song_duration"]):
|
||||
too_long.append(ytd)
|
||||
continue
|
||||
added.append(ytd)
|
||||
voice_player.playing.full_pool.append(ytd)
|
||||
voice_player.playing.remaining_pool.append(ytd)
|
||||
if not voice_player.voice_client.is_playing():
|
||||
await voice_player.start()
|
||||
else:
|
||||
raise rc.CommandError(f"Non so come aggiungere musica a [c]{voice_player.playing.__class__.__qualname__}[/c]!")
|
||||
|
||||
main_channel: discord.TextChannel = client.get_channel(self.config["Discord"]["main_channel_id"])
|
||||
|
||||
if len(added) > 0:
|
||||
if user:
|
||||
await main_channel.send(rsd.escape(f"▶️ {user} ha aggiunto {len(added)} file _(lazy)_ alla coda:"))
|
||||
else:
|
||||
await main_channel.send(rsd.escape(f"▶️ Aggiunt{'o' if len(added) == 1 else 'i'} {len(added)} file "
|
||||
f"[i](lazy)[/i] alla coda:"))
|
||||
for ytd in added[:5]:
|
||||
embed: discord.Embed = ytd.embed()
|
||||
if force_color:
|
||||
embed._colour = discord.Colour(force_color)
|
||||
await main_channel.send(embed=embed)
|
||||
if len(added) > 5:
|
||||
await main_channel.send(f"e altri {len(added) - 5}!")
|
||||
|
||||
if len(too_long) > 0:
|
||||
if user:
|
||||
await main_channel.send(rsd.escape(
|
||||
f"⚠ {len(too_long)} file non {'è' if len(too_long) == 1 else 'sono'}"
|
||||
f" stat{'o' if len(too_long) == 1 else 'i'} scaricat{'o' if len(too_long) == 1 else 'i'}"
|
||||
f" perchè durava{'' if len(too_long) == 1 else 'no'}"
|
||||
f" più di [c]{self.config['Play']['max_song_duration']}[/c] secondi."
|
||||
))
|
||||
|
||||
if len(added) + len(too_long) == 0:
|
||||
raise rc.InvalidInputError("Non è stato aggiunto nessun file alla coda.")
|
||||
|
||||
return {
|
||||
"added": [{
|
||||
"title": ytd.info.title,
|
||||
} for ytd in added],
|
||||
"too_long": [{
|
||||
"title": ytd.info.title,
|
||||
} for ytd in too_long]
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
import discord
|
||||
from typing import *
|
||||
import royalnet.commands as rc
|
||||
from royalnet.serf.discord import *
|
||||
|
||||
|
||||
class DiscordPauseEvent(rc.Event):
|
||||
name = "discord_pause"
|
||||
|
||||
async def run(self,
|
||||
guild_id: Optional[int] = None,
|
||||
**kwargs) -> dict:
|
||||
if not isinstance(self.serf, DiscordSerf):
|
||||
raise rc.UnsupportedError()
|
||||
client: discord.Client = self.serf.client
|
||||
if len(self.serf.voice_players) == 1:
|
||||
voice_player: VoicePlayer = self.serf.voice_players[0]
|
||||
else:
|
||||
if guild_id is None:
|
||||
# TODO: trovare un modo per riprodurre canzoni su più server da Telegram
|
||||
raise rc.InvalidInputError("Non so in che Server riprodurre questo file...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
guild: discord.Guild = client.get_guild(guild_id)
|
||||
if guild is None:
|
||||
raise rc.InvalidInputError("Impossibile trovare il Server specificato.")
|
||||
candidate_players = self.serf.find_voice_players(guild)
|
||||
if len(candidate_players) == 0:
|
||||
raise rc.UserError("Il bot non è in nessun canale vocale.\n"
|
||||
"Evocalo prima con [c]summon[/c]!")
|
||||
elif len(candidate_players) == 1:
|
||||
voice_player = candidate_players[0]
|
||||
else:
|
||||
raise rc.CommandError("Non so su che Server saltare canzone...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
|
||||
if voice_player.voice_client.is_paused():
|
||||
voice_player.voice_client.resume()
|
||||
return {"action": "resumed"}
|
||||
else:
|
||||
voice_player.voice_client.pause()
|
||||
return {"action": "paused"}
|
|
@ -1,102 +0,0 @@
|
|||
import datetime
|
||||
from typing import *
|
||||
|
||||
import discord
|
||||
import royalnet.commands as rc
|
||||
import royalnet.serf.discord as rsd
|
||||
import royalnet.bard.discord as rbd
|
||||
|
||||
from ..utils import RoyalQueue, RoyalPool
|
||||
|
||||
|
||||
class DiscordPlayEvent(rc.Event):
|
||||
name = "discord_play"
|
||||
|
||||
async def run(self,
|
||||
urls: List[str],
|
||||
guild_id: Optional[int] = None,
|
||||
user: Optional[str] = None,
|
||||
force_color: Optional[int] = None,
|
||||
**kwargs) -> dict:
|
||||
if not isinstance(self.serf, rsd.DiscordSerf):
|
||||
raise rc.UnsupportedError()
|
||||
|
||||
serf: rsd.DiscordSerf = self.serf
|
||||
client: discord.Client = self.serf.client
|
||||
guild: discord.Guild = client.get_guild(guild_id) if guild_id is not None else None
|
||||
candidate_players: List[rsd.VoicePlayer] = serf.find_voice_players(guild)
|
||||
|
||||
if len(candidate_players) == 0:
|
||||
raise rc.UserError("Il bot non è in nessun canale vocale.\n"
|
||||
"Evocalo prima con [c]summon[/c]!")
|
||||
elif len(candidate_players) == 1:
|
||||
voice_player = candidate_players[0]
|
||||
else:
|
||||
raise rc.CommandError("Non so in che Server riprodurre questo file...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
|
||||
added: List[rbd.YtdlDiscord] = []
|
||||
too_long: List[rbd.YtdlDiscord] = []
|
||||
|
||||
for url in urls:
|
||||
ytds = await rbd.YtdlDiscord.from_url(url)
|
||||
if isinstance(voice_player.playing, RoyalQueue):
|
||||
for index, ytd in enumerate(ytds):
|
||||
if ytd.info.duration >= datetime.timedelta(seconds=self.config["Play"]["max_song_duration"]):
|
||||
too_long.append(ytd)
|
||||
continue
|
||||
await ytd.convert_to_pcm()
|
||||
added.append(ytd)
|
||||
voice_player.playing.contents.append(ytd)
|
||||
if not voice_player.voice_client.is_playing():
|
||||
await voice_player.start()
|
||||
elif isinstance(voice_player.playing, RoyalPool):
|
||||
for index, ytd in enumerate(ytds):
|
||||
if ytd.info.duration >= datetime.timedelta(seconds=self.config["Play"]["max_song_duration"]):
|
||||
too_long.append(ytd)
|
||||
continue
|
||||
await ytd.convert_to_pcm()
|
||||
added.append(ytd)
|
||||
voice_player.playing.full_pool.append(ytd)
|
||||
voice_player.playing.remaining_pool.append(ytd)
|
||||
if not voice_player.voice_client.is_playing():
|
||||
await voice_player.start()
|
||||
else:
|
||||
raise rc.CommandError(f"Non so come aggiungere musica a [c]{voice_player.playing.__class__.__qualname__}[/c]!")
|
||||
|
||||
main_channel: discord.TextChannel = client.get_channel(self.config["Discord"]["main_channel_id"])
|
||||
|
||||
if len(added) > 0:
|
||||
if user:
|
||||
await main_channel.send(rsd.escape(f"▶️ {user} ha aggiunto {len(added)} file alla coda:"))
|
||||
else:
|
||||
await main_channel.send(rsd.escape(f"▶️ Aggiunt{'o' if len(added) == 1 else 'i'} {len(added)} file alla"
|
||||
f" coda:"))
|
||||
for ytd in added[:5]:
|
||||
embed: discord.Embed = ytd.embed()
|
||||
if force_color:
|
||||
embed._colour = discord.Colour(force_color)
|
||||
await main_channel.send(embed=embed)
|
||||
if len(added) > 5:
|
||||
await main_channel.send(f"e altri {len(added) - 5}!")
|
||||
|
||||
if len(too_long) > 0:
|
||||
if user:
|
||||
await main_channel.send(rsd.escape(
|
||||
f"⚠ {len(too_long)} file non {'è' if len(too_long) == 1 else 'sono'}"
|
||||
f" stat{'o' if len(too_long) == 1 else 'i'} scaricat{'o' if len(too_long) == 1 else 'i'}"
|
||||
f" perchè durava{'' if len(too_long) == 1 else 'no'}"
|
||||
f" più di [c]{self.config['Play']['max_song_duration']}[/c] secondi."
|
||||
))
|
||||
|
||||
if len(added) + len(too_long) == 0:
|
||||
raise rc.InvalidInputError("Non è stato aggiunto nessun file alla coda.")
|
||||
|
||||
return {
|
||||
"added": [{
|
||||
"title": ytd.info.title,
|
||||
} for ytd in added],
|
||||
"too_long": [{
|
||||
"title": ytd.info.title,
|
||||
} for ytd in too_long]
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
import datetime
|
||||
from typing import *
|
||||
|
||||
import discord
|
||||
import royalnet.commands as rc
|
||||
import royalnet.serf.discord as rsd
|
||||
import royalnet.bard.discord as rbd
|
||||
|
||||
from ..utils import RoyalQueue, RoyalPool
|
||||
|
||||
|
||||
class DiscordPlaymodeEvent(rc.Event):
|
||||
name = "discord_playmode"
|
||||
|
||||
async def run(self,
|
||||
playable_string: str,
|
||||
guild_id: Optional[int] = None,
|
||||
user: Optional[str] = None,
|
||||
**kwargs) -> dict:
|
||||
if not isinstance(self.serf, rsd.DiscordSerf):
|
||||
raise rc.UnsupportedError()
|
||||
|
||||
serf: rsd.DiscordSerf = self.serf
|
||||
client: discord.Client = self.serf.client
|
||||
guild: discord.Guild = client.get_guild(guild_id) if guild_id is not None else None
|
||||
candidate_players: List[rsd.VoicePlayer] = serf.find_voice_players(guild)
|
||||
|
||||
if len(candidate_players) == 0:
|
||||
raise rc.UserError("Il bot non è in nessun canale vocale.\n"
|
||||
"Evocalo prima con [c]summon[/c]!")
|
||||
elif len(candidate_players) == 1:
|
||||
voice_player = candidate_players[0]
|
||||
else:
|
||||
raise rc.CommandError("Non so a che Server cambiare Playable...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
|
||||
if playable_string.upper() == "QUEUE":
|
||||
playable = await RoyalQueue.create()
|
||||
elif playable_string.upper() == "POOL":
|
||||
playable = await RoyalPool.create()
|
||||
else:
|
||||
raise rc.InvalidInputError(f"Unknown playable '{playable_string.upper()}'")
|
||||
|
||||
await voice_player.change_playing(playable)
|
||||
|
||||
return {
|
||||
"name": f"{playable.__class__.__qualname__}"
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
import discord
|
||||
import pickle
|
||||
import base64
|
||||
from typing import *
|
||||
import royalnet.commands as rc
|
||||
from royalnet.serf.discord import *
|
||||
from ..utils import RoyalQueue
|
||||
|
||||
|
||||
class DiscordQueueEvent(rc.Event):
|
||||
name = "discord_queue"
|
||||
|
||||
async def run(self,
|
||||
guild_id: Optional[int] = None,
|
||||
**kwargs) -> dict:
|
||||
if not isinstance(self.serf, DiscordSerf):
|
||||
raise rc.UnsupportedError()
|
||||
client: discord.Client = self.serf.client
|
||||
if len(self.serf.voice_players) == 1:
|
||||
voice_player: VoicePlayer = self.serf.voice_players[0]
|
||||
else:
|
||||
if guild_id is None:
|
||||
# TODO: trovare un modo per riprodurre canzoni su più server da Telegram
|
||||
raise rc.InvalidInputError("Non so in che Server riprodurre questo file...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
guild: discord.Guild = client.get_guild(guild_id)
|
||||
if guild is None:
|
||||
raise rc.InvalidInputError("Impossibile trovare il Server specificato.")
|
||||
candidate_players = self.serf.find_voice_players(guild)
|
||||
if len(candidate_players) == 0:
|
||||
raise rc.UserError("Il bot non è in nessun canale vocale.\n"
|
||||
"Evocalo prima con [c]summon[/c]!")
|
||||
elif len(candidate_players) == 1:
|
||||
voice_player = candidate_players[0]
|
||||
else:
|
||||
raise rc.CommandError("Non so di che Server visualizzare la coda...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
if isinstance(voice_player.playing, RoyalQueue):
|
||||
now_playing = voice_player.playing.now_playing
|
||||
return {
|
||||
"type": f"{voice_player.playing.__class__.__qualname__}",
|
||||
"now_playing": {
|
||||
"title": now_playing.info.title,
|
||||
"stringified_base64_pickled_discord_embed": str(base64.b64encode(pickle.dumps(now_playing.embed())),
|
||||
encoding="ascii")
|
||||
} if now_playing is not None else None,
|
||||
"next_up": [{
|
||||
"title": ytd.info.title,
|
||||
"stringified_base64_pickled_discord_embed": str(base64.b64encode(pickle.dumps(ytd.embed())),
|
||||
encoding="ascii")
|
||||
} for ytd in voice_player.playing.contents]
|
||||
}
|
||||
else:
|
||||
raise rc.CommandError(f"Non so come visualizzare il contenuto di un "
|
||||
f"[c]{voice_player.playing.__class__.__qualname__}[/c].")
|
|
@ -1,38 +0,0 @@
|
|||
import discord
|
||||
from typing import *
|
||||
import royalnet.commands as rc
|
||||
from royalnet.serf.discord import *
|
||||
|
||||
|
||||
class DiscordSkipEvent(rc.Event):
|
||||
name = "discord_skip"
|
||||
|
||||
async def run(self,
|
||||
guild_id: Optional[int] = None,
|
||||
**kwargs) -> dict:
|
||||
if not isinstance(self.serf, DiscordSerf):
|
||||
raise rc.UnsupportedError()
|
||||
client: discord.Client = self.serf.client
|
||||
if len(self.serf.voice_players) == 1:
|
||||
voice_player: VoicePlayer = self.serf.voice_players[0]
|
||||
else:
|
||||
if guild_id is None:
|
||||
# TODO: trovare un modo per riprodurre canzoni su più server da Telegram
|
||||
raise rc.InvalidInputError("Non so in che Server riprodurre questo file...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
guild: discord.Guild = client.get_guild(guild_id)
|
||||
if guild is None:
|
||||
raise rc.InvalidInputError("Impossibile trovare il Server specificato.")
|
||||
candidate_players = self.serf.find_voice_players(guild)
|
||||
if len(candidate_players) == 0:
|
||||
raise rc.UserError("Il bot non è in nessun canale vocale.\n"
|
||||
"Evocalo prima con [c]summon[/c]!")
|
||||
elif len(candidate_players) == 1:
|
||||
voice_player = candidate_players[0]
|
||||
else:
|
||||
raise rc.CommandError("Non so su che Server saltare canzone...\n"
|
||||
"Invia il comando su Discord, per favore!")
|
||||
# Stop the playback of the current song
|
||||
voice_player.voice_client.stop()
|
||||
# Done!
|
||||
return {}
|
|
@ -1,83 +0,0 @@
|
|||
from typing import *
|
||||
from royalnet.commands import *
|
||||
from royalnet.serf.discord import *
|
||||
from royalnet.serf.discord.errors import *
|
||||
from ..utils import RoyalQueue
|
||||
import discord
|
||||
|
||||
|
||||
class DiscordSummonEvent(Event):
|
||||
name = "discord_summon"
|
||||
|
||||
async def run(self, *,
|
||||
channel_name: str = "",
|
||||
channel_id: Optional[int] = None,
|
||||
guild_id: Optional[int] = None,
|
||||
user_id: Optional[int] = None,
|
||||
**kwargs):
|
||||
if not isinstance(self.serf, DiscordSerf):
|
||||
raise UnsupportedError()
|
||||
# Find the guild
|
||||
if guild_id is not None:
|
||||
guild: Optional[discord.Guild] = self.serf.client.get_guild(guild_id)
|
||||
else:
|
||||
guild = None
|
||||
# Find the member
|
||||
if user_id is not None and guild is not None:
|
||||
member: Optional[Union[discord.User, discord.Member]] = guild.get_member(user_id=user_id)
|
||||
else:
|
||||
member = None
|
||||
# From channel id
|
||||
if channel_id is not None:
|
||||
client: discord.Client = self.serf.client
|
||||
channel = client.get_channel(channel_id)
|
||||
# Find channel
|
||||
elif channel_name != "":
|
||||
# Find accessible_to
|
||||
accessible_to = [self.serf.client.user]
|
||||
if member is not None:
|
||||
accessible_to.append(member)
|
||||
# Find the channel
|
||||
channel: Optional["discord.VoiceChannel"] = self.serf.find_channel(channel_type=discord.VoiceChannel,
|
||||
name=channel_name,
|
||||
guild=guild,
|
||||
accessible_to=accessible_to,
|
||||
required_permissions=["connect", "speak"]
|
||||
)
|
||||
elif not (guild_id is None and user_id is None):
|
||||
if member.voice is not None:
|
||||
channel = member.voice.channel
|
||||
else:
|
||||
channel = None
|
||||
else:
|
||||
raise InvalidInputError("Non so a cosa devo connettermi! Specifica il nome di un canale, o entra tu stesso"
|
||||
" in un canale vocale prima di invocare [c]summon[/c]!")
|
||||
if channel is None:
|
||||
raise InvalidInputError("Non ho trovato nessun canale in cui connettermi.")
|
||||
# Create a new VoicePlayer
|
||||
vp = VoicePlayer(loop=self.loop)
|
||||
vp.playing = await RoyalQueue.create()
|
||||
# Connect to the channel
|
||||
try:
|
||||
await vp.connect(channel)
|
||||
except OpusNotLoadedError:
|
||||
raise ConfigurationError("libopus non è disponibile sul sistema in cui sta venendo eseguito questo bot,"
|
||||
" pertanto non è possibile con")
|
||||
except DiscordTimeoutError:
|
||||
raise ExternalError("Timeout durante la connessione al canale."
|
||||
" Forse il bot non ha i permessi per entrarci?")
|
||||
except GuildAlreadyConnectedError:
|
||||
raise UserError("Il bot è già connesso in un canale vocale nel Server!\n"
|
||||
"Spostalo manualmente, o disconnettilo e riinvoca [c]summon[/c]!")
|
||||
# Add the created VoicePlayer to the list
|
||||
self.serf.voice_players.append(vp)
|
||||
# Reply to the request
|
||||
return {
|
||||
"channel": {
|
||||
"id": channel.id,
|
||||
"name": channel.name,
|
||||
"guild": {
|
||||
"name": channel.guild.name,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ import royalnet.commands as rc
|
|||
import datetime
|
||||
|
||||
|
||||
class PongEvent(rc.Event):
|
||||
class PongEvent(rc.HeraldEvent):
|
||||
name = "pong"
|
||||
|
||||
async def run(self, **kwargs) -> dict:
|
||||
|
|
|
@ -2,21 +2,21 @@ import logging
|
|||
import telegram
|
||||
from typing import *
|
||||
from royalnet.serf.telegram.telegramserf import TelegramSerf, escape
|
||||
from royalnet.commands import *
|
||||
import royalnet.commands as rc
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TelegramMessageEvent(Event):
|
||||
class TelegramMessageEvent(rc.HeraldEvent):
|
||||
name = "telegram_message"
|
||||
|
||||
async def run(self, chat_id, text, **kwargs) -> dict:
|
||||
if not self.interface.name == "telegram":
|
||||
raise UnsupportedError()
|
||||
if not isinstance(self.parent, TelegramSerf):
|
||||
raise rc.UnsupportedError()
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
serf: TelegramSerf = self.interface.serf
|
||||
serf: TelegramSerf = self.parent
|
||||
|
||||
log.debug("Forwarding message from Herald to Telegram.")
|
||||
await serf.api_call(serf.client.send_message,
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
import logging
|
||||
from typing import Optional, List, AsyncGenerator, Tuple, Any, Dict
|
||||
from royalnet.bard.discord import YtdlDiscord
|
||||
from royalnet.serf.discord import Playable
|
||||
import discord
|
||||
import random
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RoyalPool(Playable):
|
||||
"""A pool of :class:`YtdlDiscord` that will be played in a loop."""
|
||||
def __init__(self, start_with: Optional[List[YtdlDiscord]] = None):
|
||||
super().__init__()
|
||||
self.full_pool: List[YtdlDiscord] = []
|
||||
self.remaining_pool: List[YtdlDiscord] = []
|
||||
self.now_playing: Optional[YtdlDiscord] = None
|
||||
if start_with is not None:
|
||||
self.full_pool = [*self.full_pool, *start_with]
|
||||
log.debug(f"Created new {self.__class__.__qualname__} containing: {self.full_pool}")
|
||||
|
||||
async def _generator(self) \
|
||||
-> AsyncGenerator[Optional["discord.AudioSource"], Tuple[Tuple[Any, ...], Dict[str, Any]]]:
|
||||
yield
|
||||
while True:
|
||||
if len(self.remaining_pool) == 0:
|
||||
if len(self.full_pool) == 0:
|
||||
log.debug(f"Nothing in the pool, yielding None...")
|
||||
yield None
|
||||
continue
|
||||
else:
|
||||
self.remaining_pool = self.full_pool.copy()
|
||||
random.shuffle(self.remaining_pool)
|
||||
log.debug(f"Dequeuing an item...")
|
||||
# Get the first YtdlDiscord of the queue
|
||||
self.now_playing: YtdlDiscord = self.remaining_pool.pop(0)
|
||||
log.debug(f"Yielding FileAudioSource from: {self.now_playing}")
|
||||
# Create a FileAudioSource from the YtdlDiscord
|
||||
# If the file hasn't been fetched / downloaded / converted yet, it will do so before yielding
|
||||
async with self.now_playing.spawn_audiosource() as fas:
|
||||
# Yield the resulting AudioSource
|
||||
yield fas
|
||||
|
||||
async def destroy(self):
|
||||
for file in self.full_pool:
|
||||
log.debug(f"Deleting: {file}")
|
||||
await file.delete_asap()
|
||||
log.debug(f"Deleting: {file.ytdl_file}")
|
||||
await file.ytdl_file.delete_asap()
|
||||
log.debug(f"Deleted successfully!")
|
||||
self.full_pool = []
|
||||
self.remaining_pool = []
|
||||
self.now_playing = None
|
|
@ -1,62 +0,0 @@
|
|||
import logging
|
||||
from typing import Optional, List, AsyncGenerator, Tuple, Any, Dict
|
||||
from royalnet.bard.discord import YtdlDiscord
|
||||
from royalnet.serf.discord import Playable
|
||||
import discord
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RoyalQueue(Playable):
|
||||
"""A queue of :class:`YtdlDiscord` to be played in sequence."""
|
||||
def __init__(self, start_with: Optional[List[YtdlDiscord]] = None):
|
||||
super().__init__()
|
||||
self.contents: List[YtdlDiscord] = []
|
||||
self.now_playing: Optional[YtdlDiscord] = None
|
||||
if start_with is not None:
|
||||
self.contents = [*self.contents, *start_with]
|
||||
log.debug(f"Created new {self.__class__.__qualname__} containing: {self.contents}")
|
||||
|
||||
async def _generator(self) \
|
||||
-> AsyncGenerator[Optional["discord.AudioSource"], Tuple[Tuple[Any, ...], Dict[str, Any]]]:
|
||||
yield
|
||||
while True:
|
||||
log.debug(f"Dequeuing an item...")
|
||||
try:
|
||||
# Try to get the first YtdlDiscord of the queue
|
||||
self.now_playing: YtdlDiscord = self.contents.pop(0)
|
||||
except IndexError:
|
||||
# If there isn't anything, yield None
|
||||
log.debug(f"Nothing to dequeue, yielding None.")
|
||||
yield None
|
||||
continue
|
||||
log.debug(f"Yielding FileAudioSource from: {self.now_playing}")
|
||||
# Create a FileAudioSource from the YtdlDiscord
|
||||
# If the file hasn't been fetched / downloaded / converted yet, it will do so before yielding
|
||||
async with self.now_playing.spawn_audiosource() as fas:
|
||||
# Yield the resulting AudioSource
|
||||
yield fas
|
||||
# Delete the YtdlDiscord file
|
||||
log.debug(f"Deleting: {self.now_playing}")
|
||||
await self.now_playing.delete_asap()
|
||||
log.debug(f"Deleting: {self.now_playing.ytdl_file}")
|
||||
await self.now_playing.ytdl_file.delete_asap()
|
||||
log.debug(f"Deleted successfully!")
|
||||
self.now_playing = None
|
||||
|
||||
async def destroy(self):
|
||||
if self.now_playing is not None:
|
||||
log.debug(f"Deleting: {self.now_playing}")
|
||||
await self.now_playing.delete_asap()
|
||||
log.debug(f"Deleting: {self.now_playing.ytdl_file}")
|
||||
await self.now_playing.ytdl_file.delete_asap()
|
||||
log.debug(f"Deleted successfully!")
|
||||
self.now_playing = None
|
||||
for file in self.contents:
|
||||
log.debug(f"Deleting: {file}")
|
||||
await file.delete_asap()
|
||||
log.debug(f"Deleting: {file.ytdl_file}")
|
||||
await file.ytdl_file.delete_asap()
|
||||
log.debug(f"Deleted successfully!")
|
||||
self.contents = []
|
Loading…
Reference in a new issue