misc
This commit is contained in:
parent
6c29c6fede
commit
58ba471b5e
14
base.py
14
base.py
@ -12,6 +12,7 @@ from lyric_search.sources import redis_cache
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
app = FastAPI(
|
||||
title="codey.lol API",
|
||||
@ -85,7 +86,9 @@ routes: dict = {
|
||||
"lastfm": importlib.import_module("endpoints.lastfm").LastFM(app, util, constants),
|
||||
"yt": importlib.import_module("endpoints.yt").YT(app, util, constants),
|
||||
"karma": importlib.import_module("endpoints.karma").Karma(app, util, constants),
|
||||
"radio": importlib.import_module("endpoints.radio").Radio(app, util, constants),
|
||||
"radio": importlib.import_module("endpoints.radio").Radio(
|
||||
app, util, constants, loop
|
||||
),
|
||||
"mgr": importlib.import_module("endpoints.mgr.mgr_test").Mgr(app, util, constants),
|
||||
}
|
||||
|
||||
@ -105,5 +108,14 @@ End Actionable Routes
|
||||
Startup
|
||||
"""
|
||||
|
||||
|
||||
async def on_start():
|
||||
uvicorn_access_logger = logging.getLogger("uvicorn.access")
|
||||
uvicorn_access_logger.disabled = True
|
||||
|
||||
|
||||
app.add_event_handler("startup", on_start)
|
||||
|
||||
|
||||
redis = redis_cache.RedisCache()
|
||||
loop.create_task(redis.create_index())
|
||||
|
@ -84,7 +84,9 @@ class KarmaDB:
|
||||
"INSERT INTO karma(keyword, score, last_change) VALUES(?, ?, ?)"
|
||||
)
|
||||
friendly_flag: str = "++" if not flag else "--"
|
||||
audit_message: str = f"{granter} adjusted karma for {keyword} @ {datetime.datetime.now().isoformat()}: {friendly_flag}"
|
||||
audit_message: str = (
|
||||
f"{granter} adjusted karma for {keyword} @ {datetime.datetime.now().isoformat()}: {friendly_flag}"
|
||||
)
|
||||
audit_query: str = (
|
||||
"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:
|
||||
await self.notifier.send(
|
||||
f"ERROR @ {__file__.rsplit('/', maxsplit=1)[-1]}",
|
||||
f"ERROR @ {__file__.rsplit("/", maxsplit=1)[-1]}",
|
||||
f"Unknown request source: {data.src}",
|
||||
)
|
||||
return JSONResponse(
|
||||
|
@ -21,11 +21,12 @@ from fastapi.responses import RedirectResponse, JSONResponse
|
||||
class Radio(FastAPI):
|
||||
"""Radio Endpoints"""
|
||||
|
||||
def __init__(self, app: FastAPI, my_util, constants) -> None:
|
||||
def __init__(self, app: FastAPI, my_util, constants, loop) -> None:
|
||||
self.app: FastAPI = app
|
||||
self.util = my_util
|
||||
self.constants = constants
|
||||
self.radio_util = radio_util.RadioUtil(self.constants)
|
||||
self.loop = loop
|
||||
self.radio_util = radio_util.RadioUtil(self.constants, self.loop)
|
||||
self.playlist_loaded: bool = False
|
||||
|
||||
self.endpoints: dict = {
|
||||
@ -57,10 +58,7 @@ class Radio(FastAPI):
|
||||
|
||||
async def on_start(self) -> None:
|
||||
logging.info("radio: Initializing")
|
||||
with Pool() as pool:
|
||||
res = pool.apply_async(self.radio_util.load_playlist)
|
||||
if res:
|
||||
await self.radio_util._ls_skip()
|
||||
self.loop.run_in_executor(None, self.radio_util.load_playlist)
|
||||
|
||||
async def radio_skip(
|
||||
self, data: ValidRadioNextRequest, request: Request
|
||||
@ -86,8 +84,8 @@ class Radio(FastAPI):
|
||||
self.radio_util.active_playlist = self.radio_util.active_playlist[
|
||||
queue_item[0] :
|
||||
]
|
||||
if not self.radio_util.active_playlist:
|
||||
await self.radio_util.load_playlist()
|
||||
# if not self.radio_util.active_playlist:
|
||||
# self.radio_util.load_playlist()
|
||||
skip_result: bool = await self.radio_util._ls_skip()
|
||||
status_code = 200 if skip_result else 500
|
||||
return JSONResponse(
|
||||
@ -154,12 +152,15 @@ class Radio(FastAPI):
|
||||
"duration": item.get("duration"),
|
||||
}
|
||||
)
|
||||
fallback_playlist_len: int = len(
|
||||
self.radio_util.active_playlist
|
||||
) # Used if search term is provided
|
||||
out_json = {
|
||||
"draw": data.draw,
|
||||
"recordsTotal": len(queue_full),
|
||||
"recordsFiltered": (
|
||||
len(queue_full) if not data.search else len(queue_full)
|
||||
), # todo: implement search
|
||||
"recordsTotal": (
|
||||
len(queue_full) if not data.search else fallback_playlist_len
|
||||
),
|
||||
"recordsFiltered": (len(queue_full)),
|
||||
"items": queue_out,
|
||||
}
|
||||
return JSONResponse(content=out_json)
|
||||
@ -236,7 +237,7 @@ class Radio(FastAPI):
|
||||
if not track_id:
|
||||
track_id = self.radio_util.now_playing.get("id")
|
||||
logging.debug("Seeking album art with trackId: %s", track_id)
|
||||
album_art: Optional[bytes] = await self.radio_util.get_album_art(
|
||||
album_art: Optional[bytes] = self.radio_util.get_album_art(
|
||||
track_id=track_id
|
||||
)
|
||||
if not album_art:
|
||||
@ -312,7 +313,9 @@ class Radio(FastAPI):
|
||||
if len(self.radio_util.active_playlist) > 1:
|
||||
self.radio_util.active_playlist.append(next) # Push to end of playlist
|
||||
else:
|
||||
await self.radio_util.load_playlist()
|
||||
with Pool() as pool:
|
||||
pool.apply_async(self.radio_util.load_playlist())
|
||||
pool.close()
|
||||
|
||||
self.radio_util.now_playing = next
|
||||
next["start"] = time_started
|
||||
@ -323,9 +326,9 @@ class Radio(FastAPI):
|
||||
logging.info("radio_get_next Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
try:
|
||||
album_art = await self.radio_util.get_album_art(track_id=next["id"])
|
||||
album_art = self.radio_util.get_album_art(track_id=next["id"])
|
||||
if not album_art:
|
||||
await self.radio_util.cache_album_art(next["id"], next["file_path"])
|
||||
self.radio_util.cache_album_art(next["id"], next["file_path"])
|
||||
except Exception as e:
|
||||
logging.info("radio_get_next Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
@ -364,7 +367,7 @@ class Radio(FastAPI):
|
||||
},
|
||||
)
|
||||
|
||||
search: bool = await self.radio_util.search_playlist(
|
||||
search: bool = self.radio_util.search_playlist(
|
||||
artistsong=artistsong, artist=artist, song=song
|
||||
)
|
||||
if data.alsoSkip:
|
||||
@ -386,9 +389,7 @@ class Radio(FastAPI):
|
||||
"errorText": "Invalid request.",
|
||||
},
|
||||
)
|
||||
typeahead: Optional[list[str]] = await self.radio_util.trackdb_typeahead(
|
||||
data.query
|
||||
)
|
||||
typeahead: Optional[list[str]] = self.radio_util.trackdb_typeahead(data.query)
|
||||
if not typeahead:
|
||||
return JSONResponse(content=[])
|
||||
return JSONResponse(content=typeahead)
|
||||
|
@ -35,7 +35,7 @@ class RandMsg(FastAPI):
|
||||
short = data.short
|
||||
if short:
|
||||
db_rand_selected: int = 9
|
||||
db_rand_selected = random.choice([0, 1, 3])
|
||||
db_rand_selected = random.choice([3])
|
||||
title_attr: str = "Unknown"
|
||||
|
||||
match db_rand_selected:
|
||||
|
@ -113,7 +113,9 @@ class Transcriptions(FastAPI):
|
||||
db_path: Union[str, LiteralString] = os.path.join(
|
||||
"/usr/local/share", "sqlite_dbs", "sp.db"
|
||||
)
|
||||
db_query: str = """SELECT ("S" || Season || "E" || Episode || " " || Title), Character, Line FROM SP_DAT WHERE ID = ?"""
|
||||
db_query: str = (
|
||||
"""SELECT ("S" || Season || "E" || Episode || " " || Title), Character, Line FROM SP_DAT WHERE ID = ?"""
|
||||
)
|
||||
case 1:
|
||||
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"""
|
||||
|
@ -89,8 +89,10 @@ class Cache:
|
||||
logging.debug(
|
||||
"Checking whether %s is already stored", artistsong.replace("\n", " - ")
|
||||
)
|
||||
check_query: str = 'SELECT id, artist, song FROM lyrics WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
||||
check_query: str = (
|
||||
'SELECT id, artist, song FROM lyrics WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
||||
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 1'
|
||||
)
|
||||
artistsong_split = artistsong.split("\n", maxsplit=1)
|
||||
artist = artistsong_split[0].lower()
|
||||
song = artistsong_split[1].lower()
|
||||
@ -211,10 +213,8 @@ class Cache:
|
||||
lyrics = regex.sub(r"(<br>|\n|\r\n)", " / ", lyr_result.lyrics.strip())
|
||||
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(?, ?, ?, ?, ?, ?, ?)"
|
||||
)
|
||||
params = (
|
||||
lyr_result.src,
|
||||
time.time(),
|
||||
@ -233,8 +233,8 @@ class Cache:
|
||||
await db_conn.commit()
|
||||
logging.info("Stored %s to SQLite!", artistsong.replace("\n", " - "))
|
||||
return _cursor.lastrowid
|
||||
except:
|
||||
logging.critical("Cache storage error!")
|
||||
except Exception as e:
|
||||
logging.critical("Cache storage error: %s", str(e))
|
||||
traceback.print_exc()
|
||||
|
||||
async def search(self, artist: str, song: str, **kwargs) -> Optional[LyricsResult]:
|
||||
@ -258,8 +258,10 @@ class Cache:
|
||||
|
||||
if artist == "!" and song == "!":
|
||||
random_search = True
|
||||
search_query: str = "SELECT id, artist, song, lyrics, src, confidence\
|
||||
search_query: str = (
|
||||
"SELECT id, artist, song, lyrics, src, confidence\
|
||||
FROM lyrics ORDER BY RANDOM() LIMIT 1"
|
||||
)
|
||||
|
||||
logging.info("Searching %s - %s on %s", artist, song, self.label)
|
||||
|
||||
@ -304,7 +306,8 @@ class Cache:
|
||||
)
|
||||
await self.redis_cache.increment_found_count(self.label)
|
||||
return matched
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug(str(e))
|
||||
pass
|
||||
|
||||
"""SQLite: Fallback"""
|
||||
@ -317,9 +320,11 @@ class Cache:
|
||||
self.cache_pre_query
|
||||
) as _db_cursor:
|
||||
if not random_search:
|
||||
search_query: str = 'SELECT id, artist, song, lyrics, src, confidence FROM lyrics\
|
||||
search_query: str = (
|
||||
'SELECT id, artist, song, lyrics, src, confidence FROM lyrics\
|
||||
WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
||||
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 10'
|
||||
)
|
||||
search_params: tuple = (
|
||||
artist.strip(),
|
||||
song.strip(),
|
||||
@ -354,5 +359,6 @@ class Cache:
|
||||
matched.time = time_diff
|
||||
await self.redis_cache.increment_found_count(self.label)
|
||||
return matched
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.info("Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
|
@ -1,5 +1,5 @@
|
||||
from difflib import SequenceMatcher
|
||||
from typing import List, Optional, Union, Any
|
||||
from typing import List, Optional
|
||||
import logging
|
||||
import regex
|
||||
from regex import Pattern
|
||||
|
@ -50,7 +50,8 @@ class LastFM:
|
||||
.split("<a href")[0],
|
||||
}
|
||||
return ret_obj
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug("Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
return {
|
||||
"err": "Failed",
|
||||
@ -101,8 +102,9 @@ class LastFM:
|
||||
"album": album,
|
||||
}
|
||||
return ret_obj
|
||||
except:
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
logging.debug("Exception: %s", str(e))
|
||||
return {
|
||||
"err": "General Failure",
|
||||
}
|
||||
@ -132,8 +134,9 @@ class LastFM:
|
||||
|
||||
return ret_obj
|
||||
|
||||
except:
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
logging.debug("Exception: %s", str(e))
|
||||
return {
|
||||
"err": "General Failure",
|
||||
}
|
||||
@ -178,7 +181,8 @@ class LastFM:
|
||||
and int(item.get("playcount")) >= 50
|
||||
]
|
||||
return ret_obj
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug("Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
return {
|
||||
"err": "Failed",
|
||||
@ -201,7 +205,8 @@ class LastFM:
|
||||
return -1
|
||||
artist_id: int = int(artist_search[0].get("id", 0))
|
||||
return artist_id
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug("Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
return -1
|
||||
|
||||
@ -252,7 +257,8 @@ class LastFM:
|
||||
"members": members,
|
||||
}
|
||||
return ret_obj
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug("Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
return {
|
||||
"err": "Failed",
|
||||
@ -284,7 +290,8 @@ class LastFM:
|
||||
"err": "Failed",
|
||||
}
|
||||
return artist_info
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug("Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
return {
|
||||
"err": "Failed",
|
||||
@ -337,7 +344,8 @@ class LastFM:
|
||||
}
|
||||
try:
|
||||
track_key: list = data.get("tracks", None).get("track")
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug("Exception: %s", str(e))
|
||||
track_key = []
|
||||
if isinstance(track_key, list):
|
||||
ret_obj["tracks"] = [
|
||||
@ -357,7 +365,8 @@ class LastFM:
|
||||
}
|
||||
]
|
||||
return ret_obj
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug("Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
return {
|
||||
"err": "Failed",
|
||||
|
@ -34,8 +34,9 @@ class RadioUtil:
|
||||
Radio Utils
|
||||
"""
|
||||
|
||||
def __init__(self, constants) -> None:
|
||||
def __init__(self, constants, loop) -> None:
|
||||
self.constants = constants
|
||||
self.loop = loop
|
||||
self.gpt = gpt.GPT(self.constants)
|
||||
self.ls_uri: str = self.constants.LS_URI
|
||||
self.sqlite_exts: list[str] = [
|
||||
@ -51,12 +52,12 @@ class RadioUtil:
|
||||
"/usr/local/share", "sqlite_dbs", "track_album_art.db"
|
||||
)
|
||||
self.playback_genres: list[str] = [
|
||||
# "post-hardcore",
|
||||
# "post hardcore",
|
||||
# "metalcore",
|
||||
# "deathcore",
|
||||
# "edm",
|
||||
# "electronic",
|
||||
"post-hardcore",
|
||||
"post hardcore",
|
||||
"metalcore",
|
||||
"deathcore",
|
||||
"edm",
|
||||
"electronic",
|
||||
]
|
||||
self.active_playlist: list[dict] = []
|
||||
self.playlist_loaded: bool = False
|
||||
@ -161,9 +162,11 @@ class RadioUtil:
|
||||
if not artistsong and (not artist or not song):
|
||||
raise RadioException("No query provided")
|
||||
try:
|
||||
search_query: str = 'SELECT id, artist, song, (artist || " - " || song) AS artistsong, album, file_path, duration FROM tracks\
|
||||
search_query: str = (
|
||||
'SELECT id, artist, song, (artist || " - " || song) AS artistsong, album, file_path, duration FROM tracks\
|
||||
WHERE editdist3((lower(artist) || " " || lower(song)), (? || " " || ?))\
|
||||
<= 410 ORDER BY editdist3((lower(artist) || " " || lower(song)), ?) ASC LIMIT 1'
|
||||
)
|
||||
if artistsong:
|
||||
artistsong_split: list = artistsong.split(" - ", maxsplit=1)
|
||||
(search_artist, search_song) = tuple(artistsong_split)
|
||||
@ -255,7 +258,9 @@ class RadioUtil:
|
||||
for pair in pairs:
|
||||
try:
|
||||
artist, genre = pair
|
||||
query: str = "INSERT OR IGNORE INTO artist_genre (artist, genre) VALUES(?, ?)"
|
||||
query: str = (
|
||||
"INSERT OR IGNORE INTO artist_genre (artist, genre) VALUES(?, ?)"
|
||||
)
|
||||
params: tuple[str, str] = (artist, genre)
|
||||
res = _db.execute(query, params)
|
||||
if isinstance(res.lastrowid, int):
|
||||
@ -405,11 +410,12 @@ class RadioUtil:
|
||||
len(self.active_playlist),
|
||||
)
|
||||
self.playlist_loaded = True
|
||||
self.loop.create_task(self._ls_skip())
|
||||
except Exception as e:
|
||||
logging.info("Playlist load failed: %s", str(e))
|
||||
traceback.print_exc()
|
||||
|
||||
async def cache_album_art(self, track_id: int, file_path: str) -> None:
|
||||
def cache_album_art(self, track_id: int, file_path: str) -> None:
|
||||
"""
|
||||
Cache Album Art to SQLite DB
|
||||
Args:
|
||||
@ -445,7 +451,7 @@ class RadioUtil:
|
||||
logging.debug("cache_album_art Exception: %s", str(e))
|
||||
traceback.print_exc()
|
||||
|
||||
async def get_album_art(self, track_id: int) -> Optional[bytes]:
|
||||
def get_album_art(self, track_id: int) -> Optional[bytes]:
|
||||
"""
|
||||
Get Album Art
|
||||
Args:
|
||||
|
Loading…
x
Reference in New Issue
Block a user