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 - **query**: query string
""" """
pre_query: Optional[str] = None
query: str query: str
""" """

View File

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

View File

@ -186,15 +186,15 @@ class RadioUtil:
LIMITED TO ONE/SMALL SUBSET OF GENRES 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\ # 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' # 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... LIMITED TO ONE/SOME ARTISTS...
""" """
# db_query = 'SELECT distinct(artist || " - " || song) AS artistdashsong, id, artist, song, album, 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 "%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' 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, async with sqlite3.connect(self.active_playlist_path,
timeout=2) as db_conn: timeout=2) as db_conn: