diff --git a/royalnet/bard/__init__.py b/royalnet/bard/__init__.py index 1136c40c..54012c6c 100644 --- a/royalnet/bard/__init__.py +++ b/royalnet/bard/__init__.py @@ -17,13 +17,11 @@ except ImportError: from .ytdlinfo import YtdlInfo from .ytdlfile import YtdlFile -from .ytdlmp3 import YtdlMp3 from .errors import BardError, YtdlError, NotFoundError, MultipleFilesError __all__ = [ "YtdlInfo", "YtdlFile", - "YtdlMp3", "BardError", "YtdlError", "NotFoundError", diff --git a/royalnet/bard/ytdlmp3.py b/royalnet/bard/ytdlmp3.py deleted file mode 100644 index 7dfda4d4..00000000 --- a/royalnet/bard/ytdlmp3.py +++ /dev/null @@ -1,67 +0,0 @@ -from typing import * -import re -import os -import ffmpeg -import royalnet.utils as ru -from .ytdlinfo import YtdlInfo -from .ytdlfile import YtdlFile - - -class YtdlMp3: - """A representation of a :class:`YtdlFile` conversion to mp3.""" - def __init__(self, ytdl_file: YtdlFile): - self.ytdl_file: YtdlFile = ytdl_file - self.mp3_filename: Optional[str] = None - self.lock: ru.MultiLock = ru.MultiLock() - - def __repr__(self): - if not self.ytdl_file.has_info: - return f"<{self.__class__.__qualname__} without info>" - elif not self.ytdl_file.is_downloaded: - return f"<{self.__class__.__qualname__} not downloaded>" - elif not self.is_converted: - return f"<{self.__class__.__qualname__} at '{self.ytdl_file.filename}' not converted>" - else: - return f"<{self.__class__.__qualname__} at '{self.mp3_filename}'>" - - @property - def is_converted(self): - """Has the file been converted?""" - return self.mp3_filename is not None - - async def convert_to_mp3(self) -> None: - """Convert the file to mp3 with :mod:`ffmpeg`.""" - await self.ytdl_file.download_file() - if self.mp3_filename is None: - async with self.ytdl_file.lock.normal(): - destination_filename = re.sub(r"\.[^.]+$", ".mp3", self.ytdl_file.filename) - async with self.lock.exclusive(): - await ru.asyncify( - ffmpeg.input(self.ytdl_file.filename) - .output(destination_filename, format="mp3") - .overwrite_output() - .run - ) - self.mp3_filename = destination_filename - - async def delete_asap(self) -> None: - """Delete the mp3 file.""" - if self.is_converted: - async with self.lock.exclusive(): - os.remove(self.mp3_filename) - self.mp3_filename = None - - @classmethod - async def from_url(cls, url, **ytdl_args) -> List["YtdlMp3"]: - """Create a :class:`list` of :class:`YtdlMp3` from a URL.""" - files = await YtdlFile.from_url(url, **ytdl_args) - dfiles = [] - for file in files: - dfile = YtdlMp3(file) - dfiles.append(dfile) - return dfiles - - @property - def info(self) -> Optional[YtdlInfo]: - """Shortcut to get the :class:`YtdlInfo` of the object.""" - return self.ytdl_file.info diff --git a/royalnet/commands/commandargs.py b/royalnet/commands/commandargs.py index e5211c70..f66833e5 100644 --- a/royalnet/commands/commandargs.py +++ b/royalnet/commands/commandargs.py @@ -1,5 +1,5 @@ import re -from typing import * +import typing from .errors import InvalidInputError @@ -66,7 +66,7 @@ class CommandArgs(list): raise InvalidInputError(f"Not enough arguments specified (minimum is {require_at_least}).") return " ".join(self) - def match(self, pattern: Union[str, Pattern], *flags) -> Sequence[AnyStr]: + def match(self, pattern: typing.Union[str, typing.Pattern], *flags) -> typing.Sequence[typing.AnyStr]: """Match the :meth:`.joined` string to a :class:`re.Pattern`-like object. Parameters: @@ -83,7 +83,7 @@ class CommandArgs(list): raise InvalidInputError("Invalid syntax.") return match.groups() - def optional(self, index: int, default=None) -> Optional[str]: + def optional(self, index: int, default=None) -> typing.Optional[str]: """Get the argument at a specific index, but don't raise an error if nothing is found, instead returning the ``default`` value. diff --git a/royalnet/commands/event.py b/royalnet/commands/event.py index e4309c7a..67a08d7b 100644 --- a/royalnet/commands/event.py +++ b/royalnet/commands/event.py @@ -18,7 +18,7 @@ class Event: """The :class:`CommandInterface` available to this :class:`Event`.""" @property - def serf(self) -> Serf: + def serf(self) -> "Serf": """A shortcut for :attr:`.interface.serf`.""" return self.interface.serf diff --git a/royalnet/serf/discord/voiceplayer.py b/royalnet/serf/discord/voiceplayer.py index 6d424ca8..b365e805 100644 --- a/royalnet/serf/discord/voiceplayer.py +++ b/royalnet/serf/discord/voiceplayer.py @@ -20,7 +20,6 @@ class VoicePlayer: self.loop: asyncio.AbstractEventLoop = asyncio.get_event_loop() else: self.loop = loop - # FIXME: this looks like spaghetti self._playback_ended_event: threading.Event = threading.Event() async def connect(self, channel: "discord.VoiceChannel") -> "discord.VoiceClient": @@ -88,6 +87,7 @@ class VoicePlayer: raise PlayerNotConnectedError() if self.voice_client.is_playing(): raise PlayerAlreadyPlaying() + self.playing = None log.debug("Getting next AudioSource...") next_source: Optional["discord.AudioSource"] = await self.playing.next() if next_source is None: @@ -98,7 +98,6 @@ class VoicePlayer: self.loop.create_task(self._playback_check()) async def _playback_check(self): - # FIXME: quite spaghetti while True: if self._playback_ended_event.is_set(): self._playback_ended_event.clear() diff --git a/royalnet/serf/serf.py b/royalnet/serf/serf.py index da957343..8f8eb0c9 100644 --- a/royalnet/serf/serf.py +++ b/royalnet/serf/serf.py @@ -8,6 +8,7 @@ import royalnet.utils as ru import royalnet.alchemy as ra import royalnet.backpack as rb import royalnet.herald as rh +import traceback log = logging.getLogger(__name__) @@ -39,7 +40,7 @@ class Serf: try: packs[pack_name] = importlib.import_module(pack_name) except ImportError as e: - log.error(f"Error during the import of {pack_name}: {e}") + log.error(f"{e.__class__.__name__} during the import of {pack_name}: {e}") log.info(f"Packs: {len(packs)} imported") self.alchemy: Optional[ra.Alchemy] = None