typeahead

This commit is contained in:
codey 2025-01-14 20:22:12 -05:00
parent 598478f804
commit b2bb724826

View File

@ -4,9 +4,11 @@
import importlib import importlib
import traceback import traceback
import logging import logging
import os
import urllib.parse import urllib.parse
import regex import regex
import aiohttp import aiohttp
import aiosqlite as sqlite3
from fastapi import FastAPI, HTTPException from fastapi import FastAPI, HTTPException
from pydantic import BaseModel from pydantic import BaseModel
from lyric_search_new.sources import aggregate from lyric_search_new.sources import aggregate
@ -44,6 +46,13 @@ class ValidLyricRequest(BaseModel):
} }
} }
class ValidTypeAheadRequest(BaseModel):
"""
- **query**: query string
"""
pre_query: str|None = None
query: str
class ValidLyricSearchLogRequest(BaseModel): class ValidLyricSearchLogRequest(BaseModel):
""" """
@ -52,6 +61,28 @@ class ValidLyricSearchLogRequest(BaseModel):
webradio: bool = False webradio: bool = False
class CacheUtils:
"""Lyrics Cache DB Utils"""
def __init__(self):
self.lyrics_db_path = os.path.join("/", "var", "lib",
"singerdbs", "cached_lyrics.db")
async def check_typeahead(self, s: str, pre_query: str | None = None):
"""Check s against artists stored - for typeahead"""
async with sqlite3.connect(self.lyrics_db_path,
timeout=2) as db_conn:
db_conn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
if not pre_query:
query = "SELECT distinct(artist) FROM lyrics WHERE artist LIKE ? LIMIT 15"
query_params = (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 db_conn.execute(query, query_params) as db_cursor:
return await db_cursor.fetchall()
class LyricSearch(FastAPI): class LyricSearch(FastAPI):
"""Lyric Search Endpoint""" """Lyric Search Endpoint"""
def __init__(self, app: FastAPI, util, constants, glob_state): # pylint: disable=super-init-not-called def __init__(self, app: FastAPI, util, constants, glob_state): # pylint: disable=super-init-not-called
@ -59,12 +90,15 @@ class LyricSearch(FastAPI):
self.util = util self.util = util
self.constants = constants self.constants = constants
self.glob_state = glob_state self.glob_state = glob_state
self.cache_utils = CacheUtils()
self.lyrics_engine = importlib.import_module("lyrics_engine").LyricsEngine() self.lyrics_engine = importlib.import_module("lyrics_engine").LyricsEngine()
self.endpoint_name = "lyric_search" self.endpoint_name = "lyric_search"
self.endpoint2_name = "lyric_cache_list" self.endpoint2_name = "lyric_cache_list"
self.endpoints = { self.endpoints = {
"typeahead/artist": self.artist_typeahead_handler,
"typeahead/song": self.song_typeahead_handler,
"lyric_search": self.lyric_search_handler, "lyric_search": self.lyric_search_handler,
"lyric_cache_list": self.lyric_cache_list_handler, "lyric_cache_list": self.lyric_cache_list_handler,
"lyric_search_history": self.lyric_search_log_handler, "lyric_search_history": self.lyric_search_log_handler,
@ -96,6 +130,32 @@ class LyricSearch(FastAPI):
'data': await self.lyrics_engine.listCacheEntries() 'data': await self.lyrics_engine.listCacheEntries()
} }
async def artist_typeahead_handler(self, data: ValidTypeAheadRequest):
"""Artist Type Ahead Handler"""
if not isinstance(data.query, str) or len(data.query) < 2:
return {
'err': True,
'errorText': 'Invalid request',
}
query = data.query
typeahead_result = await self.cache_utils.check_typeahead(query)
typeahead_list = [str(r.get('artist')) for r in typeahead_result]
return typeahead_list
async def song_typeahead_handler(self, data: ValidTypeAheadRequest):
"""Song Type Ahead Handler"""
if not isinstance(data.pre_query, str) or len(data.pre_query) < 2\
or not isinstance(data.query, str) or len(data.query) < 2:
return {
'err': True,
'errorText': 'Invalid request',
}
pre_query = data.pre_query
query = data.query
typeahead_result = await self.cache_utils.check_typeahead(query, pre_query)
typeahead_list = [str(r.get('song')) for r in typeahead_result]
return typeahead_list
async def lyric_search_log_handler(self, data: ValidLyricSearchLogRequest): async def lyric_search_log_handler(self, data: ValidLyricSearchLogRequest):
"""Lyric Search Log Handler""" """Lyric Search Log Handler"""
include_radio = data.webradio include_radio = data.webradio