130 lines
4.1 KiB
Python
130 lines
4.1 KiB
Python
import logging
|
|
import time
|
|
from datetime import UTC, datetime
|
|
from pathlib import Path
|
|
|
|
import anyio
|
|
|
|
from app.library.config import Config
|
|
from app.library.DownloadQueue import DownloadQueue
|
|
from app.library.Events import EventBus, Events, error
|
|
from app.library.ItemDTO import Item
|
|
from app.library.router import RouteType, route
|
|
from app.library.Utils import is_downloaded
|
|
from app.library.YTDLPOpts import YTDLPOpts
|
|
|
|
LOG: logging.Logger = logging.getLogger(__name__)
|
|
|
|
|
|
@route(RouteType.SOCKET, "pause", "pause_downloads")
|
|
async def pause(notify: EventBus, queue: DownloadQueue):
|
|
queue.pause()
|
|
await notify.emit(Events.PAUSED, data={"paused": True, "at": time.time()})
|
|
|
|
|
|
@route(RouteType.SOCKET, "resume", "resume_downloads")
|
|
async def resume(notify: EventBus, queue: DownloadQueue):
|
|
queue.resume()
|
|
await notify.emit(Events.PAUSED, data={"paused": False, "at": time.time()})
|
|
|
|
|
|
@route(RouteType.SOCKET, "add_url", "add_url")
|
|
async def add_url(queue: DownloadQueue, notify: EventBus, sid: str, data: dict):
|
|
url: str | None = data.get("url")
|
|
|
|
if not url:
|
|
await notify.emit(Events.ERROR, data=error("No URL provided.", data={"unlock": True}), to=sid)
|
|
return
|
|
|
|
try:
|
|
await notify.emit(
|
|
event=Events.STATUS,
|
|
data=await queue.add(item=Item.format(data)),
|
|
to=sid,
|
|
)
|
|
except ValueError as e:
|
|
LOG.exception(e)
|
|
await notify.emit(Events.ERROR, data=error(str(e)), to=sid)
|
|
return
|
|
|
|
|
|
@route(RouteType.SOCKET, "item_cancel", "item_cancel")
|
|
async def item_cancel(queue: DownloadQueue, notify: EventBus, sid: str, data: str):
|
|
if not data:
|
|
await notify.emit(Events.ERROR, data=error("Invalid request."), to=sid)
|
|
return
|
|
|
|
status: dict[str, str] = {}
|
|
status = await queue.cancel([data])
|
|
status.update({"identifier": data})
|
|
|
|
await notify.emit(Events.ITEM_CANCEL, data=status)
|
|
|
|
|
|
@route(RouteType.SOCKET, "item_delete", "item_delete")
|
|
async def item_delete(queue: DownloadQueue, notify: EventBus, sid: str, data: dict):
|
|
if not data:
|
|
await notify.emit(Events.ERROR, data=error("Invalid request."), to=sid)
|
|
return
|
|
|
|
id: str | None = data.get("id")
|
|
if not id:
|
|
await notify.emit(Events.ERROR, data=error("Invalid request."), to=sid)
|
|
return
|
|
|
|
status: dict[str, str] = {}
|
|
status = await queue.clear([id], remove_file=bool(data.get("remove_file", False)))
|
|
status.update({"identifier": id})
|
|
|
|
await notify.emit(Events.ITEM_DELETE, data=status)
|
|
|
|
|
|
@route(RouteType.SOCKET, "archive_item", "archive_item")
|
|
async def archive_item(config: Config, data: dict):
|
|
if not isinstance(data, dict) or "url" not in data:
|
|
return
|
|
|
|
params: YTDLPOpts = YTDLPOpts.get_instance()
|
|
|
|
if "preset" in data and isinstance(data["preset"], str):
|
|
params.preset(name=data["preset"])
|
|
|
|
if "cli" in data and isinstance(data["cli"], str) and len(data["cli"]) > 1:
|
|
params.add_cli(data["cli"], from_user=True)
|
|
|
|
params = params.get_all()
|
|
|
|
file: str = params.get("download_archive", None)
|
|
|
|
if not file:
|
|
return
|
|
|
|
exists, idDict = is_downloaded(file, data["url"])
|
|
if exists or "archive_id" not in idDict or idDict["archive_id"] is None:
|
|
return
|
|
|
|
async with await anyio.open_file(file, "a") as f:
|
|
await f.write(f"{idDict['archive_id']}\n")
|
|
|
|
manual_archive: str = config.manual_archive
|
|
if not manual_archive:
|
|
return
|
|
|
|
manual_archive = Path(manual_archive)
|
|
|
|
if not manual_archive.exists():
|
|
manual_archive.touch(exist_ok=True)
|
|
|
|
previouslyArchived = False
|
|
async with await anyio.open_file(manual_archive) as f:
|
|
async for line in f:
|
|
if idDict["archive_id"] in line:
|
|
previouslyArchived = True
|
|
break
|
|
|
|
if not previouslyArchived:
|
|
async with await anyio.open_file(manual_archive, "a") as f:
|
|
await f.write(f"{idDict['archive_id']} - at: {datetime.now(UTC).isoformat()}\n")
|
|
LOG.info(f"Archiving url '{data['url']}' with id '{idDict['archive_id']}'.")
|
|
else:
|
|
LOG.info(f"URL '{data['url']}' with id '{idDict['archive_id']}' already archived.")
|