mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 11:18:54 -05:00
* First commit - Bring everything from dev cog minus NSFW support * Add a toggle for auto deafen * Add a one off Send to Owners * aaaaaaa * Update this to ensure `get_perms` is not called if the API is disabled * Apply suggestions from code review Co-authored-by: Vuks <51289041+Vuks69@users.noreply.github.com> * silence any errors here (in case API is down so it doesnt affect audio) * update the message to tell the mto join the Official Red server. * remove useless sutff, and change dj check order to ensure bot doesnt join VC for non DJ's * ffs * Update redbot/cogs/audio/core/tasks/startup.py Co-authored-by: Twentysix <Twentysix26@users.noreply.github.com> * Aikas Review * Add #3995 in here * update * *sigh* * lock behind owner * to help with debugging * Revert "to help with debugging" This reverts commit 8cbf17be * resolve last review Co-authored-by: Vuks <51289041+Vuks69@users.noreply.github.com> Co-authored-by: Twentysix <Twentysix26@users.noreply.github.com>
156 lines
4.6 KiB
Python
156 lines
4.6 KiB
Python
import datetime
|
|
import json
|
|
import logging
|
|
from collections import namedtuple
|
|
from dataclasses import dataclass, field
|
|
from typing import List, MutableMapping, Optional, Union
|
|
|
|
import discord
|
|
import lavalink
|
|
|
|
from redbot.core.bot import Red
|
|
from redbot.core.utils.chat_formatting import humanize_list
|
|
|
|
from ..errors import InvalidPlaylistScope, MissingAuthor, MissingGuild
|
|
from ..utils import PlaylistScope
|
|
|
|
log = logging.getLogger("red.cogs.Audio.api.utils")
|
|
|
|
|
|
@dataclass
|
|
class YouTubeCacheFetchResult:
|
|
query: Optional[str]
|
|
last_updated: int
|
|
|
|
def __post_init__(self):
|
|
if isinstance(self.last_updated, int):
|
|
self.updated_on: datetime.datetime = datetime.datetime.fromtimestamp(self.last_updated)
|
|
|
|
|
|
@dataclass
|
|
class SpotifyCacheFetchResult:
|
|
query: Optional[str]
|
|
last_updated: int
|
|
|
|
def __post_init__(self):
|
|
if isinstance(self.last_updated, int):
|
|
self.updated_on: datetime.datetime = datetime.datetime.fromtimestamp(self.last_updated)
|
|
|
|
|
|
@dataclass
|
|
class LavalinkCacheFetchResult:
|
|
query: Optional[MutableMapping]
|
|
last_updated: int
|
|
|
|
def __post_init__(self):
|
|
if isinstance(self.last_updated, int):
|
|
self.updated_on: datetime.datetime = datetime.datetime.fromtimestamp(self.last_updated)
|
|
|
|
if isinstance(self.query, str):
|
|
self.query = json.loads(self.query)
|
|
|
|
|
|
@dataclass
|
|
class LavalinkCacheFetchForGlobalResult:
|
|
query: str
|
|
data: MutableMapping
|
|
|
|
def __post_init__(self):
|
|
if isinstance(self.data, str):
|
|
self.data_string = str(self.data)
|
|
self.data = json.loads(self.data)
|
|
|
|
|
|
@dataclass
|
|
class PlaylistFetchResult:
|
|
playlist_id: int
|
|
playlist_name: str
|
|
scope_id: int
|
|
author_id: int
|
|
playlist_url: Optional[str] = None
|
|
tracks: List[MutableMapping] = field(default_factory=lambda: [])
|
|
|
|
def __post_init__(self):
|
|
if isinstance(self.tracks, str):
|
|
self.tracks = json.loads(self.tracks)
|
|
|
|
|
|
@dataclass
|
|
class QueueFetchResult:
|
|
guild_id: int
|
|
room_id: int
|
|
track: dict = field(default_factory=lambda: {})
|
|
track_object: lavalink.Track = None
|
|
|
|
def __post_init__(self):
|
|
if isinstance(self.track, str):
|
|
self.track = json.loads(self.track)
|
|
if self.track:
|
|
self.track_object = lavalink.Track(self.track)
|
|
|
|
|
|
def standardize_scope(scope: str) -> str:
|
|
"""Convert any of the used scopes into one we are expecting."""
|
|
scope = scope.upper()
|
|
valid_scopes = ["GLOBAL", "GUILD", "AUTHOR", "USER", "SERVER", "MEMBER", "BOT"]
|
|
|
|
if scope in PlaylistScope.list():
|
|
return scope
|
|
elif scope not in valid_scopes:
|
|
raise InvalidPlaylistScope(
|
|
f'"{scope}" is not a valid playlist scope.'
|
|
f" Scope needs to be one of the following: {humanize_list(valid_scopes)}"
|
|
)
|
|
|
|
if scope in ["GLOBAL", "BOT"]:
|
|
scope = PlaylistScope.GLOBAL.value
|
|
elif scope in ["GUILD", "SERVER"]:
|
|
scope = PlaylistScope.GUILD.value
|
|
elif scope in ["USER", "MEMBER", "AUTHOR"]:
|
|
scope = PlaylistScope.USER.value
|
|
|
|
return scope
|
|
|
|
|
|
def prepare_config_scope(
|
|
bot: Red,
|
|
scope,
|
|
author: Union[discord.abc.User, int] = None,
|
|
guild: Union[discord.Guild, int] = None,
|
|
):
|
|
"""Return the scope used by Playlists."""
|
|
scope = standardize_scope(scope)
|
|
if scope == PlaylistScope.GLOBAL.value:
|
|
config_scope = [PlaylistScope.GLOBAL.value, bot.user.id]
|
|
elif scope == PlaylistScope.USER.value:
|
|
if author is None:
|
|
raise MissingAuthor("Invalid author for user scope.")
|
|
config_scope = [PlaylistScope.USER.value, int(getattr(author, "id", author))]
|
|
else:
|
|
if guild is None:
|
|
raise MissingGuild("Invalid guild for guild scope.")
|
|
config_scope = [PlaylistScope.GUILD.value, int(getattr(guild, "id", guild))]
|
|
return config_scope
|
|
|
|
|
|
def prepare_config_scope_for_migration23( # TODO: remove me in a future version ?
|
|
scope, author: Union[discord.abc.User, int] = None, guild: discord.Guild = None
|
|
):
|
|
"""Return the scope used by Playlists."""
|
|
scope = standardize_scope(scope)
|
|
|
|
if scope == PlaylistScope.GLOBAL.value:
|
|
config_scope = [PlaylistScope.GLOBAL.value]
|
|
elif scope == PlaylistScope.USER.value:
|
|
if author is None:
|
|
raise MissingAuthor("Invalid author for user scope.")
|
|
config_scope = [PlaylistScope.USER.value, str(getattr(author, "id", author))]
|
|
else:
|
|
if guild is None:
|
|
raise MissingGuild("Invalid guild for guild scope.")
|
|
config_scope = [PlaylistScope.GUILD.value, str(getattr(guild, "id", guild))]
|
|
return config_scope
|
|
|
|
|
|
FakePlaylist = namedtuple("Playlist", "author scope")
|