[3.2][Audio] Part 6 (Last? maybe?) (#3244)

* Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
`[p]bankset maxbal` can be used to set the maximum bank balance

Signed-off-by: Guy <guyreis96@gmail.com>

* Initial Commit

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* I need to make sure I keep aika on her toes.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fixes a few missing kwargs and case consistency

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fixes a few missing kwargs and case consistency v2 and typos

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Reset cooldowns + add changelogs

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Add 3 extra file formats.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* IRDUMB - fix capitalization.

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Fix a silent error, and some incorrect messages.

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove unnecessary emojis from queue when they are not needed

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove duplicated call in `[p]playlist update`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Remove duplicated call in `[p]playlist update`

Signed-off-by: guyre <27962761+drapersniper@users.noreply.github.com>

* Resolve conflicts

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Bring all files up to date + Black

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Facepalm

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* *Sigh*

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* *Sigh* 2.0

Signed-off-by: Draper <27962761+Drapersniper@users.noreply.github.com>

* Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-DiscordBot into audio-misc-pt1

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

# Resolve Conflicts:
#	redbot/cogs/audio/audio.py
#	redbot/cogs/audio/utils.py

* Import missing Typecheck

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix Broken docstrings

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Sort Local Tracks

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 🤦

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Reorder the sorting of local tracks,
`alphanumerical lower then alphanumerical upper`
`a comes before A, but B comes after A`

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black formatting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Make the local file sorting case insensitive

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add global blacklist/whitelist + fix some issues with original server based whitelist/blacklist

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the pre-commit yaml

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Nottin to see

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Further improvement to the blacklists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Further improvement to the blacklists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix  the __str__ method on LocalTracks Object

* Rename LocalTracks.to_string_hidden() to LocalTracks.to_string_user() To keep it inline with the Query object

* Remove encoding pragmas + a few typo fixes

* Update some typehints + fix some typos

* Remove this duplicate call

* Black

* fix capitalization

* Address preda's review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the API from the audio cog

 - Is in direct conflict with goals stated in #2804
 - Features this was intended to enable can be enabled in other more
 appropriate ways later on

* changelog

* Address Aika's review

* Black

* *sigh* dont use github web ui

* Fuck windows Long live linux... *sigh* no lets ensure windows users can still use local tracks

* Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-DiscordBot into refactoring

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

# Conflicts:
#	redbot/cogs/audio/audio.py

* 👀 + chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* facepalm

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* facepalm... again y u h8 me bruh

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fuk this fuk u tube fuck python fuck all

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* awyehfqwajefhnqeffawefqa eqewarfqaesf qwef qaf qwfr

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fuck everything

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* oh lord saviour resus i love you just make this work

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Change logic to be no errors within last 10 seconds... this should be a valid work around discord ratelimits caused by the spam

* Remove auto deletion

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* See I did a ting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* irdumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Add an is_url attribute to Query objects

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

* Address Aikas review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Hyperlink Playlist names

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Make shit bold

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* why was this here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* why was this here

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Initial commit

* Workinnng

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Improve SQL Statements +  migrate from SQL Alchemy + Databases to APSW

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* apsw tested and working

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chose

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Migrate Playlist to DB 3 TODO
1 Migrate Config to Schema 3 without playlists
and update get_playlist methods

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert "Migrate Playlist to DB 3 TODO 1 Migrate Config to Schema 3 without playlists and update get_playlist methods"

This reverts commit 4af33cff

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Implement schema migration

* Lets not touch the deps since #3192 is already adding them

* chore

* *sigh* Black

* Follow the existing logic and always default Playlist to guild scope

* wghqjegqf black

* Update usage of last_fetched and last_updated to be Ints... However column migration still pending

* Some bug fixes

* Update usage of last_fetched and last_updated to be Ints... However column migration still pending

* working

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* partial match

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* better partial match

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* I thought i done this before

* Delete 3195.misc.1.rst

Wrong PR

* Thanks Sinbad

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Thanks Sinbad

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Log Errors  in init ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Update error logs.

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Create index

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* :Drapersweat:

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Revert "Chore"

This reverts commit edcc9a9f

UGHHHH

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Allow removing tracks from queue by URL

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Words matter

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* arghhh CONFLICTS

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Review sinbads latest comment ..

ToDo.. Nuke existing playlist - check version and set version

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* migrate the DB schema to v3 (to keep in line with the schema visioning of Config

* Add a Todo

* *sigh* conflicts and black

* *sigh* black

* Passively delete playlist deletion mechanism

* Delete Old entries on startup

* Since we are dropping the table mightaware make these into JSON for future proofing

* Don't Dump strings in JSON field ? :think:

* Move some things around to make easier to use 1 connection to the Audio DB

* Move some things around to make easier to use 1 connection to the Audio DB

* *sigh*

* Clean up api

* *sigh* black

* Red + reorder some variables

* 🤦

* how could i forget this .......

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* #automagically

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* FINAFUCKINGLY

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* FINAFUCKINGLY

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove unused config default

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Remove the API from the audio Cog (Properly)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Missed these changes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ARGHHH

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Some fixes I've noticed while running through the code line by line

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Translation + UX (show playlist author ID if can't find user)

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* missed this one

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* this is no longer needed ....

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* 🤦

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix new lines in error messages

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black

* Sinbads Review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Sinbads Review

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* copy paste

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* imrpove backups

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Im a fucking idiot

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix #3238

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* chore

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* humans

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* humans

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* add play alias to playlists

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Im dumb ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Im dumb ...

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix new line

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix new line

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* show playlist count on playlist picker

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* fix currency check

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* show playlist count on playlist picker

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* DJ/Vote system fixes

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* fix currency check

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Fix duplicate messages on timeout

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix SQL Statement logic

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* fix SQL Statement logic

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape fix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Markdown escape fix

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* clean up local cache more frequently

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* clean up db more frequently

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Await in hell

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black cuz I hate red

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Black cuz I hate red

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* StringIO to ByteIO

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* StringIO to ByteIO

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* :Facepalm: the whole purpose of this is so its offline so this can be backed up without being blocking

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Run write queries on ThreadPoolExecutor

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* Backup Audio.db

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh* im dumb

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* blaaaack

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* *sigh*

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* formatting

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* remove duplicated string of code

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

* ffs awaits

Signed-off-by: Drapersniper <27962761+drapersniper@users.noreply.github.com>

Co-authored-by: Michael H <michael@michaelhall.tech>
This commit is contained in:
Draper
2020-01-04 01:36:09 +00:00
committed by Michael H
parent 1d2dd19244
commit 95e8d60729
43 changed files with 4128 additions and 1938 deletions

View File

@@ -1,9 +1,10 @@
import asyncio
import contextlib
import functools
import os
import re
import time
from enum import Enum, unique
from typing import MutableMapping, Optional, TYPE_CHECKING
from urllib.parse import urlparse
import discord
@@ -11,13 +12,14 @@ import lavalink
from redbot.core import Config, commands
from redbot.core.bot import Red
from redbot.core.i18n import Translator
from redbot.core.utils.chat_formatting import bold, box
from discord.utils import escape_markdown as escape
from . import audio_dataclasses
from .converters import _pass_config_to_converters
from .playlists import _pass_config_to_playlist
from .audio_dataclasses import Query
__all__ = [
"pass_config_to_dependencies",
"_pass_config_to_utils",
"track_limit",
"queue_duration",
"draw_time",
@@ -26,35 +28,45 @@ __all__ = [
"clear_react",
"match_yt_playlist",
"remove_react",
"get_description",
"get_track_description",
"track_creator",
"time_convert",
"url_check",
"userlimit",
"is_allowed",
"track_to_json",
"rgetattr",
"humanize_scope",
"CacheLevel",
"format_playlist_picker_data",
"get_track_description_unformatted",
"Notifier",
"PlaylistScope",
]
_re_time_converter = re.compile(r"(?:(\d+):)?([0-5]?[0-9]):([0-5][0-9])")
re_yt_list_playlist = re.compile(
_RE_TIME_CONVERTER = re.compile(r"(?:(\d+):)?([0-5]?[0-9]):([0-5][0-9])")
_RE_YT_LIST_PLAYLIST = re.compile(
r"^(https?://)?(www\.)?(youtube\.com|youtu\.?be)(/playlist\?).*(list=)(.*)(&|$)"
)
_config = None
_bot = None
if TYPE_CHECKING:
_config: Config
_bot: Red
else:
_config = None
_bot = None
_ = Translator("Audio", __file__)
def pass_config_to_dependencies(config: Config, bot: Red, localtracks_folder: str):
global _bot, _config
_bot = bot
_config = config
_pass_config_to_playlist(config, bot)
_pass_config_to_converters(config, bot)
audio_dataclasses._pass_config_to_dataclasses(config, bot, localtracks_folder)
def _pass_config_to_utils(config: Config, bot: Red) -> None:
global _config, _bot
if _config is None:
_config = config
if _bot is None:
_bot = bot
def track_limit(track, maxlength):
def track_limit(track, maxlength) -> bool:
try:
length = round(track.length / 1000)
except AttributeError:
@@ -65,16 +77,33 @@ def track_limit(track, maxlength):
return True
async def is_allowed(guild: discord.Guild, query: str):
async def is_allowed(guild: discord.Guild, query: str, query_obj: Query = None) -> bool:
query = query.lower().strip()
whitelist = set(await _config.guild(guild).url_keyword_whitelist())
if whitelist:
return any(i in query for i in whitelist)
blacklist = set(await _config.guild(guild).url_keyword_blacklist())
return not any(i in query for i in blacklist)
if query_obj is not None:
query = query_obj.lavalink_query.replace("ytsearch:", "youtubesearch").replace(
"scsearch:", "soundcloudsearch"
)
global_whitelist = set(await _config.url_keyword_whitelist())
global_whitelist = [i.lower() for i in global_whitelist]
if global_whitelist:
return any(i in query for i in global_whitelist)
global_blacklist = set(await _config.url_keyword_blacklist())
global_blacklist = [i.lower() for i in global_blacklist]
if any(i in query for i in global_blacklist):
return False
if guild is not None:
whitelist = set(await _config.guild(guild).url_keyword_whitelist())
whitelist = [i.lower() for i in whitelist]
if whitelist:
return any(i in query for i in whitelist)
blacklist = set(await _config.guild(guild).url_keyword_blacklist())
blacklist = [i.lower() for i in blacklist]
return not any(i in query for i in blacklist)
return True
async def queue_duration(ctx):
async def queue_duration(ctx) -> int:
player = lavalink.get_player(ctx.guild.id)
duration = []
for i in range(len(player.queue)):
@@ -94,7 +123,7 @@ async def queue_duration(ctx):
return queue_total_duration
async def draw_time(ctx):
async def draw_time(ctx) -> str:
player = lavalink.get_player(ctx.guild.id)
paused = player.paused
pos = player.position
@@ -115,7 +144,7 @@ async def draw_time(ctx):
return msg
def dynamic_time(seconds):
def dynamic_time(seconds) -> str:
m, s = divmod(seconds, 60)
h, m = divmod(m, 60)
d, h = divmod(h, 24)
@@ -133,7 +162,19 @@ def dynamic_time(seconds):
return msg.format(d, h, m, s)
def match_url(url):
def format_playlist_picker_data(pid, pname, ptracks, pauthor, scope) -> str:
author = _bot.get_user(pauthor) or pauthor or _("Unknown")
line = _(
" - Name: <{pname}>\n"
" - Scope: < {scope} >\n"
" - ID: < {pid} >\n"
" - Tracks: < {ptracks} >\n"
" - Author: < {author} >\n\n"
).format(pname=pname, scope=humanize_scope(scope), pid=pid, ptracks=ptracks, author=author)
return box(line, lang="md")
def match_url(url) -> bool:
try:
query_url = urlparse(url)
return all([query_url.scheme, query_url.netloc, query_url.path])
@@ -141,18 +182,18 @@ def match_url(url):
return False
def match_yt_playlist(url):
if re_yt_list_playlist.match(url):
def match_yt_playlist(url) -> bool:
if _RE_YT_LIST_PLAYLIST.match(url):
return True
return False
async def remove_react(message, react_emoji, react_user):
async def remove_react(message, react_emoji, react_user) -> None:
with contextlib.suppress(discord.HTTPException):
await message.remove_reaction(react_emoji, react_user)
async def clear_react(bot: Red, message: discord.Message, emoji: dict = None):
async def clear_react(bot: Red, message: discord.Message, emoji: MutableMapping = None) -> None:
try:
await message.clear_reactions()
except discord.Forbidden:
@@ -166,29 +207,50 @@ async def clear_react(bot: Red, message: discord.Message, emoji: dict = None):
return
async def get_description(track):
if any(x in track.uri for x in [f"{os.sep}localtracks", f"localtracks{os.sep}"]):
local_track = audio_dataclasses.LocalPath(track.uri)
if track.title != "Unknown title":
return "**{} - {}**\n{}".format(
track.author, track.title, local_track.to_string_hidden()
)
def get_track_description(track) -> Optional[str]:
if track and getattr(track, "uri", None):
query = Query.process_input(track.uri)
if query.is_local:
if track.title != "Unknown title":
return f'**{escape(f"{track.author} - {track.title}")}**' + escape(
f"\n{query.to_string_user()} "
)
else:
return escape(query.to_string_user())
else:
return local_track.to_string_hidden()
else:
return "**[{}]({})**".format(track.title, track.uri)
return f'**{escape(f"[{track.title}]({track.uri}) ")}**'
elif hasattr(track, "to_string_user") and track.is_local:
return escape(track.to_string_user() + " ")
def track_creator(player, position=None, other_track=None):
def get_track_description_unformatted(track) -> Optional[str]:
if track and hasattr(track, "uri"):
query = Query.process_input(track.uri)
if query.is_local:
if track.title != "Unknown title":
return escape(f"{track.author} - {track.title}")
else:
return escape(query.to_string_user())
else:
return escape(f"{track.title}")
elif hasattr(track, "to_string_user") and track.is_local:
return escape(track.to_string_user() + " ")
def track_creator(player, position=None, other_track=None) -> MutableMapping:
if position == "np":
queued_track = player.current
elif position is None:
queued_track = other_track
else:
queued_track = player.queue[position]
track_keys = queued_track._info.keys()
track_values = queued_track._info.values()
track_id = queued_track.track_identifier
return track_to_json(queued_track)
def track_to_json(track: lavalink.Track) -> MutableMapping:
track_keys = track._info.keys()
track_values = track._info.values()
track_id = track.track_identifier
track_info = {}
for k, v in zip(track_keys, track_values):
track_info[k] = v
@@ -200,8 +262,8 @@ def track_creator(player, position=None, other_track=None):
return track_obj
def time_convert(length):
match = re.compile(_re_time_converter).match(length)
def time_convert(length) -> int:
match = _RE_TIME_CONVERTER.match(length)
if match is not None:
hr = int(match.group(1)) if match.group(1) else 0
mn = int(match.group(2)) if match.group(2) else 0
@@ -215,7 +277,7 @@ def time_convert(length):
return 0
def url_check(url):
def url_check(url) -> bool:
valid_tld = [
"youtube.com",
"youtu.be",
@@ -235,7 +297,7 @@ def url_check(url):
return True if url_domain in valid_tld else False
def userlimit(channel):
def userlimit(channel) -> bool:
if channel.user_limit == 0 or channel.user_limit > len(channel.members) + 1:
return False
return True
@@ -386,7 +448,9 @@ class CacheLevel:
class Notifier:
def __init__(self, ctx: commands.Context, message: discord.Message, updates: dict, **kwargs):
def __init__(
self, ctx: commands.Context, message: discord.Message, updates: MutableMapping, **kwargs
):
self.context = ctx
self.message = message
self.updates = updates
@@ -402,8 +466,8 @@ class Notifier:
seconds_key: str = None,
seconds: str = None,
):
"""
This updates an existing message.
"""This updates an existing message.
Based on the message found in :variable:`Notifier.updates` as per the `key` param
"""
if self.last_msg_time + self.cooldown > time.time() and not current == total:
@@ -435,3 +499,27 @@ class Notifier:
self.last_msg_time = time.time()
except discord.errors.NotFound:
pass
@unique
class PlaylistScope(Enum):
GLOBAL = "GLOBALPLAYLIST"
GUILD = "GUILDPLAYLIST"
USER = "USERPLAYLIST"
def __str__(self):
return "{0}".format(self.value)
@staticmethod
def list():
return list(map(lambda c: c.value, PlaylistScope))
def humanize_scope(scope, ctx=None, the=None):
if scope == PlaylistScope.GLOBAL.value:
return _("the ") if the else "" + _("Global")
elif scope == PlaylistScope.GUILD.value:
return ctx.name if ctx else _("the ") if the else "" + _("Server")
elif scope == PlaylistScope.USER.value:
return str(ctx) if ctx else _("the ") if the else "" + _("User")