1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-12-17 23:24:20 +00:00

Create queue command

This commit is contained in:
Steffo 2019-06-02 18:19:53 +02:00
parent a512da0058
commit 956cdb5ac0
7 changed files with 116 additions and 5 deletions

View file

@ -47,6 +47,18 @@ class PlayMode:
"""Delete all :py:class:`royalnet.audio.RoyalPCMAudio` contained inside this PlayMode.""" """Delete all :py:class:`royalnet.audio.RoyalPCMAudio` contained inside this PlayMode."""
raise NotImplementedError() raise NotImplementedError()
def queue_preview(self) -> typing.List[RoyalPCMAudio]:
"""Display all the videos in the PlayMode as a list, if possible.
To be used with `queue` commands, for example.
Raises:
NotImplementedError: If a preview can't be generated.
Returns:
A list of videos contained in the queue."""
raise NotImplementedError()
class Playlist(PlayMode): class Playlist(PlayMode):
"""A video list. :py:class:`royalnet.audio.RoyalPCMAudio` played are removed from the list.""" """A video list. :py:class:`royalnet.audio.RoyalPCMAudio` played are removed from the list."""
@ -85,6 +97,9 @@ class Playlist(PlayMode):
while self.list: while self.list:
self.list.pop(0).delete() self.list.pop(0).delete()
def queue_preview(self) -> typing.List[RoyalPCMAudio]:
return self.list
class Pool(PlayMode): class Pool(PlayMode):
"""A :py:class:`royalnet.audio.RoyalPCMAudio` pool. :py:class:`royalnet.audio.RoyalPCMAudio` are selected in random order and are not repeated until every song has been played at least once.""" """A :py:class:`royalnet.audio.RoyalPCMAudio` pool. :py:class:`royalnet.audio.RoyalPCMAudio` are selected in random order and are not repeated until every song has been played at least once."""
@ -126,3 +141,8 @@ class Pool(PlayMode):
item.delete() item.delete()
self.pool = None self.pool = None
self._pool_copy = None self._pool_copy = None
def queue_preview(self) -> typing.List[RoyalPCMAudio]:
preview_pool = self.pool.copy()
random.shuffle(preview_pool)
return preview_pool

View file

@ -26,9 +26,11 @@ from .videochannel import VideochannelCommand
from .missing import MissingCommand from .missing import MissingCommand
from .cv import CvCommand from .cv import CvCommand
from .pause import PauseCommand from .pause import PauseCommand
from .queue import QueueCommand
__all__ = ["NullCommand", "PingCommand", "ShipCommand", "SmecdsCommand", "CiaoruoziCommand", "ColorCommand", __all__ = ["NullCommand", "PingCommand", "ShipCommand", "SmecdsCommand", "CiaoruoziCommand", "ColorCommand",
"SyncCommand", "DiarioCommand", "RageCommand", "DateparserCommand", "AuthorCommand", "ReminderCommand", "SyncCommand", "DiarioCommand", "RageCommand", "DateparserCommand", "AuthorCommand", "ReminderCommand",
"KvactiveCommand", "KvCommand", "KvrollCommand", "VideoinfoCommand", "SummonCommand", "PlayCommand", "KvactiveCommand", "KvCommand", "KvrollCommand", "VideoinfoCommand", "SummonCommand", "PlayCommand",
"SkipCommand", "PlaymodeCommand", "VideochannelCommand", "MissingCommand", "CvCommand", "PauseCommand"] "SkipCommand", "PlaymodeCommand", "VideochannelCommand", "MissingCommand", "CvCommand", "PauseCommand",
"QueueCommand"]

View file

@ -10,6 +10,7 @@ if typing.TYPE_CHECKING:
class PauseNH(NetworkHandler): class PauseNH(NetworkHandler):
message_type = "music_pause" message_type = "music_pause"
# noinspection PyProtectedMember
@classmethod @classmethod
async def discord(cls, bot: "DiscordBot", data: dict): async def discord(cls, bot: "DiscordBot", data: dict):
# Find the matching guild # Find the matching guild
@ -23,7 +24,7 @@ class PauseNH(NetworkHandler):
guild = list(bot.music_data)[0] guild = list(bot.music_data)[0]
# Set the currently playing source as ended # Set the currently playing source as ended
voice_client: discord.VoiceClient = bot.client.find_voice_client_by_guild(guild) voice_client: discord.VoiceClient = bot.client.find_voice_client_by_guild(guild)
if not voice_client.is_playing(): if not (voice_client.is_playing() or voice_client.is_paused()):
raise NoneFoundError("Nothing to pause") raise NoneFoundError("Nothing to pause")
# Toggle pause # Toggle pause
resume = voice_client._player.is_paused() resume = voice_client._player.is_paused()

View file

@ -0,0 +1,76 @@
import typing
import pickle
from ..network import Request, ResponseSuccess
from ..utils import Command, Call, NetworkHandler, numberemojiformat
from ..error import TooManyFoundError, NoneFoundError
if typing.TYPE_CHECKING:
from ..bots import DiscordBot
class QueueNH(NetworkHandler):
message_type = "music_queue"
@classmethod
async def discord(cls, bot: "DiscordBot", data: dict):
# Find the matching guild
if data["guild_name"]:
guild = bot.client.find_guild_by_name(data["guild_name"])
else:
if len(bot.music_data) == 0:
raise NoneFoundError("No voice clients active")
if len(bot.music_data) > 1:
raise TooManyFoundError("Multiple guilds found")
guild = list(bot.music_data)[0]
# Check if the guild has a PlayMode
playmode = bot.music_data.get(guild)
if not playmode:
return ResponseSuccess({
"type": None
})
try:
queue = playmode.queue_preview()
except NotImplementedError:
return ResponseSuccess({
"type": playmode.__class__.__name__
})
return ResponseSuccess({
"type": playmode.__class__.__name__,
"queue":
{
"strings": [str(element.rpf.info) for element in queue],
"pickled_embeds": str(pickle.dumps([element.rpf.info.to_discord_embed() for element in queue]))
}
})
class QueueCommand(Command):
command_name = "queue"
command_description = "Visualizza un'anteprima della coda di riproduzione attuale."
command_syntax = "[ [guild] ]"
network_handlers = [QueueNH]
@classmethod
async def common(cls, call: Call):
guild, = call.args.match(r"(?:\[(.+)])?")
data = await call.net_request(Request("music_queue", {"guild_name": guild}), "discord")
if data["type"] is None:
await call.reply(" Non c'è nessuna coda di riproduzione attiva al momento.")
return
elif "queue" not in data:
await call.reply(f" La coda di riproduzione attuale ([c]{data['type']}[/c]) non permette l'anteprima.")
return
if data["type"] == "Playlist":
message = f" Questa [c]Playlist[/c] contiene {len(data['queue'])} elementi, e i prossimi saranno:\n"
elif data["type"] == "Pool":
message = f" Questo [c]Pool[/c] contiene {len(data['queue'])} elementi, tra cui:\n"
else:
message = f" Il PlayMode attuale, [c]{data['type']}[/c], contiene {len(data['queue'])} elementi:\n"
if call.interface_name == "discord":
await call.reply(message)
for embed in pickle.loads(eval(data["queue"]["pickled_embeds"]))[:5]:
await call.channel.send(embed=embed)
else:
message += numberemojiformat(data["queue"]["strings"])
await call.reply(message)

View file

@ -20,7 +20,7 @@ log.setLevel(logging.WARNING)
commands = [PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, DebugCreateCommand, SyncCommand, commands = [PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, DebugCreateCommand, SyncCommand,
AuthorCommand, DiarioCommand, RageCommand, DateparserCommand, ReminderCommand, KvactiveCommand, KvCommand, AuthorCommand, DiarioCommand, RageCommand, DateparserCommand, ReminderCommand, KvactiveCommand, KvCommand,
KvrollCommand, VideoinfoCommand, SummonCommand, PlayCommand, SkipCommand, PlaymodeCommand, KvrollCommand, VideoinfoCommand, SummonCommand, PlayCommand, SkipCommand, PlaymodeCommand,
VideochannelCommand, CvCommand, PauseCommand] VideochannelCommand, CvCommand, PauseCommand, QueueCommand]
address, port = "127.0.0.1", 1234 address, port = "127.0.0.1", 1234

View file

@ -9,7 +9,7 @@ from .safeformat import safeformat
from .classdictjanitor import cdj from .classdictjanitor import cdj
from .sleepuntil import sleep_until from .sleepuntil import sleep_until
from .networkhandler import NetworkHandler from .networkhandler import NetworkHandler
from .formatters import andformat, plusformat, fileformat, ytdldateformat from .formatters import andformat, plusformat, fileformat, ytdldateformat, numberemojiformat
__all__ = ["asyncify", "Call", "Command", "safeformat", "cdj", "sleep_until", "plusformat", "CommandArgs", __all__ = ["asyncify", "Call", "Command", "safeformat", "cdj", "sleep_until", "plusformat", "CommandArgs",
"NetworkHandler", "andformat", "plusformat", "fileformat", "ytdldateformat"] "NetworkHandler", "andformat", "plusformat", "fileformat", "ytdldateformat", "numberemojiformat"]

View file

@ -58,3 +58,15 @@ def ytdldateformat(string: typing.Optional[str], separator: str = "-") -> str:
if string is None: if string is None:
return "" return ""
return f"{string[0:4]}{separator}{string[4:6]}{separator}{string[6:8]}" return f"{string[0:4]}{separator}{string[4:6]}{separator}{string[6:8]}"
def numberemojiformat(l: typing.List[str]) -> str:
number_emojis = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "🔟"]
extra_emoji = "*️⃣"
result = ""
for index, element in enumerate(l):
try:
result += f"{number_emojis[index]} {element}\n"
except IndexError:
result += f"{extra_emoji} {element}\n"
return result