cleanup/minor

This commit is contained in:
codey 2025-03-04 08:11:55 -05:00
parent a023868671
commit f29837280a
6 changed files with 103 additions and 46 deletions

View File

@ -45,10 +45,12 @@ class ValidArtistSearchRequest(BaseModel):
a: str a: str
class Config: model_config = {
schema_extra = { "json_schema_extra": {
"example": { "examples": [
"a": "eminem" {
"a": "eminem",
}]
} }
} }
@ -61,11 +63,13 @@ class ValidAlbumDetailRequest(BaseModel):
a: str a: str
release: str release: str
class Config: model_config = {
schema_extra = { "json_schema_extra": {
"example": { "examples": [
{
"a": "eminem", "a": "eminem",
"release": "houdini" "release": "houdini",
}]
} }
} }
@ -78,11 +82,13 @@ class ValidTrackInfoRequest(BaseModel):
a: str a: str
t: str t: str
class Config: model_config = {
schema_extra = { "json_schema_extra": {
"example": { "examples": [
{
"a": "eminem", "a": "eminem",
"t": "rap god" "t": "rap god",
}]
} }
} }

View File

@ -7,8 +7,8 @@ import aiosqlite as sqlite3
from typing import LiteralString, Optional, Union from typing import LiteralString, Optional, Union
from fastapi import FastAPI, Request, HTTPException from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from .constructors import ValidTopKarmaRequest, ValidKarmaRetrievalRequest,\ from .constructors import (ValidTopKarmaRequest, ValidKarmaRetrievalRequest,
ValidKarmaUpdateRequest ValidKarmaUpdateRequest)
class KarmaDB: class KarmaDB:
"""Karma DB Util""" """Karma DB Util"""

View File

@ -3,8 +3,8 @@ import traceback
from typing import Optional, Union from typing import Optional, Union
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from .constructors import ValidArtistSearchRequest, ValidAlbumDetailRequest,\ from .constructors import (ValidArtistSearchRequest, ValidAlbumDetailRequest,
ValidTrackInfoRequest, LastFMException ValidTrackInfoRequest, LastFMException)
class LastFM(FastAPI): class LastFM(FastAPI):
"""Last.FM Endpoints""" """Last.FM Endpoints"""
@ -41,7 +41,8 @@ class LastFM(FastAPI):
}) })
artist_result = await self.lastfm.search_artist(artist=artist) artist_result = await self.lastfm.search_artist(artist=artist)
if not artist_result or "err" in artist_result.keys(): if not artist_result or not artist_result.get('bio')\
or "err" in artist_result.keys():
return JSONResponse(status_code=500, content={ return JSONResponse(status_code=500, content={
'err': True, 'err': True,
'errorText': 'Search failed (no results?)', 'errorText': 'Search failed (no results?)',

View File

@ -1,7 +1,11 @@
import logging import logging
import time import time
from typing import Optional import os
from fastapi import FastAPI from typing import Optional, Annotated
from fastapi import (
FastAPI, Request, UploadFile,
Response, HTTPException, Form
)
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
import redis.asyncio as redis import redis.asyncio as redis
from lyric_search.sources import private, cache as LyricsCache, redis_cache from lyric_search.sources import private, cache as LyricsCache, redis_cache
@ -19,16 +23,51 @@ class Misc(FastAPI):
self.redis_cache = redis_cache.RedisCache() self.redis_cache = redis_cache.RedisCache()
self.redis_client = redis.Redis(password=private.REDIS_PW) self.redis_client = redis.Redis(password=private.REDIS_PW)
self.radio = radio self.radio = radio
self.activity_image: Optional[bytes] = None
self.endpoints: dict = { self.endpoints: dict = {
"widget/redis": self.homepage_redis_widget, "widget/redis": self.homepage_redis_widget,
"widget/sqlite": self.homepage_sqlite_widget, "widget/sqlite": self.homepage_sqlite_widget,
"widget/lyrics": self.homepage_lyrics_widget, "widget/lyrics": self.homepage_lyrics_widget,
"widget/radio": self.homepage_radio_widget, "widget/radio": self.homepage_radio_widget,
"misc/get_activity_image": self.get_activity_image,
} }
for endpoint, handler in self.endpoints.items(): for endpoint, handler in self.endpoints.items():
app.add_api_route(f"/{endpoint}", handler, methods=["GET"], app.add_api_route(f"/{endpoint}", handler, methods=["GET"],
include_in_schema=False) include_in_schema=True)
app.add_api_route("/misc/upload_activity_image",
self.upload_activity_image, methods=["POST"])
async def upload_activity_image(self,
image: UploadFile,
key: Annotated[str, Form()], request: Request) -> Response:
if not key or not isinstance(key, str)\
or not self.util.check_key(path=request.url.path, req_type=2, key=key):
raise HTTPException(status_code=403, detail="Unauthorized")
if not image:
return JSONResponse(status_code=500, content={
'err': True,
'errorText': 'Invalid request',
})
self.activity_image = await image.read()
return JSONResponse(content={
'success': True,
})
async def get_activity_image(self, request: Request) -> Response:
if isinstance(self.activity_image, bytes):
return Response(content=self.activity_image,
media_type="image/png")
# Fallback
fallback_path = os.path.join("/var/www/codey.lol/public",
"images", "plex_placeholder.png")
with open(fallback_path, 'rb') as f:
return Response(content=f.read(),
media_type="image/png")
async def get_radio_np(self) -> str: async def get_radio_np(self) -> str:
""" """

View File

@ -3,13 +3,16 @@ import traceback
import time import time
import random import random
import asyncio import asyncio
from . import radio_util from utils import radio_util
from .constructors import ValidRadioNextRequest, ValidRadioReshuffleRequest, ValidRadioQueueShiftRequest,\ from .constructors import (ValidRadioNextRequest, ValidRadioReshuffleRequest,
ValidRadioQueueRemovalRequest, ValidRadioSongRequest,\ ValidRadioQueueShiftRequest, ValidRadioQueueRemovalRequest,
ValidRadioTypeaheadRequest, RadioException ValidRadioSongRequest, ValidRadioTypeaheadRequest,
RadioException)
from uuid import uuid4 as uuid from uuid import uuid4 as uuid
from typing import Optional from typing import Optional
from fastapi import FastAPI, BackgroundTasks, Request, Response, HTTPException from fastapi import (FastAPI, BackgroundTasks, Request,
Response, HTTPException)
from fastapi.responses import RedirectResponse, JSONResponse from fastapi.responses import RedirectResponse, JSONResponse
""" """

View File

@ -10,7 +10,7 @@ from aiohttp import ClientSession, ClientTimeout
import aiosqlite as sqlite3 import aiosqlite as sqlite3
from typing import Union, Optional, LiteralString, Iterable from typing import Union, Optional, LiteralString, Iterable
from uuid import uuid4 as uuid from uuid import uuid4 as uuid
from .constructors import RadioException from endpoints.constructors import RadioException
double_space: Pattern = regex.compile(r'\s{2,}') double_space: Pattern = regex.compile(r'\s{2,}')
@ -31,6 +31,7 @@ class RadioUtil:
self.now_playing: dict = { self.now_playing: dict = {
'artist': 'N/A', 'artist': 'N/A',
'song': 'N/A', 'song': 'N/A',
'album': 'N/A',
'genre': 'N/A', 'genre': 'N/A',
'artistsong': 'N/A - N/A', 'artistsong': 'N/A - N/A',
'duration': 0, 'duration': 0,
@ -94,7 +95,7 @@ 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 = 'SELECT id, artist, song, (artist || " - " || song) AS artistsong, genre, file_path, duration FROM tracks\ search_query: str = 'SELECT id, artist, song, (artist || " - " || song) AS artistsong, album, genre, 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:
@ -138,14 +139,14 @@ class RadioUtil:
try: try:
logging.info(f"Loading playlist...") logging.info(f"Loading playlist...")
self.active_playlist.clear() self.active_playlist.clear()
# db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, genre, file_path, duration FROM tracks\ # db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\
# GROUP BY artistdashsong ORDER BY RANDOM()' # GROUP BY artistdashsong ORDER BY RANDOM()'
""" """
LIMITED GENRES LIMITED GENRES
""" """
db_query: str = """SELECT distinct(LOWER(TRIM(artist)) || " - " || LOWER(TRIM(song))), (TRIM(artist) || " - " || TRIM(song)) AS artistdashsong, id, artist, song, genre, file_path, duration FROM tracks\ db_query: str = """SELECT distinct(LOWER(TRIM(artist)) || " - " || LOWER(TRIM(song))), (TRIM(artist) || " - " || TRIM(song)) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\
WHERE (genre LIKE "%metalcore%"\ WHERE (genre LIKE "%metalcore%"\
OR genre LIKE "%rock%"\ OR genre LIKE "%rock%"\
OR genre LIKE "%pop punk%"\ OR genre LIKE "%pop punk%"\
@ -178,16 +179,22 @@ class RadioUtil:
OR genre LIKE "%synthwave%"\ OR genre LIKE "%synthwave%"\
OR genre LIKE "%trap%"\ OR genre LIKE "%trap%"\
OR genre LIKE "%indie pop%"\ OR genre LIKE "%indie pop%"\
OR genre LIKE "%dnb%"\ OR genre LIKE "%dnb%")\
OR genre LIKE "untagged")\
GROUP BY artistdashsong ORDER BY RANDOM()""" GROUP BY artistdashsong ORDER BY RANDOM()"""
""" """
LIMITED TO ONE ARTIST... LIMITED TO ONE/SMALL SUBSET OF GENRES
""" """
# db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, genre, file_path, duration FROM tracks\ # db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\
# WHERE artist LIKE "%wage war%" GROUP BY artistdashsong ORDER BY id DESC' # WHERE genre like "%edm%" OR genre LIKE "%electronic%"'
"""
LIMITED TO ONE/SOME ARTISTS...
"""
# db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\
# WHERE artist LIKE "%sullivan king%" GROUP BY artistdashsong ORDER BY artist ASC, album ASC, id DESC'
async with sqlite3.connect(self.active_playlist_path, async with sqlite3.connect(self.active_playlist_path,
timeout=2) as db_conn: timeout=2) as db_conn:
@ -199,6 +206,7 @@ class RadioUtil:
'id': r['id'], 'id': r['id'],
'artist': double_space.sub(' ', r['artist']).strip(), 'artist': double_space.sub(' ', r['artist']).strip(),
'song': double_space.sub(' ', r['song']).strip(), 'song': double_space.sub(' ', r['song']).strip(),
'album': double_space.sub(' ', r['album']).strip(),
'genre': r['genre'] if r['genre'] else 'Unknown', 'genre': r['genre'] if r['genre'] else 'Unknown',
'artistsong': double_space.sub(' ', r['artistdashsong']).strip(), 'artistsong': double_space.sub(' ', r['artistdashsong']).strip(),
'file_path': r['file_path'], 'file_path': r['file_path'],