mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Create queue command
This commit is contained in:
parent
a512da0058
commit
956cdb5ac0
7 changed files with 116 additions and 5 deletions
|
@ -47,6 +47,18 @@ class PlayMode:
|
|||
"""Delete all :py:class:`royalnet.audio.RoyalPCMAudio` contained inside this PlayMode."""
|
||||
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):
|
||||
"""A video list. :py:class:`royalnet.audio.RoyalPCMAudio` played are removed from the list."""
|
||||
|
@ -85,6 +97,9 @@ class Playlist(PlayMode):
|
|||
while self.list:
|
||||
self.list.pop(0).delete()
|
||||
|
||||
def queue_preview(self) -> typing.List[RoyalPCMAudio]:
|
||||
return self.list
|
||||
|
||||
|
||||
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."""
|
||||
|
@ -126,3 +141,8 @@ class Pool(PlayMode):
|
|||
item.delete()
|
||||
self.pool = None
|
||||
self._pool_copy = None
|
||||
|
||||
def queue_preview(self) -> typing.List[RoyalPCMAudio]:
|
||||
preview_pool = self.pool.copy()
|
||||
random.shuffle(preview_pool)
|
||||
return preview_pool
|
|
@ -26,9 +26,11 @@ from .videochannel import VideochannelCommand
|
|||
from .missing import MissingCommand
|
||||
from .cv import CvCommand
|
||||
from .pause import PauseCommand
|
||||
from .queue import QueueCommand
|
||||
|
||||
|
||||
__all__ = ["NullCommand", "PingCommand", "ShipCommand", "SmecdsCommand", "CiaoruoziCommand", "ColorCommand",
|
||||
"SyncCommand", "DiarioCommand", "RageCommand", "DateparserCommand", "AuthorCommand", "ReminderCommand",
|
||||
"KvactiveCommand", "KvCommand", "KvrollCommand", "VideoinfoCommand", "SummonCommand", "PlayCommand",
|
||||
"SkipCommand", "PlaymodeCommand", "VideochannelCommand", "MissingCommand", "CvCommand", "PauseCommand"]
|
||||
"SkipCommand", "PlaymodeCommand", "VideochannelCommand", "MissingCommand", "CvCommand", "PauseCommand",
|
||||
"QueueCommand"]
|
||||
|
|
|
@ -10,6 +10,7 @@ if typing.TYPE_CHECKING:
|
|||
class PauseNH(NetworkHandler):
|
||||
message_type = "music_pause"
|
||||
|
||||
# noinspection PyProtectedMember
|
||||
@classmethod
|
||||
async def discord(cls, bot: "DiscordBot", data: dict):
|
||||
# Find the matching guild
|
||||
|
@ -23,7 +24,7 @@ class PauseNH(NetworkHandler):
|
|||
guild = list(bot.music_data)[0]
|
||||
# Set the currently playing source as ended
|
||||
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")
|
||||
# Toggle pause
|
||||
resume = voice_client._player.is_paused()
|
||||
|
|
76
royalnet/commands/queue.py
Normal file
76
royalnet/commands/queue.py
Normal 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)
|
|
@ -20,7 +20,7 @@ log.setLevel(logging.WARNING)
|
|||
commands = [PingCommand, ShipCommand, SmecdsCommand, ColorCommand, CiaoruoziCommand, DebugCreateCommand, SyncCommand,
|
||||
AuthorCommand, DiarioCommand, RageCommand, DateparserCommand, ReminderCommand, KvactiveCommand, KvCommand,
|
||||
KvrollCommand, VideoinfoCommand, SummonCommand, PlayCommand, SkipCommand, PlaymodeCommand,
|
||||
VideochannelCommand, CvCommand, PauseCommand]
|
||||
VideochannelCommand, CvCommand, PauseCommand, QueueCommand]
|
||||
|
||||
address, port = "127.0.0.1", 1234
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from .safeformat import safeformat
|
|||
from .classdictjanitor import cdj
|
||||
from .sleepuntil import sleep_until
|
||||
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",
|
||||
"NetworkHandler", "andformat", "plusformat", "fileformat", "ytdldateformat"]
|
||||
"NetworkHandler", "andformat", "plusformat", "fileformat", "ytdldateformat", "numberemojiformat"]
|
||||
|
|
|
@ -58,3 +58,15 @@ def ytdldateformat(string: typing.Optional[str], separator: str = "-") -> str:
|
|||
if string is None:
|
||||
return ""
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue