From 34e521a7e4248bda8adaf1ccca993c58b8b4c469 Mon Sep 17 00:00:00 2001 From: Azarath7 <158289825+Azarath7@users.noreply.github.com> Date: Wed, 31 Jan 2024 15:00:27 +0200 Subject: [PATCH] Add files via upload --- PLACEHOLDERS.md | 6 +- update.py | 2 +- voicelink/objects.py | 2 +- voicelink/placeholders.py | 247 +++++++++++++++++--------------------- voicelink/player.py | 4 +- 5 files changed, 115 insertions(+), 146 deletions(-) diff --git a/PLACEHOLDERS.md b/PLACEHOLDERS.md index f5e494d..10b5a99 100644 --- a/PLACEHOLDERS.md +++ b/PLACEHOLDERS.md @@ -14,7 +14,7 @@ Actions | Action Name | Description | | --- | --- | -| player | Playing status. | +| play | Playing status. | | listen | Listening status. | | watch | Watching status. | | stream | Streaming status. | @@ -59,6 +59,8 @@ Valuables | channel_name | The name of the channel the bot is playing on. | | track_name | The name of the track currently playing. | | track_url | The url of the track currently playing. | +| track_author | The name of the author of the track currently playing. | +| track_duration | The length of the track currently playing. | | track_thumbnail | The thumbnail of the track currently playing. | | requester | The mention name of the requester of the currently playing track. | | requester_name | The name of the requester of the currently playing track. | @@ -88,7 +90,7 @@ Change the value of `default_controller` in `settings.json`. "active": { "description": "**Now Playing: ```[@@track_name@@]```\nLink: [Click Me](@@track_url@@) | Requester: @@requester@@ | DJ: @@dj@@**", "footer": { - "text": "Queue Length: @@queue_length@@ | Duration: @@duration@@ | Volume: @@volume@@% {{loop_mode!=Off ?? | Repeat: @@loop_mode@@}}" + "text": "Queue Length: @@queue_length@@ | Duration: @@track_duration@@ | Volume: @@volume@@% {{loop_mode!=Off ?? | Repeat: @@loop_mode@@}}" }, "image": "@@track_thumbnail@@", "author": { diff --git a/update.py b/update.py index 2f93e5f..eee641d 100644 --- a/update.py +++ b/update.py @@ -2,7 +2,7 @@ import requests, zipfile, os, shutil, argparse from io import BytesIO ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) -__version__ = "v2.6.7" +__version__ = "v2.6.7b1" GITHUB_API_URL = "https://api.github.com/repos/ChocoMeow/Vocard/releases/latest" VOCARD_URL = "https://github.com/ChocoMeow/Vocard/archive/" diff --git a/voicelink/objects.py b/voicelink/objects.py index 3a36a36..8032fe9 100644 --- a/voicelink/objects.py +++ b/voicelink/objects.py @@ -85,7 +85,7 @@ class Track: self.artist_id: Optional[list] = info.get("artist_id") self.original: Optional[Track] = None if self.spotify else self - self._search_type: SearchType = SearchType.ytmsearch if self.spotify else search_type + self._search_type: SearchType = SearchType.ytsearch if self.spotify else search_type self.spotify_track: Track = spotify_track self.thumbnail: str = info.get("artworkUrl") diff --git a/voicelink/placeholders.py b/voicelink/placeholders.py index 73b5fac..11fed34 100644 --- a/voicelink/placeholders.py +++ b/voicelink/placeholders.py @@ -3,112 +3,89 @@ from __future__ import annotations import re import function as func -from discord import Embed +from discord import Embed, Client + from typing import TYPE_CHECKING if TYPE_CHECKING: from .player import Player + from .objects import Track + +def ensure_track(func) -> callable: + def wrapper(self: Placeholders, *args, **kwargs): + current = self.get_current() + if not current: + return "None" + return func(self, current, *args, **kwargs) + return wrapper class Placeholders: - def __init__(self, player: Player = None) -> None: - self.player = player + def __init__(self, bot: Client, player: Player = None) -> None: + self.bot: Client = bot + self.player: Player = player - if player: - self.variables = { - "channel_name": self.channel_name, - "track_name": self.track_name, - "track_url": self.track_url, - "track_thumbnail": self.track_thumbnail, - "requester": self.requester, - "requester_name": self.requester_name, - "requester_avatar": self.requester_avatar, - "duration": self.duration, - "queue_length": self.queue_length, - "volume": self.volume, - "dj": self.dj, - "loop_mode": self.loop_mode, - "default_embed_color": self.default_embed_color, - "bot_icon": self.bot_icon, - "server_invite_link": func.settings.invite_link, - "invite_link": f"https://discord.com/oauth2/authorize?client_id={self.player._bot.user.id}&permissions=2184260928&scope=bot%20applications.commands" - } - else: - self.variables = { - "channel_name": "Test Channel", - "track_name": "Test Track", - "track_url": "http://example.com", - "track_thumbnail": "https://i.imgur.com/dIFBwU7.png", - "requester": "<@12345678>", - "requester_name": "Test", - "requester_avatar": "https://i.imgur.com/dIFBwU7.png", - "duration": "00:00", - "queue_length": 0, - "volume": 100, - "dj": "<@12345678>", - "loop_mode": "Off", - "default_embed_color": self.default_embed_color, - "bot_icon": "https://i.imgur.com/dIFBwU7.png", - "server_invite_link": func.settings.invite_link, - "invite_link": f"https://discord.com/oauth2/authorize?client_id={func.tokens.client_id}&permissions=2184260928&scope=bot%20applications.commands" - } + self.variables = { + "channel_name": self.channel_name, + "track_name": self.track_name, + "track_url": self.track_url, + "track_author": self.track_author, + "track_duration": self.track_duration, + "track_thumbnail": self.track_thumbnail, + "requester": self.requester, + "requester_name": self.requester_name, + "requester_avatar": self.requester_avatar, + "queue_length": self.queue_length, + "volume": self.volume, + "dj": self.dj, + "loop_mode": self.loop_mode, + "default_embed_color": self.default_embed_color, + "bot_icon": self.bot_icon, + "server_invite_link": func.settings.invite_link, + "invite_link": f"https://discord.com/oauth2/authorize?client_id={self.bot.user.id}&permissions=2184260928&scope=bot%20applications.commands" + } + def get_current(self) -> Track: + return self.player.current if self.player else None + def channel_name(self) -> str: - if not self.player.channel: - return "None" - - return self.player.channel.name + return self.player.channel.name if self.player.channel else "None" + + @ensure_track + def track_name(self, track: Track) -> str: + return track.title - def track_name(self) -> str: - if self.player.current is None: - return "None" - - return self.player.current.title - - def track_url(self) -> str: - if self.player.current is None: - return "" - - return self.player.current.uri + @ensure_track + def track_url(self, track: Track) -> str: + return track.uri + + @ensure_track + def track_author(self, track: Track) -> str: + return track.author + @ensure_track + def track_duration(self, track: Track) -> str: + return self.player.get_msg("live") if track.is_stream else func.time(track.length) + + @ensure_track + def requester(self, track: Track) -> str: + return track.requester.mention if track.requester else self.bot.user.mention + + @ensure_track + def requester_name(self, track: Track) -> str: + return track.requester.name if track.requester else self.bot.user.name + + @ensure_track + def requester_avatar(self, track: Track) -> str: + return track.requester.display_avatar.url if track.requester else self.bot.user.display_avatar.url + def track_thumbnail(self) -> str: - if self.player.current is None: - return "" + if not self.player or not self.player.current: + return "https://i.imgur.com/dIFBwU7.png" return self.player.current.thumbnail or "https://cdn.discordapp.com/attachments/674788144931012638/823086668445384704/eq-dribbble.gif" - def requester(self) -> str: - if self.player.current is None: - return "None" - - if requester := self.player.current.requester: - return requester.mention - else: - return self.player._bot.user.mention - - def requester_name(self) -> str: - if self.player.current is None: - return "None" - - if requester := self.player.current.requester: - return requester.name - else: - return self.player._bot.user.name - - def requester_avatar(self) -> str: - if self.player.current is None: - return "None" - - if requester := self.player.current.requester: - return requester.display_avatar.url - else: - return self.player._bot.user.display_avatar.url - - def duration(self) -> str: - track = self.player.current - if not track: - return "None" - - return self.player.get_msg("live") if track.is_stream else func.time(track.length) + def queue_length(self) -> str: + return str(self.player.queue.count) if self.player else "0" def dj(self) -> str: if dj_id := self.player.settings.get("dj"): @@ -116,80 +93,70 @@ class Placeholders: return self.player.dj.mention - def queue_length(self) -> str: - return str(self.player.queue.count) - def volume(self) -> int: - return self.player.volume + return self.player.volume if self.player else 0 def loop_mode(self) -> str: - return self.player.queue.repeat + return self.player.queue.repeat if self.player else "Off" def default_embed_color(self) -> int: return func.settings.embed_color def bot_icon(self) -> str: - return self.player._bot.user.display_avatar.url + return self.bot.user.display_avatar.url if self.player else "https://i.imgur.com/dIFBwU7.png" - def check_callable(self, value): + def check_callable(self, value) -> str: return str(value()) if callable(value) else str(value) def evaluate_expression(self, s: str): - if not s.startswith("{{") or not s.endswith("}}"): + if not (s.startswith("{{") and s.endswith("}}")) or "?? " not in s: return s + inner = s[2:-2].strip() - if "?? " not in inner: - return s - if "//" in inner: - expr, rest = inner.split("?? ") - true_val, false_val = rest.split("//") - else: - expr, true_val = inner.split("?? ") - false_val = "" + parts = inner.split("?? ") + expr = parts[0] + rest = parts[1] if len(parts) > 1 else "" + true_val, false_val = rest.split("//") if "//" in rest else (rest, "") + if not expr.strip() or not true_val.strip(): return s - if "!=" in expr: - var_name, var_val = expr.split("!=") - if var_name.strip() in self.variables and self.check_callable(self.variables[var_name.strip()]) != var_val.strip(): - return true_val.strip() - else: - return false_val.strip() - elif "=" in expr: - var_name, var_val = expr.split("=") - if var_name.strip() in self.variables and self.check_callable(self.variables[var_name.strip()]) == var_val.strip(): - return true_val.strip() - else: - return false_val.strip() - else: - if ">=" in expr or "<=" in expr: - expr = expr.replace(">=", ">= ") - expr = expr.replace("<=", "<= ") - expr_parts = expr.split() - for i, part in enumerate(expr_parts): - if part in self.variables: - expr_parts[i] = self.check_callable(self.variables[part]) - expr = " ".join(expr_parts) - try: - if eval(expr): - return true_val.strip() - else: - return false_val.strip() - except: - return "" + + operator_funcs = { + "!=": lambda var_name, var_val: var_name.strip() in self.variables and self.check_callable(self.variables[var_name.strip()]) != var_val.strip(), + "=": lambda var_name, var_val: var_name.strip() in self.variables and self.check_callable(self.variables[var_name.strip()]) == var_val.strip() + } + + for operator, func in operator_funcs.items(): + if operator in expr: + var_name, var_val = expr.split(operator) + return true_val.strip() if func(var_name, var_val) else false_val.strip() + + if ">=" in expr or "<=" in expr: + expr = expr.replace(">=", ">= ") + expr = expr.replace("<=", "<= ") + + expr_parts = expr.split() + for i, part in enumerate(expr_parts): + if part in self.variables: + expr_parts[i] = self.check_callable(self.variables[part]) + + expr = " ".join(expr_parts) + try: + return true_val.strip() if eval(expr) else false_val.strip() + except: + return "" def replace(self, msg: str) -> str: if not msg: return - + try: msg = "".join([self.evaluate_expression(sub_s) for sub_s in re.split(r"(\{\{.*?\}\})", msg)]) keys = re.findall(r'@@(.*?)@@', msg) for key in keys: value = self.variables.get(key.lower(), None) - if value is None: - continue - - msg = msg.replace(f"@@{key}@@", self.check_callable(value)) + if value is not None: + msg = msg.replace(f"@@{key}@@", self.check_callable(value)) except: pass diff --git a/voicelink/player.py b/voicelink/player.py index 14cee67..125f773 100644 --- a/voicelink/player.py +++ b/voicelink/player.py @@ -134,7 +134,7 @@ class Player(VoiceProtocol): self.shuffle_votes = set() self.stop_votes = set() - self.ph = Placeholders(self) + self.ph = Placeholders(client, self) def __repr__(self): return ( @@ -499,7 +499,7 @@ class Player(VoiceProtocol): if track.spotify: if not track.original: search: Track = (await self._node.get_tracks( - f"ytmsearch:{track.author} - {track.title}", + f"ytsearch:{track.author} - {track.title}", requester=track.requester ))