Update 'cogs/music.py'

This commit is contained in:
a 2023-03-27 00:43:27 +00:00
parent bb26a223b1
commit 2352c101bc

View file

@ -3,8 +3,7 @@ from discord.ext.commands import Cog, command, Context
from discord.ext.pages import Paginator from discord.ext.pages import Paginator
import asyncio # used to run async functions within regular functions import asyncio # used to run async functions within regular functions
import subprocess # for running ffprobe and getting duration of files import subprocess # for running ffprobe and getting duration of files
from os import path, makedirs from os import getenv, path, makedirs
from decouple import config
from time import time # performance tracking from time import time # performance tracking
import random # for shuffling the queue import random # for shuffling the queue
import math # for ceiling function in queue pages import math # for ceiling function in queue pages
@ -61,7 +60,7 @@ class Track:
self.data = data self.data = data
def __repr__(self): def __repr__(self):
return f"<Track {self.source=} {self.requester=} {self.title=} {self.duration=} {self.data=}" return f"<Track {self.source=} {self.requester=} {self.title=} {self.duration=}"
def __str__(self): def __str__(self):
title = f"**{self.title}**" if self.title else f"`{self.source}`" title = f"**{self.title}**" if self.title else f"`{self.source}`"
@ -105,7 +104,7 @@ class Player(discord.PCMVolumeTransformer):
return cls(data['url'], track.duration, data = data, ffmpeg_options = {"options": "-vn", "before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5"}) return cls(data['url'], track.duration, data = data, ffmpeg_options = {"options": "-vn", "before_options": "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5"})
def __repr__(self): def __repr__(self):
return ''.join([f"{key=}\n" for key in self.__dict__]) return ''.join([f"{key=}\n" for key in self.__dict__ if key != "data"])
def __str__(self): def __str__(self):
return ( return (
@ -145,11 +144,12 @@ class Music(Cog):
def __init__(self, bot: discord.Bot): def __init__(self, bot: discord.Bot):
self.bot: discord.Bot = bot self.bot: discord.Bot = bot
self.q: list[Track] = [] self.q: list[Track] = [] # queue
self.track: Track | None = None self.track: Track | None = None
self.repeat_mode = Music.REPEAT_NONE self.repeat_mode = Music.REPEAT_NONE
self.search_results: dict = None self.search_results: dict = None
self.i: int = -1 self.i: int = -1 # initial value used for repeat mode
self.h: list[Track] = [] # history
print("Initialized Music cog") print("Initialized Music cog")
@command(aliases=['start', 'summon', 'connect']) @command(aliases=['start', 'summon', 'connect'])
@ -254,7 +254,8 @@ class Music(Cog):
tracks = [] tracks = []
for entry in entries: for entry in entries:
source = entry["url"] source = entry["url"]
title = entry["title"] original_url = entry.get("original_url")
title = entry.get("title", "(no title)")
duration = None duration = None
data = entry data = entry
if not "duration" in data and not "duration_string" in data: if not "duration" in data and not "duration_string" in data:
@ -276,9 +277,9 @@ class Music(Cog):
tracks.append( tracks.append(
Track( Track(
source=source, source=source,
original_url=original_url,
requester=ctx.message.author, requester=ctx.message.author,
title=title, title=title,
original_url=url,
duration=duration, duration=duration,
data=data data=data
) )
@ -371,8 +372,8 @@ class Music(Cog):
for i, result in enumerate(self.search_results['entries']): for i, result in enumerate(self.search_results['entries']):
result: dict result: dict
if result.get('live_status') == "is_upcoming": if result['live_status'] == "is_upcoming":
continue # skip YT Premieres continue # skip YT Premieres
title = result.get('title', '<no title found>') title = result.get('title', '<no title found>')
@ -459,6 +460,7 @@ class Music(Cog):
player = await Player.prepare_file(self.track, loop = self.bot.loop) player = await Player.prepare_file(self.track, loop = self.bot.loop)
logger.info("playing Player on the voice client") logger.info("playing Player on the voice client")
self.h += [self.track]
ctx.voice_client.play( ctx.voice_client.play(
player, player,
after=lambda e: self.after(ctx) after=lambda e: self.after(ctx)
@ -628,7 +630,8 @@ class Music(Cog):
# check that there is a queue and a current track # check that there is a queue and a current track
if not self.q and not self.track: if not self.q and not self.track:
msg = await ctx.send("The queue is currently empty.") msg = await ctx.send("The queue is currently empty.")
logger.info("Message sent: The queue is currently empty.") if msg:
logger.info("Message sent: The queue is currently empty.")
return return
# paginate the queue to just one page # paginate the queue to just one page
full_queue = [self.track] + self.q full_queue = [self.track] + self.q
@ -652,6 +655,25 @@ class Music(Cog):
msg = await ctx.send(formatted_results) msg = await ctx.send(formatted_results)
if msg: if msg:
logger.info("Message sent: Sent queue page to channel") logger.info("Message sent: Sent queue page to channel")
@command(aliases=['h'])
async def history(self, ctx: Context, limit: int = 10):
"""Show recent actions"""
logger.info(f".history {limit}" if limit else ".history")
if not self.h:
msg = await ctx.send("No available history in this session.")
if msg:
logger.info("Message sent: No available history in this session.")
return
page = self.h[-limit:]
formatted_results = f"Last {len(page)} tracks played:\n"
for i, entry in enumerate(page):
formatted_results += (
f"{i - len(page)}: {entry}\n"
)
msg = await ctx.send(formatted_results)
if msg:
logger.info("Message sent: Sent history page to channel")
@command(aliases=['np']) @command(aliases=['np'])
async def nowplaying(self, ctx: Context): async def nowplaying(self, ctx: Context):
@ -709,7 +731,9 @@ class Music(Cog):
async def remove(self, ctx: Context, i: int): async def remove(self, ctx: Context, i: int):
"""Remove track at given position""" """Remove track at given position"""
logger.info(f".remove {i}") logger.info(f".remove {i}")
i -= 1 # convert to zero-indexing i -= 2 # convert to zero-indexing and also the np track is popped
logger.warning(f"trying to pop index {i}")
logger.warning(f"{self.q[i]=}")
track = self.q.pop(i) track = self.q.pop(i)
msg = await ctx.send(f"Removed: {track.title}") msg = await ctx.send(f"Removed: {track.title}")
if msg: if msg:
@ -781,6 +805,7 @@ class Music(Cog):
logger.info(".refresh") logger.info(".refresh")
self.q = [] self.q = []
self.track = [] self.track = []
self.h = []
msg = await ctx.send("Music bot has been refreshed") msg = await ctx.send("Music bot has been refreshed")
if msg: if msg:
logger.info("Message sent: Bot has been refreshed") logger.info("Message sent: Bot has been refreshed")
@ -837,6 +862,6 @@ ytdl_format_options = {
# "source_address": "0.0.0.0", # Bind to ipv4 since ipv6 addresses cause issues # "source_address": "0.0.0.0", # Bind to ipv4 since ipv6 addresses cause issues
"extract_flat": True, # massive speedup for fetching metadata, at the cost of no upload date "extract_flat": True, # massive speedup for fetching metadata, at the cost of no upload date
} }
# username = config("YOUTUBE_USERNAME") username = getenv("YOUTUBE_USERNAME")
# password = config("YOUTUBE_PASSWORD") password = getenv("YOUTUBE_PASSWORD")
ytdl = youtube_dl.YoutubeDL(ytdl_format_options) ytdl = youtube_dl.YoutubeDL(ytdl_format_options)