Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.2][Audio] Part 2 #3210

Closed
wants to merge 96 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
d99b140
Removes `MAX_BALANCE` from bank, user `bank.get_max_balance()` now
Drapersniper Aug 8, 2019
a28b8c6
Bring it up to date
Drapersniper Aug 27, 2019
9ca1b60
Bring it up to date
Drapersniper Aug 28, 2019
9dfce1d
Bring it up to date
Drapersniper Aug 30, 2019
af5db27
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Sep 3, 2019
c494b6c
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Oct 11, 2019
4241cae
Initial Commit
Drapersniper Oct 11, 2019
cbc586f
I need to make sure I keep aika on her toes.
Drapersniper Oct 11, 2019
8a9da7c
Fixes a few missing kwargs and case consistency
Drapersniper Oct 11, 2019
7c0c82d
Fixes a few missing kwargs and case consistency v2 and typos
Drapersniper Oct 11, 2019
861ecd9
Reset cooldowns + add changelogs
Drapersniper Oct 11, 2019
0cf379d
Add 3 extra file formats.
Drapersniper Oct 11, 2019
4e68fd2
IRDUMB - fix capitalization.
Drapersniper Oct 11, 2019
032a913
Fix a silent error, and some incorrect messages.
Drapersniper Oct 11, 2019
df2dc85
Remove unnecessary emojis from queue when they are not needed
Drapersniper Oct 11, 2019
dc0e0d0
Remove duplicated call in `[p]playlist update`
Drapersniper Oct 11, 2019
bf6c7a9
Remove duplicated call in `[p]playlist update`
Drapersniper Oct 12, 2019
cb7cc52
Merge branch 'V3/develop' into audio-misc-pt1
Drapersniper Oct 17, 2019
c672e76
Resolve conflicts
Drapersniper Oct 31, 2019
17ea6d8
Bring all files up to date + Black
Drapersniper Oct 31, 2019
6bb9547
Facepalm
Drapersniper Oct 31, 2019
82acb69
*Sigh*
Drapersniper Oct 31, 2019
c46bbac
Merge branch 'V3/develop' into audio-misc-pt1
Drapersniper Oct 31, 2019
cb02bd6
*Sigh* 2.0
Drapersniper Oct 31, 2019
55d8222
Merge branch 'V3/develop' into audio-misc-pt1
Drapersniper Nov 7, 2019
334d1a4
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Nov 10, 2019
36c6d04
Merge remote-tracking branch 'origin/audio-misc-pt1' into audio-misc-pt1
Drapersniper Nov 10, 2019
5f3e7ca
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Nov 10, 2019
cf5ca38
Import missing Typecheck
Drapersniper Nov 10, 2019
71707e3
Fix Broken docstrings
Drapersniper Nov 10, 2019
271e638
Sort Local Tracks
Drapersniper Nov 10, 2019
d7c4f85
:facepalm:
Drapersniper Nov 10, 2019
3776b09
Reorder the sorting of local tracks,
Drapersniper Nov 10, 2019
a2ad03d
Black formatting
Drapersniper Nov 10, 2019
67d6584
Make the local file sorting case insensitive
Drapersniper Nov 10, 2019
5213f28
Add global blacklist/whitelist + fix some issues with original server…
Drapersniper Nov 10, 2019
7c1c4a4
Remove the pre-commit yaml
Drapersniper Nov 10, 2019
f854614
Nottin to see
Drapersniper Nov 11, 2019
895be45
Merge branch 'V3/develop' into audio-misc-pt1
Drapersniper Nov 11, 2019
aa550c2
Further improvement to the blacklists
Drapersniper Nov 11, 2019
a88ecd3
Further improvement to the blacklists
Drapersniper Nov 11, 2019
3df2e34
Fix the __str__ method on LocalTracks Object
Drapersniper Nov 13, 2019
e511430
Rename LocalTracks.to_string_hidden() to LocalTracks.to_string_user()…
Drapersniper Nov 13, 2019
28e43ba
Remove encoding pragmas + a few typo fixes
Drapersniper Nov 14, 2019
f330a70
Update some typehints + fix some typos
Drapersniper Nov 14, 2019
6f63cc8
Remove this duplicate call
Drapersniper Nov 14, 2019
297ef16
Black
Drapersniper Nov 14, 2019
3f76ac7
fix capitalization
Drapersniper Nov 14, 2019
117454d
Address preda's review
Drapersniper Nov 17, 2019
9877d69
Remove the API from the audio cog
mikeshardmind Nov 26, 2019
75757d8
changelog
mikeshardmind Nov 26, 2019
f1b5e12
Address Aika's review
Drapersniper Nov 26, 2019
0083d64
Merge branch 'V3/develop' into audio-misc-pt1
Drapersniper Nov 26, 2019
8b5755d
Black
Drapersniper Nov 26, 2019
6d7b762
*sigh* dont use github web ui
Drapersniper Nov 26, 2019
c9f0873
Fuck windows Long live linux... *sigh* no lets ensure windows users c…
Drapersniper Nov 26, 2019
135a309
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Dec 3, 2019
8e06629
:eyes: + chore
Drapersniper Dec 3, 2019
39787fb
facepalm
Drapersniper Dec 3, 2019
35d1566
facepalm... again y u h8 me bruh
Drapersniper Dec 3, 2019
57180c6
fuk this fuk u tube fuck python fuck all
Drapersniper Dec 3, 2019
6877d0a
awyehfqwajefhnqeffawefqa eqewarfqaesf qwef qaf qwfr
Drapersniper Dec 3, 2019
757ec9d
fuck everything
Drapersniper Dec 3, 2019
68b3425
oh lord saviour resus i love you just make this work
Drapersniper Dec 3, 2019
fa0f267
Change logic to be no errors within last 10 seconds... this should be…
Drapersniper Dec 4, 2019
89afd69
Remove auto deletion
Drapersniper Dec 4, 2019
4f7dbaa
black
Drapersniper Dec 4, 2019
a89815c
Add an is_url attribute to Query objects
Drapersniper Dec 6, 2019
0bb46a2
Merge branch 'V3/develop' into audio-misc-pt1
Drapersniper Dec 10, 2019
b3b7d74
Black
Drapersniper Dec 10, 2019
a14b34f
Address Aikas review
Drapersniper Dec 13, 2019
6265a53
Hyperlink Playlist names
Drapersniper Dec 13, 2019
d845ae6
Make shit bold
Drapersniper Dec 13, 2019
59b6bc9
why was this here
Drapersniper Dec 13, 2019
16927ad
why was this here
Drapersniper Dec 14, 2019
4af33cf
Migrate Playlist to DB 3 TODO
Drapersniper Dec 17, 2019
6bce47c
Revert "Migrate Playlist to DB 3 TODO 1 Migrate Config to Schema 3 wi…
Drapersniper Dec 17, 2019
bce139d
Allow removing tracks from queue by URL
Drapersniper Dec 19, 2019
4783e83
Words matter
Drapersniper Dec 19, 2019
28fec7b
*sigh*
Drapersniper Dec 19, 2019
46ba8ff
chore
Drapersniper Dec 19, 2019
ceac51c
Merge branches 'V3/develop' and 'f-yu-tube' of https://github.com/Dra…
Drapersniper Dec 20, 2019
8a4cd32
Merge branch 'V3/develop' into f-yu-tube
Drapersniper Dec 20, 2019
1c7b7de
arghhh CONFLICTS
Drapersniper Dec 20, 2019
6f7badc
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Dec 20, 2019
58d09a1
Merge branch 'V3/develop' of https://github.com/Drapersniper/Red-Disc…
Drapersniper Dec 20, 2019
e6595c0
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Dec 20, 2019
f6bd643
*sigh* conflicts and black
Drapersniper Dec 20, 2019
48d4da2
Merge branch 'audio-cog-isnt-an-api' of https://github.com/mikeshardm…
Drapersniper Dec 20, 2019
266eb50
Merge branch 'V3/develop' of https://github.com/Cog-Creators/Red-Disc…
Drapersniper Dec 21, 2019
9ddcb3e
Merge remote-tracking branch 'origin/V3/develop' into V3/develop
Drapersniper Dec 21, 2019
224e47f
Remove unused config default
Drapersniper Dec 22, 2019
364f8b1
Merge branches 'V3/develop' and 'audio-misc-pt1' of https://github.co…
Drapersniper Dec 22, 2019
048a6f8
Remove the API from the audio Cog (Properly)
Drapersniper Dec 22, 2019
8dc9cb6
Merge branch 'f-yu-tube' of https://github.com/Drapersniper/Red-Disco…
Drapersniper Dec 22, 2019
b993588
merge with upstream
Drapersniper Jan 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -30,7 +30,7 @@ redbot/core/utils/dbtools.py @mikeshardmind
# Cogs
redbot/cogs/admin/* @tekulvw
redbot/cogs/alias/* @tekulvw
redbot/cogs/audio/* @aikaterna
redbot/cogs/audio/* @aikaterna @Drapersniper
redbot/cogs/bank/* @tekulvw
redbot/cogs/cleanup/* @palmtree5
redbot/cogs/customcom/* @palmtree5
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -137,3 +137,6 @@ ENV/

# pytest
.pytest_cache/

# Pre-commit hooks
/.pre-commit-config.yaml
1 change: 1 addition & 0 deletions changelog.d/3047.bugfix.3.rst
@@ -0,0 +1 @@
Escape track descriptions so that they do not break markdown.
2 changes: 1 addition & 1 deletion changelog.d/audio/2904.dep.1.rst
@@ -1 +1 @@
New dependency: ``databases[sqlite]`` .
New dependency: ``databases[sqlite]``.
5 changes: 5 additions & 0 deletions changelog.d/audio/2904.enhance.9.rst
@@ -0,0 +1,5 @@
When playing a localtrack ``[p]play`` and ``[p]bumpplay`` no longer require the use of "localtracks\\" prefix.

Before: ``[p]bumpplay localtracks\\ENM\\501 - Inside The Machine.mp3``
Now: ``[p]bumpplay ENM\\501 - Inside The Machine.mp3``
Now nested folders: ``[p]bumpplay Parent Folder\\Nested Folder\\track.mp3``
1 change: 1 addition & 0 deletions changelog.d/audio/2940.bugfix.1.rst
@@ -0,0 +1 @@
Fix track index being off by 1 on ``[p]search`` command.
1 change: 1 addition & 0 deletions changelog.d/audio/2940.enhancement.1.rts
@@ -0,0 +1 @@
Expanded local track support to all file formats (m3u, m4a, mp4, etc).
1 change: 1 addition & 0 deletions changelog.d/audio/2940.enhancement.2.rst
@@ -0,0 +1 @@
Reset cooldown upon failure of commands that has a cooldown timer.
1 change: 1 addition & 0 deletions changelog.d/audio/2940.feature.1.rst
@@ -0,0 +1 @@
``[p]bumpplay`` command has been added.
1 change: 1 addition & 0 deletions changelog.d/audio/2940.feature.2.rst
@@ -0,0 +1 @@
``[p]shuffle`` command has an additional argument to tell the bot whether it should shuffle bumped tracks.
1 change: 1 addition & 0 deletions changelog.d/audio/2940.misc.1.rst
@@ -0,0 +1 @@
DJ_ENABLED and DJ_ROLE settings are now stored on memory after first fetch, to reduce duplicated calls.
1 change: 1 addition & 0 deletions changelog.d/audio/3047.bugfix.1.rst
@@ -0,0 +1 @@
Fix an issue where updating your Spotify and YouTube Data API tokens did not refresh them.
1 change: 1 addition & 0 deletions changelog.d/audio/3047.bugfix.2.rst
@@ -0,0 +1 @@
Fix an issue where the blacklist was not being applied correctly.
1 change: 1 addition & 0 deletions changelog.d/audio/3047.bugfix.3.rst
@@ -0,0 +1 @@
Fix an issue in ``[p]audioset restrictions blacklist list`` where it would call the list a `Whitelist`.
1 change: 1 addition & 0 deletions changelog.d/audio/3047.feature.1.rst
@@ -0,0 +1 @@
Add global whitelist/blacklist commands.
1 change: 1 addition & 0 deletions changelog.d/audio/3104.misc.3.rst
@@ -0,0 +1 @@
Add `cache.db` to the list of items not included in a backup.
1 change: 1 addition & 0 deletions changelog.d/audio/3152.misc.rst
@@ -0,0 +1 @@
remove an undocumented API from audio
1 change: 1 addition & 0 deletions changelog.d/audio/3165.bugfix.1.rst
@@ -0,0 +1 @@
Fixed an error that was thrown when running ``[p]audioset dj``.
1 change: 1 addition & 0 deletions changelog.d/audio/3165.enhance.1.rst
@@ -0,0 +1 @@
Better error handling the player is unable to play multiple tracks in sequence.
1 change: 1 addition & 0 deletions changelog.d/audio/3201.feature.1.rst
@@ -0,0 +1 @@
``[p]remove`` command now accepts an URL or Index, if an URL is used it will remove all tracks in the queue with that URL.
2 changes: 1 addition & 1 deletion docs/guide_cog_creation.rst
Expand Up @@ -21,7 +21,7 @@ To start off, be sure that you have installed Python 3.7.
Next, you need to decide if you want to develop against the Stable or Develop version of Red.
Depending on what your goal is should help determine which version you need.

.. attention::
.. attention::
The Develop version may have changes on it which break compatibility with the Stable version and other cogs.
If your goal is to support both versions, make sure you build compatibility layers or use separate branches to keep compatibility until the next Red release

Expand Down
116 changes: 52 additions & 64 deletions redbot/cogs/audio/apis.py
Expand Up @@ -11,19 +11,6 @@
from collections import namedtuple
from typing import Callable, Dict, List, Mapping, Optional, Tuple, Union

try:
from sqlite3 import Error as SQLError
from databases import Database

HAS_SQL = True
_ERROR = None
except ImportError as err:
_ERROR = "".join(traceback.format_exception_only(type(err), err)).strip()
HAS_SQL = False
SQLError = err.__class__
Database = None


import aiohttp
import discord
import lavalink
Expand All @@ -32,11 +19,25 @@
from redbot.core import Config, commands
from redbot.core.bot import Red
from redbot.core.i18n import Translator, cog_i18n

from . import audio_dataclasses
from .errors import InvalidTableError, SpotifyFetchError, YouTubeApiError, DatabaseError
from .playlists import get_playlist
from .utils import CacheLevel, Notifier, is_allowed, queue_duration, track_limit

try:
from sqlite3 import Error as SQLError
from databases import Database

HAS_SQL = True
_ERROR = None
except ImportError as err:
_ERROR = "".join(traceback.format_exception_only(type(err), err)).strip()
HAS_SQL = False
SQLError = err.__class__
Database: Callable = None


log = logging.getLogger("red.audio.cache")
_ = Translator("Audio", __file__)

Expand All @@ -57,13 +58,13 @@
)

_INSERT_YOUTUBE_TABLE = """
INSERT OR REPLACE INTO
youtube(track_info, youtube_url, last_updated, last_fetched)
INSERT OR REPLACE INTO
youtube(track_info, youtube_url, last_updated, last_fetched)
VALUES (:track_info, :track_url, :last_updated, :last_fetched);
"""
_QUERY_YOUTUBE_TABLE = "SELECT * FROM youtube WHERE track_info=:track;"
_UPDATE_YOUTUBE_TABLE = """UPDATE youtube
SET last_fetched=:last_fetched
SET last_fetched=:last_fetched
WHERE track_info=:track;"""

_DROP_SPOTIFY_TABLE = "DROP TABLE spotify;"
Expand All @@ -78,7 +79,7 @@
type TEXT,
uri TEXT,
track_name TEXT,
artist_name TEXT,
artist_name TEXT,
song_url TEXT,
track_info TEXT,
last_updated TEXT,
Expand All @@ -87,15 +88,15 @@
"""

_INSERT_SPOTIFY_TABLE = """
INSERT OR REPLACE INTO
spotify(id, type, uri, track_name, artist_name,
song_url, track_info, last_updated, last_fetched)
VALUES (:id, :type, :uri, :track_name, :artist_name,
INSERT OR REPLACE INTO
spotify(id, type, uri, track_name, artist_name,
song_url, track_info, last_updated, last_fetched)
VALUES (:id, :type, :uri, :track_name, :artist_name,
:song_url, :track_info, :last_updated, :last_fetched);
"""
_QUERY_SPOTIFY_TABLE = "SELECT * FROM spotify WHERE uri=:uri;"
_UPDATE_SPOTIFY_TABLE = """UPDATE spotify
SET last_fetched=:last_fetched
SET last_fetched=:last_fetched
WHERE uri=:uri;"""

_DROP_LAVALINK_TABLE = "DROP TABLE lavalink;"
Expand All @@ -115,8 +116,8 @@
)

_INSERT_LAVALINK_TABLE = """
INSERT OR REPLACE INTO
lavalink(query, data, last_updated, last_fetched)
INSERT OR REPLACE INTO
lavalink(query, data, last_updated, last_fetched)
VALUES (:query, :data, :last_updated, :last_fetched);
"""
_QUERY_LAVALINK_TABLE = "SELECT * FROM lavalink WHERE query=:query;"
Expand All @@ -131,7 +132,7 @@
" OR last_fetched LIKE :day7;"
)
_UPDATE_LAVALINK_TABLE = """UPDATE lavalink
SET last_fetched=:last_fetched
SET last_fetched=:last_fetched
WHERE query=:query;"""

_PARSER = {
Expand Down Expand Up @@ -194,10 +195,9 @@ async def _make_get(self, url: str, headers: dict = None, params: dict = None) -
return await r.json()

async def _get_auth(self):
if self.client_id is None or self.client_secret is None:
tokens = await self.bot.get_shared_api_tokens("spotify")
self.client_id = tokens.get("client_id", "")
self.client_secret = tokens.get("client_secret", "")
tokens = await self.bot.get_shared_api_tokens("spotify")
self.client_id = tokens.get("client_id", "")
self.client_secret = tokens.get("client_secret", "")

async def _request_token(self) -> dict:
await self._get_auth()
Expand Down Expand Up @@ -278,10 +278,9 @@ def __init__(self, bot: Red, session: aiohttp.ClientSession):
self.session = session
self.api_key = None

async def _get_api_key(self,) -> Optional[str]:
if self.api_key is None:
tokens = await self.bot.get_shared_api_tokens("youtube")
self.api_key = tokens.get("api_key", "")
async def _get_api_key(self,) -> str:
tokens = await self.bot.get_shared_api_tokens("youtube")
self.api_key = tokens.get("api_key", "")
return self.api_key

async def get_call(self, query: str) -> Optional[str]:
Expand Down Expand Up @@ -310,8 +309,8 @@ async def get_call(self, query: str) -> Optional[str]:

@cog_i18n(_)
class MusicCache:
"""
Handles music queries to the Spotify and Youtube Data API.
"""Handles music queries to the Spotify and Youtube Data API.

Always tries the Cache first.
"""

Expand Down Expand Up @@ -353,7 +352,7 @@ async def close(self):
await self.database.execute(query="PRAGMA optimize;")
await self.database.disconnect()

async def insert(self, table: str, values: List[dict]):
async def insert(self, table: str, values: List[Mapping]):
# if table == "spotify":
# return
if HAS_SQL:
Expand Down Expand Up @@ -414,7 +413,7 @@ async def fetch_all(self, table: str, query: str, values: Dict[str, str]) -> Lis
return []

@staticmethod
def _spotify_format_call(qtype: str, key: str) -> Tuple[str, dict]:
def _spotify_format_call(qtype: str, key: str) -> Tuple[str, Mapping]:
params = {}
if qtype == "album":
query = "https://api.spotify.com/v1/albums/{0}/tracks".format(key)
Expand Down Expand Up @@ -484,7 +483,7 @@ async def _spotify_first_time_query(
if youtube_cache:
update = True
with contextlib.suppress(SQLError):
val, update = await self.fetch_one(
(val, update) = await self.fetch_one(
"youtube", "youtube_url", {"track": track_info}
)
if update:
Expand Down Expand Up @@ -545,7 +544,7 @@ async def _spotify_fetch_tracks(
) -> Union[dict, List[str]]:

if recursive is False:
call, params = self._spotify_format_call(query_type, uri)
(call, params) = self._spotify_format_call(query_type, uri)
results = await self.spotify_api.get_call(call, params)
else:
results = await self.spotify_api.get_call(recursive, params)
Expand Down Expand Up @@ -608,8 +607,7 @@ async def spotify_query(
skip_youtube: bool = False,
notifier: Optional[Notifier] = None,
) -> List[str]:
"""
Queries the Database then falls back to Spotify and YouTube APIs.
"""Queries the Database then falls back to Spotify and YouTube APIs.

Parameters
----------
Expand All @@ -635,7 +633,7 @@ async def spotify_query(
if query_type == "track" and cache_enabled:
update = True
with contextlib.suppress(SQLError):
val, update = await self.fetch_one(
(val, update) = await self.fetch_one(
"spotify", "track_info", {"uri": f"spotify:track:{uri}"}
)
if update:
Expand Down Expand Up @@ -730,7 +728,7 @@ async def spotify_enqueue(
if youtube_cache:
update = True
with contextlib.suppress(SQLError):
val, update = await self.fetch_one(
(val, update) = await self.fetch_one(
"youtube", "youtube_url", {"track": track_info}
)
if update:
Expand All @@ -745,7 +743,7 @@ async def spotify_enqueue(

if val:
try:
result, called_api = await self.lavalink_query(
(result, called_api) = await self.lavalink_query(
ctx, player, audio_dataclasses.Query.process_input(val)
)
except (RuntimeError, aiohttp.ServerDisconnectedError):
Expand All @@ -760,7 +758,7 @@ async def spotify_enqueue(
lock(ctx, False)
error_embed = discord.Embed(
colour=await ctx.embed_colour(),
title=_("Player timedout, skipping remaning tracks."),
title=_("Player timeout, skipping remaining tracks."),
)
await notifier.update_embed(error_embed)
break
Expand All @@ -771,16 +769,6 @@ async def spotify_enqueue(
key = "lavalink"
seconds = "???"
second_key = None
# if track_count == 2:
# five_time = int(time.time()) - now
# if track_count >= 2:
# remain_tracks = total_tracks - track_count
# time_remain = (remain_tracks / 2) * five_time
# if track_count < total_tracks:
# seconds = dynamic_time(int(time_remain))
# if track_count == total_tracks:
# seconds = "0s"
# second_key = "lavalink_time"
await notifier.notify_user(
current=track_count,
total=total_tracks,
Expand Down Expand Up @@ -893,7 +881,9 @@ async def youtube_query(self, ctx: commands.Context, track_info: str) -> str:
if cache_enabled:
update = True
with contextlib.suppress(SQLError):
val, update = await self.fetch_one("youtube", "youtube_url", {"track": track_info})
(val, update) = await self.fetch_one(
"youtube", "youtube_url", {"track": track_info}
)
if update:
val = None
if val is None:
Expand All @@ -914,10 +904,8 @@ async def lavalink_query(
query: audio_dataclasses.Query,
forced: bool = False,
) -> Tuple[LoadResult, bool]:
"""
A replacement for :code:`lavalink.Player.load_tracks`.
This will try to get a valid cached entry first if not found or if in valid
it will then call the lavalink API.
"""A replacement for :code:`lavalink.Player.load_tracks`. This will try to get a valid
cached entry first if not found or if in valid it will then call the lavalink API.

Parameters
----------
Expand All @@ -944,7 +932,7 @@ async def lavalink_query(
if cache_enabled and not forced and not _raw_query.is_local:
update = True
with contextlib.suppress(SQLError):
val, update = await self.fetch_one("lavalink", "data", {"query": query})
(val, update) = await self.fetch_one("lavalink", "data", {"query": query})
if update:
val = None
if val:
Expand Down Expand Up @@ -1015,7 +1003,7 @@ async def run_all_pending_tasks(self):
log.debug("Running pending writes to database")
with contextlib.suppress(Exception):
tasks = {"update": [], "insert": []}
for k, task in self._tasks.items():
for (k, task) in self._tasks.items():
for t, args in task.items():
tasks[t].append(args)
self._tasks = {}
Expand Down Expand Up @@ -1087,7 +1075,7 @@ async def autoplay(self, player: lavalink.Player):
tracks = await self.play_random()
if not tracks:
ctx = namedtuple("Context", "message")
results, called_api = await self.lavalink_query(
(results, called_api) = await self.lavalink_query(
ctx(player.channel.guild),
player,
audio_dataclasses.Query.process_input(_TOP_100_US),
Expand Down Expand Up @@ -1124,7 +1112,7 @@ async def autoplay(self, player: lavalink.Player):
continue
valid = True

track.extras = {"autoplay": True}
track.extras["autoplay"] = True
player.add(player.channel.guild.me, track)
self.bot.dispatch(
"red_audio_track_auto_play", player.channel.guild, track, player.channel.guild.me
Expand Down