Compare commits
13 Commits
b6d105a519
...
main
Author | SHA1 | Date | |
---|---|---|---|
019e60450f
|
|||
7672107c68
|
|||
ee6ea4eed4
|
|||
fed280e6c5
|
|||
1a8f84b333
|
|||
94bdb91eb0
|
|||
5c030a0557
|
|||
5344e89c26
|
|||
80e6d422e5
|
|||
71fad98d3d
|
|||
83d784c917
|
|||
f4b7e0f5ce | |||
1316fb593c
|
@@ -21,8 +21,11 @@ class Song:
|
|||||||
format_duration(self.player.duration) if self.player.duration else "stream"
|
format_duration(self.player.duration) if self.player.duration else "stream"
|
||||||
)
|
)
|
||||||
if multiline:
|
if multiline:
|
||||||
|
queue_time = (
|
||||||
|
self.trigger_message.edited_at or self.trigger_message.created_at
|
||||||
|
)
|
||||||
return f"{title}\n**duration:** {duration}" + (
|
return f"{title}\n**duration:** {duration}" + (
|
||||||
f", **queued by:** <@{self.trigger_message.author.id}>"
|
f", **queued by:** <@{self.trigger_message.author.id}> <t:{round(queue_time.timestamp())}:R>"
|
||||||
if show_queuer
|
if show_queuer
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
@@ -48,18 +51,20 @@ class Song:
|
|||||||
else "[**stream**]"
|
else "[**stream**]"
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
timestamp=self.trigger_message.edited_at or self.trigger_message.created_at,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
uploader_value = None
|
||||||
if self.player.uploader_url:
|
if self.player.uploader_url:
|
||||||
embed.add_field(
|
if self.player.uploader:
|
||||||
name="Uploader",
|
uploader_value = f"[{self.player.uploader}]({self.player.uploader_url})"
|
||||||
value=f"[{self.player.uploader}]({self.player.uploader_url})",
|
else:
|
||||||
)
|
uploader_value = self.player.uploader_url
|
||||||
elif self.player.uploader:
|
elif self.player.uploader:
|
||||||
embed.add_field(
|
uploader_value = self.player.uploader
|
||||||
name="Uploader",
|
|
||||||
value=self.player.uploader,
|
if uploader_value:
|
||||||
)
|
embed.add_field(name="Uploader", value=uploader_value)
|
||||||
if self.player.like_count:
|
if self.player.like_count:
|
||||||
embed.add_field(name="Likes", value=f"{self.player.like_count:,}")
|
embed.add_field(name="Likes", value=f"{self.player.like_count:,}")
|
||||||
if self.player.view_count:
|
if self.player.view_count:
|
||||||
@@ -73,7 +78,7 @@ class Song:
|
|||||||
embed.set_image(self.player.thumbnail_url)
|
embed.set_image(self.player.thumbnail_url)
|
||||||
|
|
||||||
embed.set_footer(
|
embed.set_footer(
|
||||||
text=f"queued by {self.trigger_message.author.name}",
|
text=f"Queued by {self.trigger_message.author.name}",
|
||||||
icon_url=(
|
icon_url=(
|
||||||
self.trigger_message.author.avatar.url
|
self.trigger_message.author.avatar.url
|
||||||
if self.trigger_message.author.avatar
|
if self.trigger_message.author.avatar
|
||||||
|
@@ -165,7 +165,7 @@ async def clear(message):
|
|||||||
tokens = commands.tokenize(message.content)
|
tokens = commands.tokenize(message.content)
|
||||||
parser = arguments.ArgumentParser(
|
parser = arguments.ArgumentParser(
|
||||||
tokens[0],
|
tokens[0],
|
||||||
"bulk delete messages in the current channel matching certain criteria",
|
"bulk delete messages in the current channel matching specified criteria",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"count",
|
"count",
|
||||||
|
@@ -90,13 +90,13 @@ async def pause(message):
|
|||||||
|
|
||||||
async def fast_forward(message):
|
async def fast_forward(message):
|
||||||
tokens = commands.tokenize(message.content)
|
tokens = commands.tokenize(message.content)
|
||||||
parser = arguments.ArgumentParser(tokens[0], "skip current sponsorblock segment")
|
parser = arguments.ArgumentParser(tokens[0], "skip the current sponsorblock segment")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-s",
|
"-s",
|
||||||
"--seconds",
|
"--seconds",
|
||||||
nargs="?",
|
nargs="?",
|
||||||
type=lambda v: arguments.range_type(v, lower=0, upper=300),
|
type=lambda v: arguments.range_type(v, lower=0, upper=300),
|
||||||
help="the amount of seconds to fast forward instead",
|
help="the number of seconds to fast forward instead",
|
||||||
)
|
)
|
||||||
if not (args := await parser.parse_args(message, tokens)):
|
if not (args := await parser.parse_args(message, tokens)):
|
||||||
return
|
return
|
||||||
|
@@ -8,16 +8,13 @@ import audio
|
|||||||
import commands
|
import commands
|
||||||
import utils
|
import utils
|
||||||
from constants import EMBED_COLOR
|
from constants import EMBED_COLOR
|
||||||
from state import client, players
|
from state import client, players, trusted_users
|
||||||
|
|
||||||
from .playback import resume
|
from .playback import resume
|
||||||
from .utils import command_allowed, ensure_joined, play_next
|
from .utils import command_allowed, ensure_joined, play_next
|
||||||
|
|
||||||
|
|
||||||
async def queue_or_play(message, edited=False):
|
async def queue_or_play(message, edited=False):
|
||||||
if message.guild.id not in players:
|
|
||||||
players[message.guild.id] = audio.queue.Player()
|
|
||||||
|
|
||||||
tokens = commands.tokenize(message.content)
|
tokens = commands.tokenize(message.content)
|
||||||
parser = arguments.ArgumentParser(
|
parser = arguments.ArgumentParser(
|
||||||
tokens[0],
|
tokens[0],
|
||||||
@@ -81,19 +78,23 @@ async def queue_or_play(message, edited=False):
|
|||||||
elif not command_allowed(message):
|
elif not command_allowed(message):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if message.guild.id not in players:
|
||||||
|
players[message.guild.id] = audio.queue.Player()
|
||||||
|
|
||||||
if edited:
|
if edited:
|
||||||
found = None
|
found = next(
|
||||||
for queued in players[message.guild.id].queue:
|
filter(
|
||||||
if queued.trigger_message.id == message.id:
|
lambda queued: queued.trigger_message.id == message.id,
|
||||||
found = queued
|
players[message.guild.id].queue,
|
||||||
break
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
if found:
|
if found:
|
||||||
players[message.guild.id].queue.remove(found)
|
players[message.guild.id].queue.remove(found)
|
||||||
|
|
||||||
if args.clear:
|
if args.clear:
|
||||||
players[message.guild.id].queue.clear()
|
players[message.guild.id].queue.clear()
|
||||||
await utils.add_check_reaction(message)
|
await utils.add_check_reaction(message)
|
||||||
return
|
|
||||||
elif indices := args.remove_index:
|
elif indices := args.remove_index:
|
||||||
targets = []
|
targets = []
|
||||||
for i in indices:
|
for i in indices:
|
||||||
@@ -114,15 +115,15 @@ async def queue_or_play(message, edited=False):
|
|||||||
f"removed **{len(targets)}** queued {'song' if len(targets) == 1 else 'songs'}",
|
f"removed **{len(targets)}** queued {'song' if len(targets) == 1 else 'songs'}",
|
||||||
)
|
)
|
||||||
elif args.remove_title or args.remove_queuer:
|
elif args.remove_title or args.remove_queuer:
|
||||||
targets = []
|
targets = set()
|
||||||
for queued in players[message.guild.id].queue:
|
for queued in players[message.guild.id].queue:
|
||||||
if t := args.remove_title:
|
if t := args.remove_title:
|
||||||
if t in queued.player.title:
|
if t in queued.player.title:
|
||||||
targets.append(queued)
|
targets.add(queued)
|
||||||
continue
|
|
||||||
if q := args.remove_queuer:
|
if q := args.remove_queuer:
|
||||||
if q == queued.trigger_message.author.id:
|
if q == queued.trigger_message.author.id:
|
||||||
targets.append(queued)
|
targets.add(queued)
|
||||||
|
targets = list(targets)
|
||||||
if not args.match_multiple:
|
if not args.match_multiple:
|
||||||
targets = targets[:1]
|
targets = targets[:1]
|
||||||
|
|
||||||
@@ -146,6 +147,7 @@ async def queue_or_play(message, edited=False):
|
|||||||
)
|
)
|
||||||
>= 5
|
>= 5
|
||||||
and not len(message.guild.voice_client.channel.members) == 2
|
and not len(message.guild.voice_client.channel.members) == 2
|
||||||
|
and message.author.id not in trusted_users
|
||||||
):
|
):
|
||||||
await utils.reply(
|
await utils.reply(
|
||||||
message,
|
message,
|
||||||
@@ -239,7 +241,7 @@ async def queue_or_play(message, edited=False):
|
|||||||
|
|
||||||
async def skip(message):
|
async def skip(message):
|
||||||
tokens = commands.tokenize(message.content)
|
tokens = commands.tokenize(message.content)
|
||||||
parser = arguments.ArgumentParser(tokens[0], "skip the currently playing song")
|
parser = arguments.ArgumentParser(tokens[0], "skip the song currently playing")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-n",
|
"-n",
|
||||||
"--next",
|
"--next",
|
||||||
|
27
core.py
27
core.py
@@ -3,6 +3,7 @@ import contextlib
|
|||||||
import importlib
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
import io
|
import io
|
||||||
|
import signal
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
@@ -59,17 +60,8 @@ async def on_message(message, edited=False):
|
|||||||
|
|
||||||
match matched:
|
match matched:
|
||||||
case C.RELOAD if message.author.id in OWNERS:
|
case C.RELOAD if message.author.id in OWNERS:
|
||||||
reloaded_modules = set()
|
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
reloaded_modules = reload()
|
||||||
rreload(reloaded_modules, __import__("core"))
|
|
||||||
rreload(reloaded_modules, __import__("extra"))
|
|
||||||
for module in filter(
|
|
||||||
lambda v: inspect.ismodule(v) and v.__name__ in RELOADABLE_MODULES,
|
|
||||||
globals().values(),
|
|
||||||
):
|
|
||||||
rreload(reloaded_modules, module)
|
|
||||||
|
|
||||||
end = time.time()
|
end = time.time()
|
||||||
debug(
|
debug(
|
||||||
f"reloaded {len(reloaded_modules)} modules in {round(end - start, 2)}s",
|
f"reloaded {len(reloaded_modules)} modules in {round(end - start, 2)}s",
|
||||||
@@ -186,3 +178,18 @@ def rreload(reloaded_modules, module):
|
|||||||
|
|
||||||
if "__reload_module__" in dir(module):
|
if "__reload_module__" in dir(module):
|
||||||
module.__reload_module__()
|
module.__reload_module__()
|
||||||
|
|
||||||
|
|
||||||
|
def reload(*_):
|
||||||
|
reloaded_modules = set()
|
||||||
|
rreload(reloaded_modules, __import__("core"))
|
||||||
|
rreload(reloaded_modules, __import__("extra"))
|
||||||
|
for module in filter(
|
||||||
|
lambda v: inspect.ismodule(v) and v.__name__ in RELOADABLE_MODULES,
|
||||||
|
globals().values(),
|
||||||
|
):
|
||||||
|
rreload(reloaded_modules, module)
|
||||||
|
return reloaded_modules
|
||||||
|
|
||||||
|
|
||||||
|
signal.signal(signal.SIGUSR1, reload)
|
||||||
|
2
main.py
2
main.py
@@ -7,7 +7,7 @@ from state import client
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
format=(
|
format=(
|
||||||
"%(asctime)s %(levelname)s %(name):%(module)s %(message)s"
|
"%(asctime)s %(levelname)s %(name)s:%(module)s %(message)s"
|
||||||
if __debug__
|
if __debug__
|
||||||
else "%(asctime)s %(levelname)s %(message)s"
|
else "%(asctime)s %(levelname)s %(message)s"
|
||||||
),
|
),
|
||||||
|
@@ -5,4 +5,4 @@ disnake_paginator
|
|||||||
psutil
|
psutil
|
||||||
PyNaCl
|
PyNaCl
|
||||||
youtube_transcript_api
|
youtube_transcript_api
|
||||||
yt-dlp
|
yt-dlp[default] @ https://github.com/yt-dlp/yt-dlp/archive/master.tar.gz
|
||||||
|
3
state.py
3
state.py
@@ -15,5 +15,6 @@ idle_tracker = {"is_idle": False, "last_used": time.time()}
|
|||||||
kill = {"transcript": False}
|
kill = {"transcript": False}
|
||||||
message_responses = LimitedSizeDict()
|
message_responses = LimitedSizeDict()
|
||||||
players = {}
|
players = {}
|
||||||
sponsorblock_cache = LimitedSizeDict(size_limit=100)
|
sponsorblock_cache = LimitedSizeDict()
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
trusted_users = []
|
||||||
|
2
tasks.py
2
tasks.py
@@ -11,7 +11,7 @@ async def cleanup():
|
|||||||
debug("spawned cleanup thread")
|
debug("spawned cleanup thread")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(3600 * 12)
|
await asyncio.sleep(3600)
|
||||||
|
|
||||||
targets = []
|
targets = []
|
||||||
for guild_id, player in players.items():
|
for guild_id, player in players.items():
|
||||||
|
@@ -50,7 +50,7 @@ def filter_secrets(text: str, secrets=SECRETS) -> str:
|
|||||||
|
|
||||||
class LimitedSizeDict(OrderedDict):
|
class LimitedSizeDict(OrderedDict):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.size_limit = kwargs.pop("size_limit", 1000)
|
self.size_limit = kwargs.pop("size_limit", 100)
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self._check_size_limit()
|
self._check_size_limit()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user