cleanup
This commit is contained in:
@ -2,22 +2,16 @@
|
||||
|
||||
import logging
|
||||
import traceback
|
||||
import os
|
||||
import aiosqlite as sqlite3
|
||||
import time
|
||||
import random
|
||||
import asyncio
|
||||
import regex
|
||||
import music_tag
|
||||
from . import radio_util
|
||||
from .constructors import ValidRadioNextRequest, ValidRadioReshuffleRequest, ValidRadioQueueShiftRequest,\
|
||||
ValidRadioQueueRemovalRequest, ValidRadioSongRequest,\
|
||||
ValidRadioQueueGetRequest, RadioException
|
||||
ValidRadioQueueRemovalRequest, ValidRadioSongRequest, RadioException
|
||||
from uuid import uuid4 as uuid
|
||||
from typing import Optional, LiteralString
|
||||
from typing import Optional
|
||||
from fastapi import FastAPI, BackgroundTasks, Request, Response, HTTPException
|
||||
from fastapi.responses import RedirectResponse
|
||||
from aiohttp import ClientSession, ClientTimeout
|
||||
from fastapi.responses import RedirectResponse, JSONResponse
|
||||
# pylint: disable=bare-except, broad-exception-caught, invalid-name
|
||||
|
||||
|
||||
@ -28,8 +22,9 @@ TODO:
|
||||
|
||||
class Radio(FastAPI):
|
||||
"""Radio Endpoints"""
|
||||
def __init__(self, app: FastAPI, my_util, constants) -> None: # pylint: disable=super-init-not-called
|
||||
self.app = app
|
||||
def __init__(self, app: FastAPI,
|
||||
my_util, constants) -> None: # pylint: disable=super-init-not-called
|
||||
self.app: FastAPI = app
|
||||
self.util = my_util
|
||||
self.constants = constants
|
||||
self.radio_util = radio_util.RadioUtil(self.constants)
|
||||
@ -55,7 +50,8 @@ class Radio(FastAPI):
|
||||
asyncio.get_event_loop().run_until_complete(self.radio_util.load_playlist())
|
||||
asyncio.get_event_loop().run_until_complete(self.radio_util._ls_skip())
|
||||
|
||||
async def radio_skip(self, data: ValidRadioNextRequest, request: Request) -> bool:
|
||||
async def radio_skip(self, data: ValidRadioNextRequest,
|
||||
request: Request) -> JSONResponse:
|
||||
"""
|
||||
Skip to the next track in the queue, or to uuid specified in skipTo if provided
|
||||
"""
|
||||
@ -65,17 +61,28 @@ class Radio(FastAPI):
|
||||
if data.skipTo:
|
||||
queue_item = self.radio_util.get_queue_item_by_uuid(data.skipTo)
|
||||
if not queue_item:
|
||||
return False
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'No such queue item.',
|
||||
})
|
||||
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()
|
||||
return await self.radio_util._ls_skip()
|
||||
skip_result: bool = await self.radio_util._ls_skip()
|
||||
status_code = 200 if skip_result else 500
|
||||
return JSONResponse(status_code=status_code, content={
|
||||
'success': skip_result,
|
||||
})
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
return False
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'General failure.',
|
||||
})
|
||||
|
||||
|
||||
async def radio_reshuffle(self, data: ValidRadioReshuffleRequest, request: Request) -> dict:
|
||||
async def radio_reshuffle(self, data: ValidRadioReshuffleRequest,
|
||||
request: Request) -> JSONResponse:
|
||||
"""
|
||||
Reshuffle the play queue
|
||||
"""
|
||||
@ -83,16 +90,16 @@ class Radio(FastAPI):
|
||||
raise HTTPException(status_code=403, detail="Unauthorized")
|
||||
|
||||
random.shuffle(self.radio_util.active_playlist)
|
||||
return {
|
||||
return JSONResponse(content={
|
||||
'ok': True
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
async def radio_get_queue(self, request: Request, limit: Optional[int] = 15_000) -> dict:
|
||||
async def radio_get_queue(self, request: Request,
|
||||
limit: Optional[int] = 15_000) -> JSONResponse:
|
||||
"""
|
||||
Get current play queue, up to limit [default: 15k]
|
||||
"""
|
||||
|
||||
queue_out: list[dict] = []
|
||||
for x, item in enumerate(self.radio_util.active_playlist[0:limit]):
|
||||
queue_out.append({
|
||||
@ -104,45 +111,52 @@ class Radio(FastAPI):
|
||||
'artistsong': item.get('artistsong'),
|
||||
'duration': item.get('duration'),
|
||||
})
|
||||
return {
|
||||
return JSONResponse(content={
|
||||
'items': queue_out
|
||||
}
|
||||
})
|
||||
|
||||
async def radio_queue_shift(self, data: ValidRadioQueueShiftRequest, request: Request) -> dict:
|
||||
"""Shift position of a UUID within the queue [currently limited to playing next or immediately]"""
|
||||
async def radio_queue_shift(self, data: ValidRadioQueueShiftRequest,
|
||||
request: Request) -> JSONResponse:
|
||||
"""
|
||||
Shift position of a UUID within the queue
|
||||
[currently limited to playing next or immediately]
|
||||
"""
|
||||
if not self.util.check_key(path=request.url.path, req_type=4, key=data.key):
|
||||
raise HTTPException(status_code=403, detail="Unauthorized")
|
||||
|
||||
queue_item = self.radio_util.get_queue_item_by_uuid(data.uuid)
|
||||
if not queue_item:
|
||||
return {
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'Queue item not found.',
|
||||
}
|
||||
})
|
||||
(x, item) = queue_item
|
||||
self.radio_util.active_playlist.pop(x)
|
||||
self.radio_util.active_playlist.insert(0, item)
|
||||
if not data.next:
|
||||
await self.radio_util._ls_skip()
|
||||
return {
|
||||
return JSONResponse(content={
|
||||
'ok': True,
|
||||
}
|
||||
})
|
||||
|
||||
async def radio_queue_remove(self, data: ValidRadioQueueRemovalRequest, request: Request) -> dict:
|
||||
"""Remove an item from the current play queue"""
|
||||
async def radio_queue_remove(self, data: ValidRadioQueueRemovalRequest,
|
||||
request: Request) -> JSONResponse:
|
||||
"""
|
||||
Remove an item from the current play queue
|
||||
"""
|
||||
if not self.util.check_key(path=request.url.path, req_type=4, key=data.key):
|
||||
raise HTTPException(status_code=403, detail="Unauthorized")
|
||||
|
||||
queue_item = self.radio_util.get_queue_item_by_uuid(data.uuid)
|
||||
if not queue_item:
|
||||
return {
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'Queue item not found.',
|
||||
}
|
||||
})
|
||||
self.radio_util.active_playlist.pop(queue_item[0])
|
||||
return {
|
||||
return JSONResponse(content={
|
||||
'ok': True,
|
||||
}
|
||||
})
|
||||
|
||||
async def album_art_handler(self, request: Request, track_id: Optional[int] = None) -> Response:
|
||||
"""
|
||||
@ -164,22 +178,22 @@ class Radio(FastAPI):
|
||||
return RedirectResponse(url="https://codey.lol/images/radio_art_default.jpg",
|
||||
status_code=302)
|
||||
|
||||
async def radio_now_playing(self, request: Request) -> dict:
|
||||
"""Get currently playing track info"""
|
||||
async def radio_now_playing(self, request: Request) -> JSONResponse:
|
||||
"""
|
||||
Get currently playing track info
|
||||
"""
|
||||
ret_obj: dict = {**self.radio_util.now_playing}
|
||||
cur_elapsed: int = self.radio_util.now_playing.get('elapsed', -1)
|
||||
cur_duration: int = self.radio_util.now_playing.get('duration', 999999)
|
||||
try:
|
||||
ret_obj['elapsed'] = int(time.time()) - ret_obj['start']
|
||||
except KeyError:
|
||||
traceback.print_exc()
|
||||
ret_obj['elapsed'] = 0
|
||||
ret_obj.pop('file_path')
|
||||
return ret_obj
|
||||
return JSONResponse(content=ret_obj)
|
||||
|
||||
|
||||
async def radio_get_next(self, data: ValidRadioNextRequest, request: Request,
|
||||
background_tasks: BackgroundTasks) -> Optional[dict]:
|
||||
background_tasks: BackgroundTasks) -> JSONResponse:
|
||||
"""
|
||||
Get next track
|
||||
Track will be removed from the queue in the process.
|
||||
@ -189,13 +203,19 @@ class Radio(FastAPI):
|
||||
if not isinstance(self.radio_util.active_playlist, list) or not self.radio_util.active_playlist:
|
||||
await self.radio_util.load_playlist()
|
||||
await self.radio_util._ls_skip()
|
||||
return None
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'General failure occurred, prompting playlist reload.',
|
||||
})
|
||||
next = self.radio_util.active_playlist.pop(0)
|
||||
if not isinstance(next, dict):
|
||||
logging.critical("next is of type: %s, reloading playlist...", type(next))
|
||||
await self.radio_util.load_playlist()
|
||||
await self.radio_util._ls_skip()
|
||||
return None
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'General failure occurred, prompting playlist reload.',
|
||||
})
|
||||
|
||||
duration: int = next['duration']
|
||||
time_started: int = int(time.time())
|
||||
@ -216,37 +236,41 @@ class Radio(FastAPI):
|
||||
try:
|
||||
if not await self.radio_util.get_album_art(file_path=next['file_path']):
|
||||
album_art = await self.radio_util.get_album_art(file_path=next['file_path'])
|
||||
if not album_art:
|
||||
return None
|
||||
await self.radio_util.cache_album_art(next['id'], album_art)
|
||||
if album_art:
|
||||
await self.radio_util.cache_album_art(next['id'], album_art)
|
||||
else:
|
||||
logging.debug("Could not read album art for %s",
|
||||
next['file_path'])
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return next
|
||||
return JSONResponse(content=next)
|
||||
|
||||
|
||||
async def radio_request(self, data: ValidRadioSongRequest, request: Request) -> dict:
|
||||
"""Song request handler"""
|
||||
async def radio_request(self, data: ValidRadioSongRequest, request: Request) -> JSONResponse:
|
||||
"""
|
||||
Song request handler
|
||||
"""
|
||||
if not self.util.check_key(path=request.url.path, req_type=4, key=data.key):
|
||||
raise HTTPException(status_code=403, detail="Unauthorized")
|
||||
artistsong: Optional[str] = data.artistsong
|
||||
artist: Optional[str] = data.artist
|
||||
song: Optional[str] = data.song
|
||||
if artistsong and (artist or song):
|
||||
return {
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'Invalid request',
|
||||
}
|
||||
})
|
||||
if not artistsong and (not artist or not song):
|
||||
return {
|
||||
return JSONResponse(status_code=500, content={
|
||||
'err': True,
|
||||
'errorText': 'Invalid request',
|
||||
}
|
||||
})
|
||||
|
||||
search: bool = await self.radio_util.search_playlist(artistsong=artistsong,
|
||||
artist=artist,
|
||||
song=song)
|
||||
if data.alsoSkip:
|
||||
await self.radio_util._ls_skip()
|
||||
return {
|
||||
return JSONResponse(content={
|
||||
'result': search
|
||||
}
|
||||
})
|
Reference in New Issue
Block a user