misc / RQ bulk downloads for TRip
This commit is contained in:
@@ -41,16 +41,16 @@ class RandMsg(FastAPI):
|
||||
db_rand_selected: int = 9
|
||||
db_rand_selected = random.choice([3])
|
||||
title_attr: str = "Unknown"
|
||||
randmsg_db_path: Optional[Union[str, LiteralString]] = None
|
||||
db_query: Optional[str] = None
|
||||
|
||||
match db_rand_selected:
|
||||
case 0:
|
||||
randmsg_db_path: Union[str, LiteralString] = os.path.join(
|
||||
randmsg_db_path = os.path.join(
|
||||
"/usr/local/share", "sqlite_dbs", "qajoke.db"
|
||||
) # For qajoke db
|
||||
db_query: str = (
|
||||
"SELECT id, ('<b>Q:</b> ' || question || '<br/><b>A:</b> ' \
|
||||
db_query = "SELECT id, ('<b>Q:</b> ' || question || '<br/><b>A:</b> ' \
|
||||
|| answer) FROM jokes ORDER BY RANDOM() LIMIT 1" # For qajoke db
|
||||
)
|
||||
title_attr = "QA Joke DB"
|
||||
case 1 | 9:
|
||||
randmsg_db_path = os.path.join(
|
||||
@@ -90,9 +90,20 @@ class RandMsg(FastAPI):
|
||||
WHERE score >= 10000 ORDER BY RANDOM() LIMIT 1"""
|
||||
title_attr = "r/jokes DB"
|
||||
|
||||
if not randmsg_db_path:
|
||||
return JSONResponse(
|
||||
content={
|
||||
"err": True,
|
||||
}
|
||||
)
|
||||
|
||||
async with sqlite3.connect(database=randmsg_db_path, timeout=1) as _db:
|
||||
async with await _db.execute(db_query) as _cursor:
|
||||
result: sqlite3.Row = await _cursor.fetchone()
|
||||
if not isinstance(_cursor, sqlite3.Cursor):
|
||||
return JSONResponse(content={"err": True})
|
||||
result: Optional[sqlite3.Row] = await _cursor.fetchone()
|
||||
if not result:
|
||||
return JSONResponse(content={"err": True})
|
||||
(result_id, result_msg) = result
|
||||
result_msg = result_msg.strip()
|
||||
return JSONResponse(
|
||||
|
110
endpoints/rip.py
110
endpoints/rip.py
@@ -4,6 +4,15 @@ from fastapi_throttle import RateLimiter
|
||||
from fastapi.responses import JSONResponse
|
||||
from utils.sr_wrapper import SRUtil
|
||||
from auth.deps import get_current_user
|
||||
from redis import Redis
|
||||
from rq import Queue
|
||||
from rq.job import Job
|
||||
from utils.rip_background import bulk_download
|
||||
from lyric_search.sources import private
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ValidBulkFetchRequest(BaseModel):
|
||||
track_ids: list[int]
|
||||
|
||||
|
||||
class RIP(FastAPI):
|
||||
@@ -16,12 +25,27 @@ class RIP(FastAPI):
|
||||
self.util = my_util
|
||||
self.trip_util = SRUtil()
|
||||
self.constants = constants
|
||||
self.redis_conn = Redis(
|
||||
host="localhost",
|
||||
port=6379,
|
||||
db=0,
|
||||
password=private.REDIS_PW,
|
||||
)
|
||||
self.task_queue = Queue(
|
||||
"dls",
|
||||
connection=self.redis_conn,
|
||||
default_result_ttl=86400,
|
||||
default_failure_ttl=86400,
|
||||
)
|
||||
self.endpoints: dict = {
|
||||
"trip/get_artists_by_name": self.artists_by_name_handler,
|
||||
"trip/get_albums_by_artist_id/{artist_id:path}": self.albums_by_artist_id_handler,
|
||||
"trip/get_tracks_by_artist_song": self.tracks_by_artist_song_handler,
|
||||
"trip/get_tracks_by_album_id/{album_id:path}": self.tracks_by_album_id_handler,
|
||||
"trip/get_track_by_id/{track_id:path}": self.track_by_id_handler,
|
||||
"trip/bulk_fetch": self.bulk_fetch_handler,
|
||||
"trip/job/{job_id:path}": self.job_status_handler,
|
||||
"trip/jobs/list": self.job_list_handler,
|
||||
}
|
||||
|
||||
for endpoint, handler in self.endpoints.items():
|
||||
@@ -29,7 +53,7 @@ class RIP(FastAPI):
|
||||
app.add_api_route(
|
||||
f"/{endpoint}",
|
||||
handler,
|
||||
methods=["GET"],
|
||||
methods=["GET"] if endpoint != "trip/bulk_fetch" else ["POST"],
|
||||
include_in_schema=True,
|
||||
dependencies=dependencies,
|
||||
)
|
||||
@@ -79,3 +103,87 @@ class RIP(FastAPI):
|
||||
if not track:
|
||||
return Response(status_code=404, content="Not found")
|
||||
return JSONResponse(content={"stream_url": track})
|
||||
|
||||
async def bulk_fetch_handler(
|
||||
self,
|
||||
data: ValidBulkFetchRequest,
|
||||
request: Request,
|
||||
user=Depends(get_current_user),
|
||||
) -> Response:
|
||||
"""Bulk fetch a list of track IDs"""
|
||||
if not data or not data.track_ids:
|
||||
return JSONResponse(
|
||||
content={
|
||||
"err": True,
|
||||
"errorText": "Invalid data",
|
||||
}
|
||||
)
|
||||
track_ids = data.track_ids
|
||||
job = self.task_queue.enqueue(bulk_download, track_ids)
|
||||
self.redis_conn.lpush("enqueued_job_ids", job.id)
|
||||
return JSONResponse(
|
||||
content={
|
||||
"job_id": job.id,
|
||||
"status": "queued",
|
||||
}
|
||||
)
|
||||
|
||||
async def job_status_handler(
|
||||
self, job_id: str, request: Request, user=Depends(get_current_user)
|
||||
):
|
||||
"""Get status and result of a single job"""
|
||||
try:
|
||||
job = Job.fetch(job_id, connection=self.redis_conn)
|
||||
except Exception:
|
||||
return JSONResponse({"error": "Job not found"}, status_code=404)
|
||||
|
||||
return {
|
||||
"id": job.id,
|
||||
"status": job.get_status(),
|
||||
"result": job.result,
|
||||
"enqueued_at": job.enqueued_at,
|
||||
"started_at": job.started_at,
|
||||
"ended_at": job.ended_at,
|
||||
}
|
||||
|
||||
async def job_list_handler(self, request: Request, user=Depends(get_current_user)):
|
||||
"""List all jobs in the queue (queued + finished, if result_ttl allows)"""
|
||||
jobs_info = []
|
||||
|
||||
# 1️⃣ Jobs still in the queue (pending)
|
||||
for job in self.task_queue.jobs:
|
||||
jobs_info.append(
|
||||
{
|
||||
"id": job.id,
|
||||
"status": job.get_status(), # queued
|
||||
"result": job.result,
|
||||
"enqueued_at": job.enqueued_at,
|
||||
"progress": job.meta.get("progress", None),
|
||||
}
|
||||
)
|
||||
|
||||
# 2️⃣ Started/running jobs tracked via enqueued_job_ids
|
||||
job_ids = self.redis_conn.lrange("enqueued_job_ids", 0, -1)
|
||||
for jid_bytes in job_ids: # type: ignore
|
||||
jid = jid_bytes.decode()
|
||||
try:
|
||||
job = Job.fetch(jid, connection=self.redis_conn)
|
||||
except Exception:
|
||||
continue # job may have completed and expired
|
||||
|
||||
status = job.get_status()
|
||||
if status in ("started", "queued", "finished"):
|
||||
# avoid duplicates for jobs already in task_queue.jobs
|
||||
if not any(j["id"] == job.id for j in jobs_info):
|
||||
jobs_info.append(
|
||||
{
|
||||
"id": job.id,
|
||||
"status": status,
|
||||
"result": job.result,
|
||||
"enqueued_at": job.enqueued_at,
|
||||
"progress": job.meta.get("progress", None),
|
||||
"tracks": job.meta.get("track_list", None),
|
||||
}
|
||||
)
|
||||
|
||||
return {"jobs": jobs_info}
|
||||
|
Reference in New Issue
Block a user