reformat / resolves #32
This commit is contained in:
parent
4c5d2b6943
commit
6c29c6fede
@ -292,6 +292,7 @@ class ValidRadioQueueRequest(BaseModel):
|
|||||||
start: Optional[int] = 0
|
start: Optional[int] = 0
|
||||||
search: Optional[str] = None
|
search: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
class ValidRadioQueueShiftRequest(BaseModel):
|
class ValidRadioQueueShiftRequest(BaseModel):
|
||||||
"""
|
"""
|
||||||
- **key**: API Key
|
- **key**: API Key
|
||||||
|
@ -84,9 +84,7 @@ class KarmaDB:
|
|||||||
"INSERT INTO karma(keyword, score, last_change) VALUES(?, ?, ?)"
|
"INSERT INTO karma(keyword, score, last_change) VALUES(?, ?, ?)"
|
||||||
)
|
)
|
||||||
friendly_flag: str = "++" if not flag else "--"
|
friendly_flag: str = "++" if not flag else "--"
|
||||||
audit_message: str = (
|
audit_message: str = f"{granter} adjusted karma for {keyword} @ {datetime.datetime.now().isoformat()}: {friendly_flag}"
|
||||||
f"{granter} adjusted karma for {keyword} @ {datetime.datetime.now().isoformat()}: {friendly_flag}"
|
|
||||||
)
|
|
||||||
audit_query: str = (
|
audit_query: str = (
|
||||||
"INSERT INTO karma_audit(impacted_keyword, comment) VALUES(?, ?)"
|
"INSERT INTO karma_audit(impacted_keyword, comment) VALUES(?, ?)"
|
||||||
)
|
)
|
||||||
|
@ -115,7 +115,7 @@ class LyricSearch(FastAPI):
|
|||||||
|
|
||||||
if data.src.upper() not in self.acceptable_request_sources:
|
if data.src.upper() not in self.acceptable_request_sources:
|
||||||
await self.notifier.send(
|
await self.notifier.send(
|
||||||
f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}",
|
f"ERROR @ {__file__.rsplit('/', maxsplit=1)[-1]}",
|
||||||
f"Unknown request source: {data.src}",
|
f"Unknown request source: {data.src}",
|
||||||
)
|
)
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
|
@ -97,8 +97,7 @@ class Radio(FastAPI):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug("radio_skip Exception: %s",
|
logging.debug("radio_skip Exception: %s", str(e))
|
||||||
str(e))
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
status_code=500,
|
status_code=500,
|
||||||
@ -122,16 +121,22 @@ class Radio(FastAPI):
|
|||||||
return JSONResponse(content={"ok": True})
|
return JSONResponse(content={"ok": True})
|
||||||
|
|
||||||
async def radio_get_queue(
|
async def radio_get_queue(
|
||||||
self, request: Request, data: ValidRadioQueueRequest,
|
self,
|
||||||
|
request: Request,
|
||||||
|
data: ValidRadioQueueRequest,
|
||||||
) -> JSONResponse:
|
) -> JSONResponse:
|
||||||
"""
|
"""
|
||||||
Get current play queue (paged, 20 results per page)
|
Get current play queue (paged, 20 results per page)
|
||||||
"""
|
"""
|
||||||
start: int = int(data.start)
|
start: int = int(data.start)
|
||||||
end: int = start+20
|
end: int = start + 20
|
||||||
logging.info("queue request with start pos: %s & end pos: %s",
|
search: Optional[str] = data.search
|
||||||
start, end)
|
logging.info("queue request with start pos: %s & end pos: %s", start, end)
|
||||||
|
|
||||||
|
if not search:
|
||||||
queue_full: list = self.radio_util.active_playlist
|
queue_full: list = self.radio_util.active_playlist
|
||||||
|
else:
|
||||||
|
queue_full: list = self.radio_util.datatables_search(data.search)
|
||||||
queue: list = queue_full[start:end]
|
queue: list = queue_full[start:end]
|
||||||
logging.info("queue length: %s", len(queue))
|
logging.info("queue length: %s", len(queue))
|
||||||
queue_out: list[dict] = []
|
queue_out: list[dict] = []
|
||||||
@ -152,7 +157,9 @@ class Radio(FastAPI):
|
|||||||
out_json = {
|
out_json = {
|
||||||
"draw": data.draw,
|
"draw": data.draw,
|
||||||
"recordsTotal": len(queue_full),
|
"recordsTotal": len(queue_full),
|
||||||
"recordsFiltered": len(queue_full) if not data.search else len(queue_full), # todo: implement search
|
"recordsFiltered": (
|
||||||
|
len(queue_full) if not data.search else len(queue_full)
|
||||||
|
), # todo: implement search
|
||||||
"items": queue_out,
|
"items": queue_out,
|
||||||
}
|
}
|
||||||
return JSONResponse(content=out_json)
|
return JSONResponse(content=out_json)
|
||||||
@ -239,8 +246,7 @@ class Radio(FastAPI):
|
|||||||
)
|
)
|
||||||
return Response(content=album_art, media_type="image/png")
|
return Response(content=album_art, media_type="image/png")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug("album_art_handler Exception: %s",
|
logging.debug("album_art_handler Exception: %s", str(e))
|
||||||
str(e))
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return RedirectResponse(
|
return RedirectResponse(
|
||||||
url="https://codey.lol/images/radio_art_default.jpg", status_code=302
|
url="https://codey.lol/images/radio_art_default.jpg", status_code=302
|
||||||
|
@ -113,9 +113,7 @@ class Transcriptions(FastAPI):
|
|||||||
db_path: Union[str, LiteralString] = os.path.join(
|
db_path: Union[str, LiteralString] = os.path.join(
|
||||||
"/usr/local/share", "sqlite_dbs", "sp.db"
|
"/usr/local/share", "sqlite_dbs", "sp.db"
|
||||||
)
|
)
|
||||||
db_query: str = (
|
db_query: str = """SELECT ("S" || Season || "E" || Episode || " " || Title), Character, Line FROM SP_DAT WHERE ID = ?"""
|
||||||
"""SELECT ("S" || Season || "E" || Episode || " " || Title), Character, Line FROM SP_DAT WHERE ID = ?"""
|
|
||||||
)
|
|
||||||
case 1:
|
case 1:
|
||||||
db_path = os.path.join("/usr/local/share", "sqlite_dbs", "futur.db")
|
db_path = os.path.join("/usr/local/share", "sqlite_dbs", "futur.db")
|
||||||
db_query = """SELECT ("S" || EP_S || "E" || EP_EP || " " || EP_TITLE || "<br><em>Opener: " || EP_OPENER || "</em>"), EP_LINE_SPEAKER, EP_LINE FROM clean_dialog WHERE EP_ID = ? ORDER BY LINE_ID ASC"""
|
db_query = """SELECT ("S" || EP_S || "E" || EP_EP || " " || EP_TITLE || "<br><em>Opener: " || EP_OPENER || "</em>"), EP_LINE_SPEAKER, EP_LINE FROM clean_dialog WHERE EP_ID = ? ORDER BY LINE_ID ASC"""
|
||||||
|
@ -78,7 +78,7 @@ class Aggregate:
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
logging.info("Could not increment redis failed counter: %s", str(e))
|
logging.info("Could not increment redis failed counter: %s", str(e))
|
||||||
self.notifier.send(
|
self.notifier.send(
|
||||||
f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}",
|
f"ERROR @ {__file__.rsplit('/', maxsplit=1)[-1]}",
|
||||||
f"Could not increment redis failed counter: {str(e)}",
|
f"Could not increment redis failed counter: {str(e)}",
|
||||||
)
|
)
|
||||||
return search_result
|
return search_result
|
||||||
|
@ -89,10 +89,8 @@ class Cache:
|
|||||||
logging.debug(
|
logging.debug(
|
||||||
"Checking whether %s is already stored", artistsong.replace("\n", " - ")
|
"Checking whether %s is already stored", artistsong.replace("\n", " - ")
|
||||||
)
|
)
|
||||||
check_query: str = (
|
check_query: str = 'SELECT id, artist, song FROM lyrics WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
||||||
'SELECT id, artist, song FROM lyrics WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
|
||||||
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 1'
|
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 1'
|
||||||
)
|
|
||||||
artistsong_split = artistsong.split("\n", maxsplit=1)
|
artistsong_split = artistsong.split("\n", maxsplit=1)
|
||||||
artist = artistsong_split[0].lower()
|
artist = artistsong_split[0].lower()
|
||||||
song = artistsong_split[1].lower()
|
song = artistsong_split[1].lower()
|
||||||
@ -132,7 +130,7 @@ class Cache:
|
|||||||
f"cache::store >> {str(e)}",
|
f"cache::store >> {str(e)}",
|
||||||
)
|
)
|
||||||
await self.notifier.send(
|
await self.notifier.send(
|
||||||
f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}",
|
f"ERROR @ {__file__.rsplit('/', maxsplit=1)[-1]}",
|
||||||
f"cache::store >> `{str(e)}`",
|
f"cache::store >> `{str(e)}`",
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -213,8 +211,10 @@ class Cache:
|
|||||||
lyrics = regex.sub(r"(<br>|\n|\r\n)", " / ", lyr_result.lyrics.strip())
|
lyrics = regex.sub(r"(<br>|\n|\r\n)", " / ", lyr_result.lyrics.strip())
|
||||||
lyrics = regex.sub(r"\s{2,}", " ", lyrics)
|
lyrics = regex.sub(r"\s{2,}", " ", lyrics)
|
||||||
|
|
||||||
insert_query = "INSERT INTO lyrics (src, date_retrieved, artist, song, artistsong, confidence, lyrics)\
|
insert_query = (
|
||||||
|
"INSERT INTO lyrics (src, date_retrieved, artist, song, artistsong, confidence, lyrics)\
|
||||||
VALUES(?, ?, ?, ?, ?, ?, ?)"
|
VALUES(?, ?, ?, ?, ?, ?, ?)"
|
||||||
|
)
|
||||||
params = (
|
params = (
|
||||||
lyr_result.src,
|
lyr_result.src,
|
||||||
time.time(),
|
time.time(),
|
||||||
@ -258,10 +258,8 @@ class Cache:
|
|||||||
|
|
||||||
if artist == "!" and song == "!":
|
if artist == "!" and song == "!":
|
||||||
random_search = True
|
random_search = True
|
||||||
search_query: str = (
|
search_query: str = "SELECT id, artist, song, lyrics, src, confidence\
|
||||||
"SELECT id, artist, song, lyrics, src, confidence\
|
|
||||||
FROM lyrics ORDER BY RANDOM() LIMIT 1"
|
FROM lyrics ORDER BY RANDOM() LIMIT 1"
|
||||||
)
|
|
||||||
|
|
||||||
logging.info("Searching %s - %s on %s", artist, song, self.label)
|
logging.info("Searching %s - %s on %s", artist, song, self.label)
|
||||||
|
|
||||||
@ -319,11 +317,9 @@ class Cache:
|
|||||||
self.cache_pre_query
|
self.cache_pre_query
|
||||||
) as _db_cursor:
|
) as _db_cursor:
|
||||||
if not random_search:
|
if not random_search:
|
||||||
search_query: str = (
|
search_query: str = 'SELECT id, artist, song, lyrics, src, confidence FROM lyrics\
|
||||||
'SELECT id, artist, song, lyrics, src, confidence FROM lyrics\
|
|
||||||
WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
||||||
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 10'
|
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 10'
|
||||||
)
|
|
||||||
search_params: tuple = (
|
search_params: tuple = (
|
||||||
artist.strip(),
|
artist.strip(),
|
||||||
song.strip(),
|
song.strip(),
|
||||||
|
@ -31,7 +31,6 @@ class LastFM:
|
|||||||
]
|
]
|
||||||
|
|
||||||
async with ClientSession() as session:
|
async with ClientSession() as session:
|
||||||
|
|
||||||
async with await session.get(
|
async with await session.get(
|
||||||
self.api_base_url,
|
self.api_base_url,
|
||||||
params=request_params,
|
params=request_params,
|
||||||
|
@ -11,9 +11,11 @@ from regex import Pattern
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import gpt
|
import gpt
|
||||||
import music_tag # type: ignore
|
import music_tag # type: ignore
|
||||||
|
from rapidfuzz import fuzz
|
||||||
from endpoints.constructors import RadioException
|
from endpoints.constructors import RadioException
|
||||||
|
|
||||||
double_space: Pattern = regex.compile(r"\s{2,}")
|
double_space: Pattern = regex.compile(r"\s{2,}")
|
||||||
|
non_alnum: Pattern = regex.compile(r"[^a-zA-Z0-9]")
|
||||||
|
|
||||||
"""
|
"""
|
||||||
TODO:
|
TODO:
|
||||||
@ -110,7 +112,36 @@ class RadioUtil:
|
|||||||
out_result = [str(r["artistsong"]) for r in result]
|
out_result = [str(r["artistsong"]) for r in result]
|
||||||
return out_result
|
return out_result
|
||||||
|
|
||||||
async def search_playlist(
|
def datatables_search(self, filter: str) -> Optional[list[dict]]:
|
||||||
|
"""DataTables Search
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filter (str): The filter query to fuzzy match with
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: List of matching playlist items (if any are found)
|
||||||
|
"""
|
||||||
|
filter = filter.strip().lower()
|
||||||
|
matched: list[dict] = []
|
||||||
|
for item in self.active_playlist:
|
||||||
|
artist: str = item.get("artist", None)
|
||||||
|
song: str = item.get("song", None)
|
||||||
|
artistsong: str = item.get("artistsong", None)
|
||||||
|
album: str = item.get("album", None)
|
||||||
|
if not artist or not song or not artistsong:
|
||||||
|
continue
|
||||||
|
if non_alnum.sub("", filter) in non_alnum.sub("", artistsong).lower():
|
||||||
|
matched.append(item)
|
||||||
|
continue
|
||||||
|
if (
|
||||||
|
fuzz.ratio(filter, artist) >= 85
|
||||||
|
or fuzz.ratio(filter, song) >= 85
|
||||||
|
or fuzz.ratio(filter, album) >= 85
|
||||||
|
):
|
||||||
|
matched.append(item)
|
||||||
|
return matched
|
||||||
|
|
||||||
|
def search_playlist(
|
||||||
self,
|
self,
|
||||||
artistsong: Optional[str] = None,
|
artistsong: Optional[str] = None,
|
||||||
artist: Optional[str] = None,
|
artist: Optional[str] = None,
|
||||||
@ -130,11 +161,9 @@ class RadioUtil:
|
|||||||
if not artistsong and (not artist or not song):
|
if not artistsong and (not artist or not song):
|
||||||
raise RadioException("No query provided")
|
raise RadioException("No query provided")
|
||||||
try:
|
try:
|
||||||
search_query: str = (
|
search_query: str = 'SELECT id, artist, song, (artist || " - " || song) AS artistsong, album, file_path, duration FROM tracks\
|
||||||
'SELECT id, artist, song, (artist || " - " || song) AS artistsong, album, file_path, duration FROM tracks\
|
|
||||||
WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
||||||
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 1'
|
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 1'
|
||||||
)
|
|
||||||
if artistsong:
|
if artistsong:
|
||||||
artistsong_split: list = artistsong.split(" - ", maxsplit=1)
|
artistsong_split: list = artistsong.split(" - ", maxsplit=1)
|
||||||
(search_artist, search_song) = tuple(artistsong_split)
|
(search_artist, search_song) = tuple(artistsong_split)
|
||||||
@ -153,9 +182,7 @@ class RadioUtil:
|
|||||||
for ext in self.sqlite_exts:
|
for ext in self.sqlite_exts:
|
||||||
db_conn.load_extension(ext)
|
db_conn.load_extension(ext)
|
||||||
db_conn.row_factory = sqlite3.Row
|
db_conn.row_factory = sqlite3.Row
|
||||||
db_cursor = db_conn.execute(
|
db_cursor = db_conn.execute(search_query, search_params)
|
||||||
search_query, search_params
|
|
||||||
)
|
|
||||||
result: Optional[sqlite3.Row | bool] = db_cursor.fetchone()
|
result: Optional[sqlite3.Row | bool] = db_cursor.fetchone()
|
||||||
if not result or not isinstance(result, sqlite3.Row):
|
if not result or not isinstance(result, sqlite3.Row):
|
||||||
return False
|
return False
|
||||||
@ -178,7 +205,7 @@ class RadioUtil:
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def add_genre(self, artist: str, genre: str) -> bool:
|
def add_genre(self, artist: str, genre: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Add artist/genre pairing to DB
|
Add artist/genre pairing to DB
|
||||||
Args:
|
Args:
|
||||||
@ -213,7 +240,7 @@ class RadioUtil:
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def add_genres(self, pairs: list[dict[str, str]]) -> bool:
|
def add_genres(self, pairs: list[dict[str, str]]) -> bool:
|
||||||
"""
|
"""
|
||||||
(BATCH) Add artist/genre pairings to DB
|
(BATCH) Add artist/genre pairings to DB
|
||||||
Expects list of dicts comprised of artist name (key), genre (value)
|
Expects list of dicts comprised of artist name (key), genre (value)
|
||||||
@ -228,9 +255,7 @@ class RadioUtil:
|
|||||||
for pair in pairs:
|
for pair in pairs:
|
||||||
try:
|
try:
|
||||||
artist, genre = pair
|
artist, genre = pair
|
||||||
query: str = (
|
query: str = "INSERT OR IGNORE INTO artist_genre (artist, genre) VALUES(?, ?)"
|
||||||
"INSERT OR IGNORE INTO artist_genre (artist, genre) VALUES(?, ?)"
|
|
||||||
)
|
|
||||||
params: tuple[str, str] = (artist, genre)
|
params: tuple[str, str] = (artist, genre)
|
||||||
res = _db.execute(query, params)
|
res = _db.execute(query, params)
|
||||||
if isinstance(res.lastrowid, int):
|
if isinstance(res.lastrowid, int):
|
||||||
@ -411,11 +436,13 @@ class RadioUtil:
|
|||||||
if isinstance(db_cursor.lastrowid, int):
|
if isinstance(db_cursor.lastrowid, int):
|
||||||
db_conn.commit()
|
db_conn.commit()
|
||||||
else:
|
else:
|
||||||
logging.debug("No row inserted for track_id: %s w/ file_path: %s", track_id,
|
logging.debug(
|
||||||
file_path)
|
"No row inserted for track_id: %s w/ file_path: %s",
|
||||||
|
track_id,
|
||||||
|
file_path,
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug("cache_album_art Exception: %s",
|
logging.debug("cache_album_art Exception: %s", str(e))
|
||||||
str(e))
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
async def get_album_art(self, track_id: int) -> Optional[bytes]:
|
async def get_album_art(self, track_id: int) -> Optional[bytes]:
|
||||||
@ -433,15 +460,12 @@ class RadioUtil:
|
|||||||
query_params: tuple[int] = (track_id,)
|
query_params: tuple[int] = (track_id,)
|
||||||
|
|
||||||
db_cursor = db_conn.execute(query, query_params)
|
db_cursor = db_conn.execute(query, query_params)
|
||||||
result: Optional[Union[sqlite3.Row, bool]] = (
|
result: Optional[Union[sqlite3.Row, bool]] = db_cursor.fetchone()
|
||||||
db_cursor.fetchone()
|
|
||||||
)
|
|
||||||
if not result or not isinstance(result, sqlite3.Row):
|
if not result or not isinstance(result, sqlite3.Row):
|
||||||
return None
|
return None
|
||||||
return result["album_art"]
|
return result["album_art"]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.debug("get_album_art Exception: %s",
|
logging.debug("get_album_art Exception: %s", str(e))
|
||||||
str(e))
|
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user