typeahead/various

This commit is contained in:
codey 2025-04-08 20:15:32 -04:00
parent c4ae59ca9f
commit ca883b2974
4 changed files with 34 additions and 52 deletions

View File

@ -195,7 +195,6 @@ class ValidTypeAheadRequest(BaseModel):
"""
- **query**: query string
"""
pre_query: Optional[str] = None
query: str
"""

View File

@ -5,7 +5,7 @@ import regex
import aiosqlite as sqlite3
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from typing import LiteralString, Optional, Union
from typing import LiteralString, Optional, Union, Iterable
from regex import Pattern
from .constructors import ValidTypeAheadRequest, ValidLyricRequest
from lyric_search.constructors import LyricsResult
@ -20,22 +20,23 @@ class CacheUtils:
self.lyrics_db_path: LiteralString = os.path.join("/usr/local/share",
"sqlite_dbs", "cached_lyrics.db")
async def check_typeahead(self, s: str,
pre_query: Optional[str] = None) -> list[dict]:
"""
Check s against artists stored - for typeahead
"""
async def check_typeahead(self, query: str) -> Optional[list[str]]:
"""Lyric Search Typeahead DB Handler"""
if not query:
return None
async with sqlite3.connect(self.lyrics_db_path,
timeout=2) as db_conn:
db_conn.row_factory = sqlite3.Row
if not pre_query:
query: str = "SELECT distinct(artist) FROM lyrics WHERE artist LIKE ? LIMIT 15"
query_params: tuple = (f"%{s}%",)
else:
query = "SELECT distinct(song) FROM lyrics WHERE artist LIKE ? AND song LIKE ? LIMIT 15"
query_params = (f"%{pre_query}%", f"%{s}%",)
async with await db_conn.execute(query, query_params) as db_cursor:
return await db_cursor.fetchall()
timeout=1) as _db:
_db.row_factory = sqlite3.Row
db_query: str = """SELECT DISTINCT(LOWER(TRIM(artist) || " - " || TRIM(song))),\
(TRIM(artist) || " - " || TRIM(song)) as ret FROM lyrics WHERE\
ret LIKE ? LIMIT 100"""
db_params: tuple[str] = (f"%%%{query}%%%",)
async with _db.execute(db_query, db_params) as _cursor:
result: Iterable[sqlite3.Row] = await _cursor.fetchall()
out_result = [
str(r['ret']) for r in result
]
return out_result
class LyricSearch(FastAPI):
@ -52,8 +53,7 @@ class LyricSearch(FastAPI):
self.endpoints: dict = {
"typeahead/artist": self.artist_typeahead_handler,
"typeahead/song": self.song_typeahead_handler,
"typeahead/lyrics": self.typeahead_handler,
"lyric_search": self.lyric_search_handler, # Preserving old endpoint path temporarily
"lyric/search": self.lyric_search_handler,
}
@ -71,39 +71,22 @@ class LyricSearch(FastAPI):
for endpoint, handler in self.endpoints.items():
_schema_include = endpoint in ["lyric/search"]
app.add_api_route(f"/{endpoint}", handler, methods=["POST"], include_in_schema=_schema_include)
async def artist_typeahead_handler(self, data: ValidTypeAheadRequest) -> JSONResponse:
async def typeahead_handler(self, data: ValidTypeAheadRequest) -> JSONResponse:
"""
Artist Type Ahead Handler
- **query**: The query
Lyric search typeahead handler
- **query**: Typeahead query
"""
if not isinstance(data.query, str) or len(data.query) < 2:
if not isinstance(data.query, str):
return JSONResponse(status_code=500, content={
'err': True,
'errorText': 'Invalid request',
'errorText': 'Invalid request.',
})
query: str = data.query
typeahead_result: list[dict] = await self.cache_utils.check_typeahead(query)
typeahead_list: list[str] = [str(r['artist']) for r in typeahead_result]
return JSONResponse(content=typeahead_list)
async def song_typeahead_handler(self, data: ValidTypeAheadRequest) -> JSONResponse:
"""
Song Type Ahead Handler
- **query**: The query
- **pre_query**: The pre-query (artist)
"""
if not isinstance(data.pre_query, str)\
or not isinstance(data.query, str):
return JSONResponse(status_code=500, content={
'err': True,
'errorText': 'Invalid request',
})
pre_query: str = data.pre_query
query: str = data.query
typeahead_result: list[dict] = await self.cache_utils.check_typeahead(query, pre_query)
typeahead_list: list[str] = [str(r['song']) for r in typeahead_result]
return JSONResponse(content=typeahead_list)
typeahead: Optional[list[str]] = await self.cache_utils.check_typeahead(data.query)
if not typeahead:
return JSONResponse(content=[])
return JSONResponse(content=typeahead)
async def lyric_search_handler(self, data: ValidLyricRequest) -> JSONResponse:
"""

View File

@ -300,7 +300,7 @@ class Radio(FastAPI):
async def radio_typeahead(self, data: ValidRadioTypeaheadRequest,
request: Request) -> JSONResponse:
"""
Radio typehead handler
Radio typeahead handler
- **query**: Typeahead query
"""
if not isinstance(data.query, str):

View File

@ -186,15 +186,15 @@ class RadioUtil:
LIMITED TO ONE/SMALL SUBSET OF GENRES
"""
db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\
WHERE genre LIKE "%edm%" OR artist LIKE "%sullivan king%" OR artist LIKE "%kai wachi%" OR artist LIKE "%kayzo%" ORDER BY RANDOM()' #ORDER BY artist DESC, album ASC, song ASC'
# db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\
# WHERE genre LIKE "%edm%" OR artist LIKE "%sullivan king%" OR artist LIKE "%kai wachi%" OR artist LIKE "%kayzo%" ORDER BY RANDOM()' #ORDER BY artist DESC, album ASC, song ASC'
"""
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 "%a scent like wolves%" OR artist LIKE "%bad wolves%" or artist LIKE "%oceans%" OR artist LIKE "%oh,%" OR artist LIKE "%august%" OR artist LIKE "%periphery%") AND (NOT song LIKE "%%stripped%%" AND NOT song LIKE "%(2022)%" AND NOT song LIKE "%(live%%" AND NOT song LIKE "%%acoustic%%" AND NOT song LIKE "%%instrumental%%" AND NOT song LIKE "%%remix%%" AND NOT song LIKE "%%reimagined%%" AND NOT song LIKE "%%alternative%%" AND NOT song LIKE "%%unzipped%%") GROUP BY artistdashsong ORDER BY RANDOM()'# ORDER BY album ASC, id ASC'
db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, genre, file_path, duration FROM tracks\
WHERE (artist LIKE "%chunk! no, %" OR artist LIKE "woe,%" OR artist LIKE "%woe is%") AND (NOT song LIKE "%%stripped%%" AND NOT song LIKE "%(2022)%" AND NOT song LIKE "%(live%%" AND NOT song LIKE "%%acoustic%%" AND NOT song LIKE "%%instrumental%%" AND NOT song LIKE "%%remix%%" AND NOT song LIKE "%%reimagined%%" AND NOT song LIKE "%%alternative%%" AND NOT song LIKE "%%unzipped%%") GROUP BY artistdashsong ORDER BY RANDOM()'# ORDER BY album ASC, id ASC'
async with sqlite3.connect(self.active_playlist_path,
timeout=2) as db_conn: