Add YDL logging, change schema

This commit is contained in:
DarkCat09 2024-05-08 13:52:36 +04:00
parent 8720ea07fd
commit 247bf65439
Signed by: DarkCat09
GPG key ID: 0A26CD5B3345D6E3
3 changed files with 59 additions and 16 deletions

View file

@ -13,7 +13,18 @@ type SocketT = websockets.WebSocketServerProtocol
async def handler(socket: SocketT) -> None: async def handler(socket: SocketT) -> None:
ydls = ydl_pool.Downloader(None, None) # type: ignore # TODO async def ydl_log_handler(level: response.YdlLogLevel, msg: str) -> None:
try:
await socket.send(response.ydl_log(level, msg))
except:
pass
ydls = ydl_pool.Downloader(
ydl_pool.YdlLogger(
ydl_log_handler,
asyncio.get_event_loop(),
)
)
async for message in socket: async for message in socket:
@ -34,9 +45,7 @@ async def handler(socket: SocketT) -> None:
data['url'], data['url'],
data.get('items'), data.get('items'),
) )
await socket.send(response.dl_end(ret)) await socket.send(response.ydl_end(ret))
# TODO: cancellation
case _: case _:
raise ValueError('invalid "action" field value') raise ValueError('invalid "action" field value')

View file

@ -1,5 +1,7 @@
import json import json
import traceback import logging
from typing import Literal
def playlist(items: list[str]) -> str: def playlist(items: list[str]) -> str:
return json.dumps({ return json.dumps({
@ -7,20 +9,25 @@ def playlist(items: list[str]) -> str:
"data": items, "data": items,
}) })
def dl_progress(msg: str) -> str:
type YdlLogLevel = Literal['debug'] | Literal['warning'] | Literal['error']
def ydl_log(level: YdlLogLevel, msg: str) -> str:
return json.dumps({ return json.dumps({
"type": "dl_progress", "type": "ydl_log",
"level": level,
"data": msg, "data": msg,
}) })
def dl_end(ret: int) -> str: def ydl_end(ret: int) -> str:
return json.dumps({ return json.dumps({
"type": "dl_end", "type": "ydl_end",
"data": ret, "data": ret,
}) })
def error(ex: Exception) -> str: def error(ex: Exception) -> str:
traceback.print_tb(ex.__traceback__) logging.getLogger('musicdlp').exception(ex)
return json.dumps({ return json.dumps({
"type": "error", "type": "error",
"data": { "data": {

View file

@ -1,10 +1,12 @@
import asyncio import asyncio
import logging
from typing import Callable, Awaitable, Iterable from typing import Callable, Awaitable, Iterable
from yt_dlp import YoutubeDL from yt_dlp import YoutubeDL
from yt_dlp.postprocessor import FFmpegExtractAudioPP from yt_dlp.postprocessor import FFmpegExtractAudioPP
import config import config
import response
import id3pp import id3pp
@ -40,12 +42,33 @@ ydl_fn_keys = create_ydl_fn.keys()
NP_YDLS = {'yandex'} NP_YDLS = {'yandex'}
class Downloader: class YdlLogger:
def __init__( def __init__(
self, self,
progress_cb: Callable[[str], Awaitable], log_cb: Callable[[response.YdlLogLevel, str], Awaitable],
lyrics_cb: Callable[[list[str]], Awaitable]) -> None: loop: asyncio.AbstractEventLoop) -> None:
self.log_cb = log_cb
self.loop = loop
self.mdlp_logger = logging.getLogger('musicdlp')
def debug(self, msg: str) -> None:
asyncio.run_coroutine_threadsafe(self.log_cb('debug', msg), self.loop)
def info(self, _: str) -> None: # afaik not used in yt-dlp
pass
def warning(self, msg: str) -> None:
asyncio.run_coroutine_threadsafe(self.log_cb('warning', msg), self.loop)
def error(self, msg: str) -> None:
self.mdlp_logger.error(msg)
asyncio.run_coroutine_threadsafe(self.log_cb('error', msg), self.loop)
class Downloader:
def __init__(self, logger: YdlLogger | None = None) -> None:
self.ydls: dict[str, YoutubeDL | None] = { self.ydls: dict[str, YoutubeDL | None] = {
'youtube': None, 'youtube': None,
@ -56,8 +79,9 @@ class Downloader:
self.cur_ydl: YoutubeDL | None = None self.cur_ydl: YoutubeDL | None = None
self.cur_site = '' self.cur_site = ''
self.progress_cb = progress_cb self.id3pp_obj = id3pp.ID3TagsPP()
self.lyrics_cb = lyrics_cb
self.logger = logger
def choose_ydl(self, site: str) -> None: def choose_ydl(self, site: str) -> None:
@ -67,8 +91,11 @@ class Downloader:
if ydl is None: if ydl is None:
ydl = create_ydl_fn[site]() ydl = create_ydl_fn[site]()
if self.logger is not None:
ydl.params['logger'] = self.logger
ydl.params['outtmpl']['default'] = cfg.tmpl ydl.params['outtmpl']['default'] = cfg.tmpl
ydl.add_post_processor(id3pp.ID3TagsPP(), when='post_process') ydl.add_post_processor(self.id3pp_obj, when='post_process')
cookies = cfg.cookies_dir / (site + '.txt') cookies = cfg.cookies_dir / (site + '.txt')
if cookies.exists(): if cookies.exists():