This commit is contained in:
2024-11-29 15:33:12 -05:00
parent 57f5564fe6
commit 6b62757dad
6 changed files with 230 additions and 35 deletions

View File

@ -40,6 +40,7 @@ class AI(FastAPI):
"""
/ai/base/
AI BASE Request
(Requires key)
"""
if not self.util.check_key(request.url.path, request.headers.get('X-Authd-With')):
@ -70,6 +71,7 @@ class AI(FastAPI):
"""
/ai/openai/
AI Request
(Requires key)
"""
if not self.util.check_key(request.url.path, request.headers.get('X-Authd-With')):
@ -145,9 +147,16 @@ class AI(FastAPI):
await self.glob_state.increment_counter('claude_ai_requests')
response = await request.json()
print(f"Response: {response}")
result = {
'resp': response.get('content')[0].get('text').strip()
}
if response.get('type') == 'error':
error_type = response.get('error').get('type')
error_message = response.get('error').get('message')
result = {
'resp': f"{error_type} error ({error_message})"
}
else:
result = {
'resp': response.get('content')[0].get('text').strip()
}
return result
except Exception as e: # pylint: disable=broad-exception-caught
logging.error("Error: %s", e)

View File

@ -3,6 +3,8 @@
import importlib
import urllib.parse
import regex
import aiohttp
import traceback
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
@ -14,6 +16,7 @@ class ValidLyricRequest(BaseModel):
- **s**: song
- **t**: track (artist and song combined) [used only if a & s are not used]
- **extra**: include extra details in response [optional, default: false]
- **lrc**: Request LRCs?
- **sub**: text to search within lyrics, if found lyrics will begin at found verse [optional]
- **src**: the script/utility which initiated the request
"""
@ -23,6 +26,7 @@ class ValidLyricRequest(BaseModel):
t: str | None = None
sub: str | None = None
extra: bool | None = False
lrc: bool | None = False
src: str
class Config: # pylint: disable=missing-class-docstring too-few-public-methods
@ -31,37 +35,11 @@ class ValidLyricRequest(BaseModel):
"a": "eminem",
"s": "rap god",
"src": "WEB",
"extra": True
"extra": True,
"lrc": False,
}
}
class ValidLyricRequest(BaseModel):
"""
- **a**: artist
- **s**: song
- **t**: track (artist and song combined) [used only if a & s are not used]
- **extra**: include extra details in response [optional, default: false]
- **sub**: text to search within lyrics, if found lyrics will begin at found verse [optional]
- **src**: the script/utility which initiated the request
"""
a: str | None = None
s: str | None = None
t: str | None = None
sub: str | None = None
extra: bool | None = False
src: str
class Config: # pylint: disable=missing-class-docstring too-few-public-methods
schema_extra = {
"example": {
"a": "eminem",
"s": "rap god",
"src": "WEB",
"extra": True
}
}
class ValidLyricSearchLogRequest(BaseModel):
"""
@ -99,6 +77,8 @@ class LyricSearch(FastAPI):
"IRC-SHARED"
]
self.lrc_regex = regex.compile(r'\[([0-9]{2}:[0-9]{2})\.[0-9]{1,3}\](\s(.*)){0,}')
for endpoint, handler in self.endpoints.items():
app.add_api_route(f"/{endpoint}/", handler, methods=["POST"])
@ -129,10 +109,12 @@ class LyricSearch(FastAPI):
- **s**: song
- **t**: track (artist and song combined) [used only if a & s are not used]
- **extra**: include extra details in response [optional, default: false]
- **lrc**: Request LRCs?
- **sub**: text to search within lyrics, if found lyrics will begin at found verse [optional, default: none]
- **src**: the script/utility which initiated the request
"""
lrc = data.lrc
src = data.src.upper()
if not src in self.acceptable_request_sources:
raise HTTPException(detail="Invalid request source", status_code=403)
@ -175,8 +157,88 @@ class LyricSearch(FastAPI):
else:
search_object = self.lyrics_engine.create_query_object(str(search_text))
if lrc:
search_worker = await self.lyrics_engine.grabFromSpotify(searching=search_object,
lrc=True)
spotify_lyrics_unsynced = True
if search_worker and search_worker.get('l'):
for line in search_worker.get('l'):
if line.get('timeTag') and line.get('timeTag') != "00:00.00":
spotify_lyrics_unsynced = False
if not search_worker or spotify_lyrics_unsynced:
# Try LRCLib before failing out
try:
lrclib_api_url = "https://lrclib.net/api/get"
sane_artist = urllib.parse.quote_plus(search_artist)
sane_track = urllib.parse.quote_plus(search_song)
async with aiohttp.ClientSession() as session:
async with session.get(f"{lrclib_api_url}?artist_name={sane_artist}&track_name={sane_track}") as request:
request.raise_for_status()
response_json = await request.json()
if not "syncedLyrics" in response_json:
raise BaseException("LRCLib Fallback Failed")
lrc_content = response_json.get('syncedLyrics')
returned_artist = response_json.get('artistName')
returned_song = response_json.get('trackName')
print(f"Synced Lyrics [LRCLib]: {lrc_content}")
lrc_content_out = []
for line in lrc_content.split("\n"):
_timetag = None
_words = None
if not line.strip():
continue
reg_helper = regex.findall(self.lrc_regex, line.strip())
if not reg_helper:
continue
reg_helper = reg_helper[0]
print(f"Reg helper: {reg_helper} for line: {line}; len: {len(reg_helper)}")
_timetag = reg_helper[0]
if not reg_helper[1].strip():
_words = ""
else:
_words = reg_helper[1]
lrc_content_out.append({
"timeTag": _timetag,
"words": _words,
})
return {
'err': False,
'artist': returned_artist,
'song': returned_song,
'combo_lev': "N/A",
'lrc': lrc_content_out,
'from_cache': False,
'src': 'Alt LRC SRC',
'reqn': await self.glob_state.get_counter('lyric_requests'),
}
except:
print(traceback.format_exc())
return {
'err': True,
'errorText': 'Search failed!',
}
return {
'err': True,
'errorText': 'Search failed!',
}
return {
'err': False,
'artist': search_worker['artist'],
'song': search_worker['song'],
'combo_lev': search_worker['combo_lev'],
'lrc': search_worker['l'],
'from_cache': False,
'src': search_worker['method'],
'reqn': await self.glob_state.get_counter('lyric_requests'),
}
search_worker = await self.lyrics_engine.lyrics_worker(searching=search_object,
recipient='anyone')
if not search_worker or not 'l' in search_worker.keys():
await self.glob_state.increment_counter('failedlyric_requests')

View File

@ -1,8 +1,21 @@
#!/usr/bin/env python3.12
from fastapi import FastAPI, Request, HTTPException
from fastapi import FastAPI, Request, HTTPException, WebSocket, WebSocketDisconnect, WebSocketException
from pydantic import BaseModel
from aiohttp import ClientSession, ClientTimeout
from aces.connection_manager import ConnectionManager
from aces.flac_reader import AudioStreamer
import os
import asyncio
import pyaudio
import wave
import traceback
import pyflac.decoder as decoder
import numpy as np
import soundfile as sf
import json
import time
class ValidXCRequest(BaseModel):
"""
@ -17,6 +30,8 @@ class ValidXCRequest(BaseModel):
cmd: str
data: dict | None = None
class XC(FastAPI):
"""XC (CrossComm) Endpoints"""
def __init__(self, app: FastAPI, util, constants, glob_state): # pylint: disable=super-init-not-called
@ -25,14 +40,26 @@ class XC(FastAPI):
self.constants = constants
self.glob_state = glob_state
self.ws_endpoints = {
# "aces_ws_put": self.put_ws_handler,
}
self.endpoints = {
"xc": self.xc_handler,
#tbd
}
for endpoint, handler in self.ws_endpoints.items():
app.add_api_websocket_route(f"/{endpoint}/", handler)
for endpoint, handler in self.endpoints.items():
app.add_api_route(f"/{endpoint}/", handler, methods=["POST"])
# async def put_ws_handler(self, ws: WebSocket):
# await ws.accept()
# await self.audio_streamer.handle_client(ws)
async def xc_handler(self, data: ValidXCRequest, request: Request):
"""
/xc/