mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
Pretty sure this was a bad idea
This commit is contained in:
parent
30a951c69e
commit
279de8efe4
2 changed files with 155 additions and 139 deletions
290
discordbot.py
290
discordbot.py
|
@ -32,8 +32,9 @@ logger = logging.getLogger(__name__)
|
||||||
os.environ["COLOREDLOGS_LOG_FORMAT"] = "%(asctime)s %(levelname)s %(name)s %(message)s"
|
os.environ["COLOREDLOGS_LOG_FORMAT"] = "%(asctime)s %(levelname)s %(name)s %(message)s"
|
||||||
coloredlogs.install(level="DEBUG", logger=logger)
|
coloredlogs.install(level="DEBUG", logger=logger)
|
||||||
|
|
||||||
# Number emojis from one to ten
|
# Number emojis from zero (now playing) to ten
|
||||||
number_emojis = [":one:",
|
number_emojis = [":arrow_forward:",
|
||||||
|
":one:",
|
||||||
":two:",
|
":two:",
|
||||||
":three:",
|
":three:",
|
||||||
":four:",
|
":four:",
|
||||||
|
@ -128,6 +129,7 @@ class YoutubeDLVideo(Video):
|
||||||
"""Get info about the video."""
|
"""Get info about the video."""
|
||||||
if self.info:
|
if self.info:
|
||||||
return
|
return
|
||||||
|
logger.debug(f"Getting info on {self.url}...")
|
||||||
with youtube_dl.YoutubeDL({"quiet": True,
|
with youtube_dl.YoutubeDL({"quiet": True,
|
||||||
"ignoreerrors": True,
|
"ignoreerrors": True,
|
||||||
"simulate": True}) as ytdl:
|
"simulate": True}) as ytdl:
|
||||||
|
@ -193,9 +195,13 @@ class YoutubeDLVideo(Video):
|
||||||
return
|
return
|
||||||
# Ensure the video has info
|
# Ensure the video has info
|
||||||
self.get_info()
|
self.get_info()
|
||||||
|
# Ensure the video is from youtube
|
||||||
if self.info["extractor"] != "youtube":
|
if self.info["extractor"] != "youtube":
|
||||||
# TODO: add more websites?
|
# TODO: add more websites?
|
||||||
self.suggestion = NotImplemented
|
self.suggestion = NotImplemented
|
||||||
|
# Log the attempt
|
||||||
|
logger.debug(f"Getting a suggestion for {self.url}...")
|
||||||
|
# Check for the api key
|
||||||
if self.youtube_api_key is None:
|
if self.youtube_api_key is None:
|
||||||
raise errors.MissingAPIKeyError()
|
raise errors.MissingAPIKeyError()
|
||||||
# Request search data (costs 100 API units)
|
# Request search data (costs 100 API units)
|
||||||
|
@ -231,19 +237,13 @@ class VideoQueue:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.list: typing.List[Video] = []
|
self.list: typing.List[Video] = []
|
||||||
self.now_playing: typing.Optional[Video] = None
|
|
||||||
self.loop_mode = LoopMode.NORMAL
|
self.loop_mode = LoopMode.NORMAL
|
||||||
|
|
||||||
def __len__(self) -> int:
|
def __len__(self) -> int:
|
||||||
return len(self.list)
|
return len(self.list)
|
||||||
|
|
||||||
def __next__(self) -> Video:
|
|
||||||
video = self.next_video()
|
|
||||||
self.advance_queue()
|
|
||||||
return video
|
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"<VideoQueue of length {len(self)}>"
|
return f"<VideoQueue of length {len(self)} in mode {self.loop_mode}>"
|
||||||
|
|
||||||
def add(self, video: Video, position: int = None) -> None:
|
def add(self, video: Video, position: int = None) -> None:
|
||||||
if position is None:
|
if position is None:
|
||||||
|
@ -251,44 +251,28 @@ class VideoQueue:
|
||||||
return
|
return
|
||||||
self.list.insert(position, video)
|
self.list.insert(position, video)
|
||||||
|
|
||||||
|
def pop(self, index) -> Video:
|
||||||
|
if self.loop_mode == LoopMode.FOLLOW_SUGGESTIONS:
|
||||||
|
raise errors.LoopModeError("Can't pop items from a suggestion queue.")
|
||||||
|
result = self[index]
|
||||||
|
self.list.remove(result)
|
||||||
|
return result
|
||||||
|
|
||||||
def advance_queue(self):
|
def advance_queue(self):
|
||||||
"""Advance the queue to the next video."""
|
"""Advance the queue to the next video."""
|
||||||
if self.loop_mode == LoopMode.NORMAL:
|
del self[0]
|
||||||
try:
|
|
||||||
self.now_playing = self.list.pop(0)
|
|
||||||
except IndexError:
|
|
||||||
self.now_playing = None
|
|
||||||
elif self.loop_mode == LoopMode.LOOP_QUEUE:
|
|
||||||
self.add(self.list[0])
|
|
||||||
self.now_playing = self.list.pop(0)
|
|
||||||
elif self.loop_mode == LoopMode.LOOP_SINGLE:
|
|
||||||
pass
|
|
||||||
elif self.loop_mode == LoopMode.FOLLOW_SUGGESTIONS:
|
|
||||||
if self.now_playing is None:
|
|
||||||
if len(self.list) > 0:
|
|
||||||
self.now_playing = self.list.pop(0)
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
self.now_playing.get_suggestion()
|
|
||||||
self.now_playing = self.now_playing.suggestion
|
|
||||||
elif self.loop_mode == LoopMode.AUTO_SHUFFLE:
|
|
||||||
self.shuffle()
|
|
||||||
try:
|
|
||||||
self.now_playing = self.list.pop(0)
|
|
||||||
except IndexError:
|
|
||||||
self.now_playing = None
|
|
||||||
elif self.loop_mode == LoopMode.LOOPING_SHUFFLE:
|
|
||||||
self.shuffle()
|
|
||||||
self.add(self.list[0])
|
|
||||||
self.now_playing = self.list.pop(0)
|
|
||||||
|
|
||||||
def next_video(self) -> typing.Optional[Video]:
|
def next_video(self) -> typing.Optional[Video]:
|
||||||
if len(self.list) == 0:
|
try:
|
||||||
|
return self[1]
|
||||||
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
return self.list[0]
|
|
||||||
|
|
||||||
def shuffle(self):
|
def shuffle(self):
|
||||||
random.shuffle(self.list)
|
part = self.list[1:]
|
||||||
|
random.shuffle(part)
|
||||||
|
part.insert(0, self.list[0])
|
||||||
|
self.list = part
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.list = []
|
self.list = []
|
||||||
|
@ -303,33 +287,90 @@ class VideoQueue:
|
||||||
def not_ready_videos(self, limit: typing.Optional[int] = None):
|
def not_ready_videos(self, limit: typing.Optional[int] = None):
|
||||||
"""Return the non-ready videos in the first limit positions of the queue."""
|
"""Return the non-ready videos in the first limit positions of the queue."""
|
||||||
video_list = []
|
video_list = []
|
||||||
# In single video repeat, the only video to be loaded is the one currently playing
|
for video in (self[:limit]):
|
||||||
if self.loop_mode == LoopMode.LOOP_SINGLE:
|
|
||||||
if self.now_playing is None or self.now_playing.is_ready:
|
|
||||||
return video_list
|
|
||||||
else:
|
|
||||||
video_list.append(self.now_playing)
|
|
||||||
return video_list
|
|
||||||
# In suggestion mode, preload the current video and the next suggested one
|
|
||||||
if self.loop_mode == LoopMode.FOLLOW_SUGGESTIONS:
|
|
||||||
video = self.now_playing
|
|
||||||
if video is None:
|
|
||||||
return video_list
|
|
||||||
video.get_suggestion()
|
|
||||||
if not video.is_ready:
|
|
||||||
video_list.append(video)
|
|
||||||
if not video.suggestion.is_ready:
|
|
||||||
video_list.append(video.suggestion)
|
|
||||||
return video_list
|
|
||||||
# In all other modes, the videos to be loaded are the current one plus the following ones
|
|
||||||
for video in (self.list[:limit] + ([self.now_playing] if self.now_playing else [])):
|
|
||||||
if not video.is_ready:
|
if not video.is_ready:
|
||||||
video_list.append(video)
|
video_list.append(video)
|
||||||
return video_list
|
return video_list
|
||||||
|
|
||||||
def __getitem__(self, index: int) -> Video:
|
async def async_not_ready_videos(self, limit: typing.Optional[int] = None):
|
||||||
"""Get an element from the list."""
|
"""Return the non-ready videos in the first limit positions of the queue."""
|
||||||
return self.list[index]
|
video_list = []
|
||||||
|
full_list = await loop.run_in_executor(executor, functools.partial(self.__getitem__, slice(None, limit, None)))
|
||||||
|
for video in full_list:
|
||||||
|
if not video.is_ready:
|
||||||
|
video_list.append(video)
|
||||||
|
return video_list
|
||||||
|
|
||||||
|
def __getitem__(self, index: typing.Union[int, slice]) -> typing.Union[Video, typing.Iterable]:
|
||||||
|
"""Get an enqueued element."""
|
||||||
|
if isinstance(index, int):
|
||||||
|
if self.loop_mode == LoopMode.NORMAL:
|
||||||
|
return self.list[index]
|
||||||
|
elif self.loop_mode == LoopMode.LOOP_QUEUE:
|
||||||
|
if len(self.list) == 0:
|
||||||
|
raise IndexError()
|
||||||
|
return self.list[index % len(self.list)]
|
||||||
|
elif self.loop_mode == LoopMode.LOOP_SINGLE:
|
||||||
|
if len(self.list) == 0:
|
||||||
|
raise IndexError()
|
||||||
|
return self.list[0]
|
||||||
|
elif self.loop_mode == LoopMode.FOLLOW_SUGGESTIONS:
|
||||||
|
counter = index
|
||||||
|
video = self.list[0]
|
||||||
|
while counter > 0:
|
||||||
|
video.get_suggestion()
|
||||||
|
video = video.suggestion
|
||||||
|
counter -= 1
|
||||||
|
return video
|
||||||
|
elif self.loop_mode == LoopMode.AUTO_SHUFFLE:
|
||||||
|
if index == 0:
|
||||||
|
return self.list[0]
|
||||||
|
elif index >= len(self.list):
|
||||||
|
raise IndexError()
|
||||||
|
number = random.randrange(1, len(self.list))
|
||||||
|
return self.list[number]
|
||||||
|
elif self.loop_mode == LoopMode.LOOPING_SHUFFLE:
|
||||||
|
if index == 0:
|
||||||
|
return self.list[0]
|
||||||
|
number = random.randrange(1, len(self.list))
|
||||||
|
return self.list[number]
|
||||||
|
else:
|
||||||
|
# FIXME: won't work properly in multiple cases, but should work fine enough for now
|
||||||
|
video_list = []
|
||||||
|
if self.loop_mode == LoopMode.FOLLOW_SUGGESTIONS:
|
||||||
|
try:
|
||||||
|
video = self.list[0]
|
||||||
|
except IndexError:
|
||||||
|
return video_list
|
||||||
|
while True:
|
||||||
|
if video is None:
|
||||||
|
break
|
||||||
|
video_list.append(video)
|
||||||
|
video = video.suggestion
|
||||||
|
else:
|
||||||
|
for i in range(len(self)):
|
||||||
|
video_list.append(self[i])
|
||||||
|
return video_list[index]
|
||||||
|
|
||||||
|
async def async_getitem(self, index):
|
||||||
|
return await loop.run_in_executor(executor, functools.partial(self.__getitem__, index))
|
||||||
|
|
||||||
|
def __delitem__(self, index: typing.Union[int, slice]):
|
||||||
|
if isinstance(index, int):
|
||||||
|
if self.loop_mode == LoopMode.LOOP_SINGLE:
|
||||||
|
pass
|
||||||
|
elif self.loop_mode == LoopMode.FOLLOW_SUGGESTIONS:
|
||||||
|
if index != 0:
|
||||||
|
raise errors.LoopModeError("Deleting suggested videos different than the current one is impossible.")
|
||||||
|
else:
|
||||||
|
video = self[0]
|
||||||
|
if video.suggestion is not None:
|
||||||
|
self.list.append(video.suggestion)
|
||||||
|
del self.list[0]
|
||||||
|
del self.list[index]
|
||||||
|
else:
|
||||||
|
for i in range(index.start, index.stop, index.step):
|
||||||
|
del self[i]
|
||||||
|
|
||||||
|
|
||||||
def escape(message: str):
|
def escape(message: str):
|
||||||
|
@ -758,7 +799,8 @@ class RoyalDiscordBot(discord.Client):
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
# Might have some problems with del
|
# Might have some problems with del
|
||||||
for index, video in enumerate(self.video_queue.not_ready_videos(self.max_videos_to_predownload)):
|
not_ready_videos = await self.video_queue.async_not_ready_videos(self.max_videos_to_predownload)
|
||||||
|
for index, video in enumerate(not_ready_videos):
|
||||||
try:
|
try:
|
||||||
with async_timeout.timeout(self.max_video_ready_time):
|
with async_timeout.timeout(self.max_video_ready_time):
|
||||||
await loop.run_in_executor(executor, video.ready_up)
|
await loop.run_in_executor(executor, video.ready_up)
|
||||||
|
@ -783,12 +825,22 @@ class RoyalDiscordBot(discord.Client):
|
||||||
})
|
})
|
||||||
self.sentry.captureException()
|
self.sentry.captureException()
|
||||||
logger.error(f"Uncaught video download error: {e}")
|
logger.error(f"Uncaught video download error: {e}")
|
||||||
await self.main_channel.send(f"⚠️ E' stato incontrato un errore durante il download di "
|
if self.video_queue.loop_mode == LoopMode.FOLLOW_SUGGESTIONS or \
|
||||||
f"{str(video)}, quindi è stato rimosso dalla coda.\n\n"
|
self.video_queue.loop_mode == LoopMode.LOOPING_SHUFFLE or \
|
||||||
f"```python\n"
|
self.video_queue.loop_mode == LoopMode.AUTO_SHUFFLE:
|
||||||
f"{str(e.args)}"
|
await self.main_channel.send(f"⚠️ E' stato incontrato un errore durante il download di "
|
||||||
f"```")
|
f"{str(video)}, quindi la coda è stata svuotata.\n\n"
|
||||||
del self.video_queue.list[index]
|
f"```python\n"
|
||||||
|
f"{str(e.args)}"
|
||||||
|
f"```")
|
||||||
|
self.video_queue.clear()
|
||||||
|
else:
|
||||||
|
await self.main_channel.send(f"⚠️ E' stato incontrato un errore durante il download di "
|
||||||
|
f"{str(video)}, quindi è stato rimosso dalla coda.\n\n"
|
||||||
|
f"```python\n"
|
||||||
|
f"{str(e.args)}"
|
||||||
|
f"```")
|
||||||
|
del self.video_queue[index]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
async def queue_play_next_video(self):
|
async def queue_play_next_video(self):
|
||||||
|
@ -799,39 +851,34 @@ class RoyalDiscordBot(discord.Client):
|
||||||
# Do not add play videos if something else is playing!
|
# Do not add play videos if something else is playing!
|
||||||
if not voice_client.is_connected():
|
if not voice_client.is_connected():
|
||||||
continue
|
continue
|
||||||
if voice_client.is_playing():
|
# Find the "now_playing" video
|
||||||
|
try:
|
||||||
|
current_video = await self.video_queue.async_getitem(0)
|
||||||
|
except IndexError:
|
||||||
continue
|
continue
|
||||||
if voice_client.is_paused():
|
|
||||||
continue
|
|
||||||
# Ensure the next video is ready
|
|
||||||
next_video = self.video_queue.next_video()
|
|
||||||
if next_video is None or not next_video.is_ready:
|
|
||||||
continue
|
|
||||||
# Advance the queue
|
|
||||||
self.video_queue.advance_queue()
|
|
||||||
# Try to generate an AudioSource
|
# Try to generate an AudioSource
|
||||||
if self.video_queue.now_playing is None:
|
try:
|
||||||
|
audio_source = current_video.make_audio_source()
|
||||||
|
except errors.VideoIsNotReady:
|
||||||
continue
|
continue
|
||||||
audio_source = self.video_queue.now_playing.make_audio_source()
|
|
||||||
# Start playing the AudioSource
|
# Start playing the AudioSource
|
||||||
logger.info(f"Started playing {self.video_queue.now_playing.plain_text()}.")
|
logger.info(f"Started playing {current_video.plain_text()}.")
|
||||||
voice_client.play(audio_source)
|
voice_client.play(audio_source)
|
||||||
# Update the voice_client activity
|
# Update the voice_client activity
|
||||||
activity = discord.Activity(name=self.video_queue.now_playing.plain_text(),
|
activity = discord.Activity(name=current_video.plain_text(),
|
||||||
type=discord.ActivityType.listening)
|
type=discord.ActivityType.listening)
|
||||||
logger.debug("Updating bot presence...")
|
logger.debug("Updating bot presence...")
|
||||||
await self.change_presence(status=discord.Status.online, activity=activity)
|
await self.change_presence(status=discord.Status.online, activity=activity)
|
||||||
# Record the played song in the database
|
# Record the played song in the database
|
||||||
if self.video_queue.now_playing.enqueuer is not None:
|
if current_video.enqueuer is not None:
|
||||||
logger.debug(f"Adding {self.video_queue.now_playing.plain_text()} to db.PlayedMusic...")
|
logger.debug(f"Adding {current_video.plain_text()} to db.PlayedMusic...")
|
||||||
try:
|
try:
|
||||||
session = db.Session()
|
session = db.Session()
|
||||||
enqueuer = await loop.run_in_executor(executor, session.query(db.Discord)
|
enqueuer = await loop.run_in_executor(executor, session.query(db.Discord)
|
||||||
.filter_by(
|
.filter_by(discord_id=current_video.enqueuer.id)
|
||||||
discord_id=self.video_queue.now_playing.enqueuer.id)
|
|
||||||
.one_or_none)
|
.one_or_none)
|
||||||
played_music = db.PlayedMusic(enqueuer=enqueuer,
|
played_music = db.PlayedMusic(enqueuer=enqueuer,
|
||||||
filename=self.video_queue.now_playing.database_text(),
|
filename=current_video.database_text(),
|
||||||
timestamp=datetime.datetime.now())
|
timestamp=datetime.datetime.now())
|
||||||
session.add(played_music)
|
session.add(played_music)
|
||||||
await loop.run_in_executor(executor, session.commit)
|
await loop.run_in_executor(executor, session.commit)
|
||||||
|
@ -840,13 +887,17 @@ class RoyalDiscordBot(discord.Client):
|
||||||
pass
|
pass
|
||||||
# Send a message in chat
|
# Send a message in chat
|
||||||
for key in self.song_text_easter_eggs:
|
for key in self.song_text_easter_eggs:
|
||||||
if key in self.video_queue.now_playing.name.lower():
|
if key in current_video.name.lower():
|
||||||
await self.main_channel.send(
|
await self.main_channel.send(
|
||||||
self.song_text_easter_eggs[key].format(song=str(self.video_queue.now_playing)))
|
self.song_text_easter_eggs[key].format(song=str(current_video)))
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
await self.main_channel.send(
|
await self.main_channel.send(
|
||||||
f":arrow_forward: Ora in riproduzione: {str(self.video_queue.now_playing)}")
|
f":arrow_forward: Ora in riproduzione: {str(current_video)}")
|
||||||
|
# Wait until the song is finished
|
||||||
|
while voice_client.is_playing() or voice_client.is_paused():
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
self.video_queue.advance_queue()
|
||||||
|
|
||||||
async def inactivity_countdown(self):
|
async def inactivity_countdown(self):
|
||||||
while True:
|
while True:
|
||||||
|
@ -1063,7 +1114,7 @@ class RoyalDiscordBot(discord.Client):
|
||||||
await channel.send("⚠️ Il numero inserito non corrisponde a nessun video nella playlist.\n"
|
await channel.send("⚠️ Il numero inserito non corrisponde a nessun video nella playlist.\n"
|
||||||
"Sintassi: `!remove [numerovideoiniziale] [numerovideofinale]`")
|
"Sintassi: `!remove [numerovideoiniziale] [numerovideofinale]`")
|
||||||
return
|
return
|
||||||
video = self.video_queue.list.pop(index)
|
video = self.video_queue.pop(index)
|
||||||
await channel.send(f":regional_indicator_x: {str(video)} è stato rimosso dalla coda.")
|
await channel.send(f":regional_indicator_x: {str(video)} è stato rimosso dalla coda.")
|
||||||
logger.debug(f"Removed from queue: {video.plain_text()}")
|
logger.debug(f"Removed from queue: {video.plain_text()}")
|
||||||
return
|
return
|
||||||
|
@ -1093,7 +1144,7 @@ class RoyalDiscordBot(discord.Client):
|
||||||
await channel.send("⚠️ Il numero iniziale è maggiore del numero finale.\n"
|
await channel.send("⚠️ Il numero iniziale è maggiore del numero finale.\n"
|
||||||
"Sintassi: `!remove [numerovideoiniziale] [numerovideofinale]`")
|
"Sintassi: `!remove [numerovideoiniziale] [numerovideofinale]`")
|
||||||
return
|
return
|
||||||
del self.video_queue.list[start:end]
|
del self.video_queue[start:end]
|
||||||
await channel.send(f":regional_indicator_x: {end - start} video rimossi dalla coda.")
|
await channel.send(f":regional_indicator_x: {end - start} video rimossi dalla coda.")
|
||||||
logger.debug(f"Removed from queue {end - start} videos.")
|
logger.debug(f"Removed from queue {end - start} videos.")
|
||||||
|
|
||||||
|
@ -1114,53 +1165,14 @@ class RoyalDiscordBot(discord.Client):
|
||||||
elif self.video_queue.loop_mode == LoopMode.LOOPING_SHUFFLE:
|
elif self.video_queue.loop_mode == LoopMode.LOOPING_SHUFFLE:
|
||||||
msg += "Modalità attuale: :arrows_counterclockwise: **Video casuali infiniti dalla coda**\n"
|
msg += "Modalità attuale: :arrows_counterclockwise: **Video casuali infiniti dalla coda**\n"
|
||||||
msg += "**Video in coda:**\n"
|
msg += "**Video in coda:**\n"
|
||||||
if self.video_queue.now_playing is None:
|
if len(self.video_queue) == 0:
|
||||||
msg += ":cloud: _nessuno_\n"
|
msg += ":cloud: _nessuno_\n"
|
||||||
else:
|
for index in range(11):
|
||||||
msg += f":arrow_forward: {str(self.video_queue.now_playing)}\n"
|
try:
|
||||||
if self.video_queue.loop_mode == LoopMode.NORMAL:
|
video = await self.video_queue.async_getitem(index)
|
||||||
for index, video in enumerate(self.video_queue.list[:10]):
|
except IndexError:
|
||||||
msg += f"{number_emojis[index]} {str(video)}\n"
|
break
|
||||||
if len(self.video_queue) > 10:
|
msg += f"{number_emojis[index]} {str(video)}\n"
|
||||||
msg += f"più altri {len(self.video_queue) - 10} video!"
|
|
||||||
elif self.video_queue.loop_mode == LoopMode.LOOP_QUEUE:
|
|
||||||
for index, video in enumerate(self.video_queue.list[:10]):
|
|
||||||
msg += f"{number_emojis[index]} {str(video)}\n"
|
|
||||||
if len(self.video_queue) > 10:
|
|
||||||
msg += f"più altri {len(self.video_queue) - 10} video che si ripetono!"
|
|
||||||
else:
|
|
||||||
if len(self.video_queue) < 6:
|
|
||||||
count = len(self.video_queue)
|
|
||||||
while count < 10:
|
|
||||||
for index, video in enumerate(self.video_queue.list[:10]):
|
|
||||||
msg += f":asterisk: {str(video)}\n"
|
|
||||||
count += len(self.video_queue)
|
|
||||||
msg += "e avanti così!"
|
|
||||||
elif self.video_queue.loop_mode == LoopMode.LOOP_SINGLE:
|
|
||||||
video = self.video_queue.now_playing
|
|
||||||
for index in range(9):
|
|
||||||
msg += f":asterisk: {str(video)}\n"
|
|
||||||
msg += "all'infinito!"
|
|
||||||
elif self.video_queue.loop_mode == LoopMode.FOLLOW_SUGGESTIONS:
|
|
||||||
msg += "e i prossimi video suggeriti!"
|
|
||||||
elif self.video_queue.loop_mode == LoopMode.AUTO_SHUFFLE:
|
|
||||||
for index, video in enumerate(self.video_queue.list[:10]):
|
|
||||||
msg += f":hash: {str(video)}\n"
|
|
||||||
if len(self.video_queue) > 10:
|
|
||||||
msg += f"più altri {len(self.video_queue) - 10} video!"
|
|
||||||
elif self.video_queue.loop_mode == LoopMode.LOOPING_SHUFFLE:
|
|
||||||
for index, video in enumerate(self.video_queue.list[:10]):
|
|
||||||
msg += f":hash: {str(video)}\n"
|
|
||||||
if len(self.video_queue) > 10:
|
|
||||||
msg += f"più altri {len(self.video_queue) - 10} video che si ripetono!"
|
|
||||||
else:
|
|
||||||
if len(self.video_queue) < 6:
|
|
||||||
count = len(self.video_queue)
|
|
||||||
while count < 10:
|
|
||||||
for index, video in enumerate(self.video_queue.list[:10]):
|
|
||||||
msg += f":asterisk: {str(video)}\n"
|
|
||||||
count += len(self.video_queue)
|
|
||||||
msg += "a ripetizione casuale!"
|
|
||||||
await channel.send(msg)
|
await channel.send(msg)
|
||||||
|
|
||||||
# noinspection PyUnusedLocal
|
# noinspection PyUnusedLocal
|
||||||
|
|
|
@ -56,3 +56,7 @@ class PastDateError(Exception):
|
||||||
|
|
||||||
class MissingAPIKeyError(Exception):
|
class MissingAPIKeyError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class LoopModeError(Exception):
|
||||||
|
pass
|
Loading…
Reference in a new issue