1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00

WIP: new queue2

This commit is contained in:
Steffo 2018-11-28 15:44:34 +00:00
parent cabc517861
commit 6fbc9898dd

View file

@ -159,9 +159,15 @@ class Video:
self.info = info self.info = info
# Who added the video to the queue? # Who added the video to the queue?
self.enqueuer = enqueuer self.enqueuer = enqueuer
# How long is the video? # How long and what title has the video?
if info is not None: if info is not None:
self.duration = info.get("duration") self.duration = info.get("duration")
self.title = info.get("title")
else:
self.duration = None
self.title = None
# No audio source exists yet
self.audio_source = None
def __str__(self): def __str__(self):
"""Format the title to be used on Discord using Markdown.""" """Format the title to be used on Discord using Markdown."""
@ -205,11 +211,56 @@ class Video:
logger.info(f"Download complete: {repr(self)}") logger.info(f"Download complete: {repr(self)}")
self.downloaded = True self.downloaded = True
def create_audio_source(self) -> discord.PCMVolumeTransformer: def load(self) -> None:
# Check if the file has been downloaded # Check if the file has been downloaded
if not self.downloaded: if not self.downloaded:
raise errors.FileNotDownloadedError() raise errors.FileNotDownloadedError()
return discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(f"{self.file}", **ffmpeg_settings)) self.audio_source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(f"{self.file}", **ffmpeg_settings))
class VideoQueue():
"""The queue of videos to be played."""
def __init__(self):
self.list: typing.List[Video] = []
self.now_playing: typing.Optional[Video] = None
def __len__(self) -> int:
return len(self.list)
def add(self, video: Video, position: int=None) -> None:
if position is None:
self.list.append(video)
return
self.list.insert(position, video)
def next_video(self) -> typing.Optional[Video]:
if len(self.list) == 0:
return None
return self.list[0]
def shuffle(self):
random.shuffle(self.list)
def clear(self):
self.list = None
self.now_playing = None
def forward(self) -> None:
self.now_playing = self.list.pop(0)
def find_video(self, title: str) -> typing.Optional[Video]:
"""Returns the first video with a certain title (or filename)."""
for video in self.list:
if title in video.title:
return video
elif title in video.file:
return video
return None
def __getitem__(self, index: int) -> Video:
"""Get an element from the list."""
return self.list[index]
class SecretVideo(Video): class SecretVideo(Video):
@ -341,8 +392,7 @@ class RoyalDiscordBot(discord.Client):
"!pause": self.cmd_pause, "!pause": self.cmd_pause,
"!resume": self.cmd_resume "!resume": self.cmd_resume
} }
self.video_queue: typing.List[Video] = [] self.video_queue: VideoQueue = VideoQueue()
self.now_playing: typing.Optional[Video] = None
self.load_config("config.ini") self.load_config("config.ini")
self.inactivity_timer = 0 self.inactivity_timer = 0
@ -550,7 +600,7 @@ class RoyalDiscordBot(discord.Client):
async def queue_predownload_videos(self): async def queue_predownload_videos(self):
while True: while True:
for index, video in enumerate(self.video_queue[:(None if self.max_videos_to_predownload == math.inf else self.max_videos_to_predownload].copy()): for index, video in enumerate(self.video_queue.list[:(None if self.max_videos_to_predownload == math.inf else self.max_videos_to_predownload].copy()):
if video.downloaded: if video.downloaded:
continue continue
try: try:
@ -562,13 +612,13 @@ class RoyalDiscordBot(discord.Client):
await self.main_channel.send(f"⚠️ Il download di {str(video)} ha richiesto più di" await self.main_channel.send(f"⚠️ Il download di {str(video)} ha richiesto più di"
f" {config['YouTube']['download_timeout']} secondi, pertanto è stato" f" {config['YouTube']['download_timeout']} secondi, pertanto è stato"
f" rimosso dalla coda.") f" rimosso dalla coda.")
del self.video_queue[index] del self.video_queue.list[index]
continue continue
except DurationError: except DurationError:
await self.main_channel.send(f"⚠️ {str(video)} dura più di" await self.main_channel.send(f"⚠️ {str(video)} dura più di"
f" {self.max_duration // 60}" f" {self.max_duration // 60}"
f" minuti, quindi è stato rimosso dalla coda.") f" minuti, quindi è stato rimosso dalla coda.")
del self.video_queue[index] del self.video_queue.list[index]
continue continue
except Exception as e: except Exception as e:
sentry.user_context({ sentry.user_context({
@ -589,53 +639,15 @@ class RoyalDiscordBot(discord.Client):
f"```python\n" f"```python\n"
f"{str(e)}" f"{str(e)}"
f"```") f"```")
del self.video_queue[index] del self.video_queue.list[index]
continue continue
await asyncio.sleep(1) await asyncio.sleep(1)
async def queue_play_next_video(self): async def queue_play_next_video(self):
await self.wait_until_ready() await self.wait_until_ready()
while True: while True:
# Fun things will happen with multiple voice clients! # TODO
for voice_client in self.voice_clients: raise NotImplementedError("queue_play_next_video isn't done yet!")
if not voice_client.is_connected() or voice_client.is_playing() or voice_client.is_paused():
continue
if len(self.video_queue) == 0:
self.now_playing = None
continue
now_playing = self.video_queue[0]
try:
audio_source = now_playing.create_audio_source()
except errors.FileNotDownloadedError:
continue
logger.info(f"Started playing {repr(now_playing)}.")
voice_client.play(audio_source)
del self.video_queue[0]
activity = discord.Activity(name=now_playing.plain_text(),
type=discord.ActivityType.listening)
logger.debug(f"Updated bot presence to {now_playing.plain_text()}.")
await self.change_presence(status=discord.Status.online, activity=activity)
if now_playing.enqueuer is not None:
try:
session = db.Session()
enqueuer = await loop.run_in_executor(executor, session.query(db.Discord)
.filter_by(discord_id=now_playing.enqueuer.id)
.one_or_none)
played_music = db.PlayedMusic(enqueuer=enqueuer,
filename=now_playing.plain_text(),
timestamp=datetime.datetime.now())
session.add(played_music)
await loop.run_in_executor(executor, session.commit)
await loop.run_in_executor(executor, session.close)
except sqlalchemy.exc.OperationalError:
pass
for key in song_special_messages:
if key in now_playing.file.lower():
await self.main_channel.send(song_special_messages[key].format(song=str(now_playing)))
break
else:
await self.main_channel.send(f":arrow_forward: Ora in riproduzione: {str(now_playing)}")
await asyncio.sleep(1)
async def inactivity_countdown(self): async def inactivity_countdown(self):
while True: while True:
@ -709,22 +721,13 @@ class RoyalDiscordBot(discord.Client):
if "entries" in info: if "entries" in info:
logger.debug(f"Playlist detected at {url}.") logger.debug(f"Playlist detected at {url}.")
for entry in info["entries"]: for entry in info["entries"]:
if index is not None: self.video_queue.add(Video(url=entry["webpage_url"], info=entry, enqueuer=enqueuer), index)
self.video_queue.insert(index, Video(url=entry["webpage_url"], info=entry, enqueuer=enqueuer))
else:
self.video_queue.append(Video(url=entry["webpage_url"], info=entry, enqueuer=enqueuer))
return return
logger.debug(f"Single video detected at {url}.") logger.debug(f"Single video detected at {url}.")
if index is not None: self.video_queue.add(Video(url=entry["webpage_url"], info=entry, enqueuer=enqueuer), index)
self.video_queue.insert(index, Video(url=url, info=info, enqueuer=enqueuer))
else:
self.video_queue.append(Video(url=url, info=info, enqueuer=enqueuer))
async def add_video_from_file(self, file, index: typing.Optional[int] = None, enqueuer: discord.Member = None): async def add_video_from_file(self, file, index: typing.Optional[int] = None, enqueuer: discord.Member = None):
if index is not None: self.video_queue.add(Video(file=file, enqueuer=enqueuer), index)
self.video_queue.insert(index, Video(file=file, enqueuer=enqueuer))
else:
self.video_queue.append(Video(file=file, enqueuer=enqueuer))
@command @command
async def null(self, channel: discord.TextChannel, author: discord.Member, params: typing.List[str]): async def null(self, channel: discord.TextChannel, author: discord.Member, params: typing.List[str]):
@ -865,7 +868,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.pop(index) video = self.video_queue.list.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
@ -895,7 +898,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[start:end] del self.video_queue.list[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.")
@ -906,7 +909,7 @@ class RoyalDiscordBot(discord.Client):
"nessuno") "nessuno")
return return
msg = "**Video in coda:**\n" msg = "**Video in coda:**\n"
for index, video in enumerate(self.video_queue[:10]): for index, video in enumerate(self.video_queue.list[:10]):
msg += f"{queue_emojis[index]} {str(video)}\n" msg += f"{queue_emojis[index]} {str(video)}\n"
if len(self.video_queue) > 10: if len(self.video_queue) > 10:
msg += f"più altri {len(self.video_queue) - 10} video!" msg += f"più altri {len(self.video_queue) - 10} video!"
@ -918,7 +921,7 @@ class RoyalDiscordBot(discord.Client):
if len(self.video_queue) == 0: if len(self.video_queue) == 0:
await channel.send("⚠ Non ci sono video in coda!") await channel.send("⚠ Non ci sono video in coda!")
return return
random.shuffle(self.video_queue) random.shuffle(self.video_queue.list)
logger.info(f"The queue was shuffled by {author.name}#{author.discriminator}.") logger.info(f"The queue was shuffled by {author.name}#{author.discriminator}.")
await channel.send("♠️ ♦️ ♣️ ♥️ Shuffle completo!") await channel.send("♠️ ♦️ ♣️ ♥️ Shuffle completo!")
@ -928,7 +931,8 @@ class RoyalDiscordBot(discord.Client):
if len(self.video_queue) == 0: if len(self.video_queue) == 0:
await channel.send("⚠ Non ci sono video in coda!") await channel.send("⚠ Non ci sono video in coda!")
return return
self.video_queue = [] # TODO
raise NotImplementedError()
logger.info(f"The queue was cleared by {author.name}#{author.discriminator}.") logger.info(f"The queue was cleared by {author.name}#{author.discriminator}.")
await channel.send(":regional_indicator_x: Tutti i video in coda rimossi.") await channel.send(":regional_indicator_x: Tutti i video in coda rimossi.")