From d9d4857a16eecda66c989b0b8395f6bb0c182a7a Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 3 Dec 2019 19:00:52 +0100 Subject: [PATCH] Final touches --- royalpack/commands/queue.py | 2 +- royalpack/commands/summon.py | 1 - royalpack/events/discord_play.py | 3 +- royalpack/events/discord_queue.py | 3 +- royalpack/events/discord_summon.py | 3 +- royalpack/utils/__init__.py | 11 +++++++- royalpack/utils/royalqueue.py | 45 ++++++++++++++++++++++++++++++ 7 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 royalpack/utils/royalqueue.py diff --git a/royalpack/commands/queue.py b/royalpack/commands/queue.py index 2af55c66..751e2180 100644 --- a/royalpack/commands/queue.py +++ b/royalpack/commands/queue.py @@ -24,7 +24,7 @@ class QueueCommand(Command): guild_id=guild_id) queue_type = response["type"] - if queue_type == "PlayableYTDQueue": + if queue_type == "RoyalQueue": next_up = response["next_up"] now_playing = response["now_playing"] await data.reply(f"ℹ️ La coda contiene {len(next_up)} file.\n\n") diff --git a/royalpack/commands/summon.py b/royalpack/commands/summon.py index 97246a18..4fc2cd3b 100644 --- a/royalpack/commands/summon.py +++ b/royalpack/commands/summon.py @@ -1,4 +1,3 @@ -import typing import discord from royalnet.commands import * diff --git a/royalpack/events/discord_play.py b/royalpack/events/discord_play.py index 294bb735..883eb863 100644 --- a/royalpack/events/discord_play.py +++ b/royalpack/events/discord_play.py @@ -6,6 +6,7 @@ from typing import * from royalnet.commands import * from royalnet.serf.discord import * from royalnet.bard import * +from ..utils import RoyalQueue class DiscordPlayEvent(Event): @@ -35,7 +36,7 @@ class DiscordPlayEvent(Event): ytds = await YtdlDiscord.from_url(url) added: List[YtdlDiscord] = [] too_long: List[YtdlDiscord] = [] - if isinstance(voice_player.playing, PlayableYTDQueue): + 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) diff --git a/royalpack/events/discord_queue.py b/royalpack/events/discord_queue.py index 396ab887..6a668f05 100644 --- a/royalpack/events/discord_queue.py +++ b/royalpack/events/discord_queue.py @@ -4,6 +4,7 @@ import base64 from typing import * from royalnet.commands import * from royalnet.serf.discord import * +from ..utils import RoyalQueue class DiscordQueueEvent(Event): @@ -29,7 +30,7 @@ class DiscordQueueEvent(Event): if voice_player is None: raise UserError("Il bot non è in nessun canale vocale.\n" "Evocalo prima con [c]summon[/c]!") - if isinstance(voice_player.playing, PlayableYTDQueue): + if isinstance(voice_player.playing, RoyalQueue): now_playing = voice_player.playing.now_playing return { "type": f"{voice_player.playing.__class__.__qualname__}", diff --git a/royalpack/events/discord_summon.py b/royalpack/events/discord_summon.py index 646613c4..4f74f69d 100644 --- a/royalpack/events/discord_summon.py +++ b/royalpack/events/discord_summon.py @@ -2,6 +2,7 @@ from typing import * from royalnet.commands import * from royalnet.serf.discord import * from royalnet.serf.discord.errors import * +from ..utils import RoyalQueue import discord @@ -55,7 +56,7 @@ class DiscordSummonEvent(Event): raise InvalidInputError("Non ho trovato nessun canale in cui connettermi.") # Create a new VoicePlayer vp = VoicePlayer(loop=self.loop) - vp.playing = await PlayableYTDQueue.create() + vp.playing = await RoyalQueue.create() # Connect to the channel try: await vp.connect(channel) diff --git a/royalpack/utils/__init__.py b/royalpack/utils/__init__.py index aaab3673..1dc3db68 100644 --- a/royalpack/utils/__init__.py +++ b/royalpack/utils/__init__.py @@ -3,5 +3,14 @@ from .mminterfacedata import MMInterfaceData, MMInterfaceDataTelegram from .leaguetier import LeagueTier from .leaguerank import LeagueRank from .leagueleague import LeagueLeague +from .royalqueue import RoyalQueue -__all__ = ["MMChoice", "MMInterfaceData", "MMInterfaceDataTelegram", "LeagueTier", "LeagueRank", "LeagueLeague"] +__all__ = [ + "MMChoice", + "MMInterfaceData", + "MMInterfaceDataTelegram", + "LeagueTier", + "LeagueRank", + "LeagueLeague", + "RoyalQueue", +] diff --git a/royalpack/utils/royalqueue.py b/royalpack/utils/royalqueue.py new file mode 100644 index 00000000..a70aa04a --- /dev/null +++ b/royalpack/utils/royalqueue.py @@ -0,0 +1,45 @@ +import logging +from typing import Optional, List, AsyncGenerator, Tuple, Any, Dict +from royalnet.bard 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!")