commit 0be9710c9bf8b8c5e80ba8c23733c3ecc393d794
parent 8ef7208d4049c6e76fe5b3c1ed292d78b3d1e02f
Author: archiveanon <>
Date: Fri, 17 Jan 2025 23:11:48 +0000
Implement WebDAV uploading
Diffstat:
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/src/autotako/config.py b/src/autotako/config.py
@@ -8,6 +8,7 @@ import msgspec
class ChannelConfig(msgspec.Struct):
id: str
name: str | None = None
+ webdav_path: str | None = None
class TorrentConfig(msgspec.Struct):
@@ -24,10 +25,17 @@ class QBittorrentConfig(msgspec.Struct):
default_save_path: str | None = None
+class WebDavConfig(msgspec.Struct):
+ base_url: str
+ username: str
+ password: str
+
+
class AppConfig(msgspec.Struct):
moombox_url: str
torrent: TorrentConfig
channels: list[ChannelConfig] = msgspec.field(name="channel", default_factory=list)
+ webdav: WebDavConfig | None = None
qbittorrent: QBittorrentConfig | None = None
def get_channel_config_by_id(self, channel_id: str) -> ChannelConfig | None:
diff --git a/src/autotako/job_render.py b/src/autotako/job_render.py
@@ -10,7 +10,7 @@ import microdot # type: ignore
import qbittorrentapi # type: ignore
import torf # type: ignore
-from .config import config_ctx
+from .config import WebDavConfig, config_ctx
from .database import database_ctx
app = microdot.Microdot()
@@ -126,6 +126,16 @@ async def do_gofile_upload(job: dict):
return gofile_url
+async def do_webdav_upload(webdav: WebDavConfig, filepath: pathlib.Path, target: str):
+ auth = httpx.BasicAuth(username=webdav.username, password=webdav.password)
+ async with httpx.AsyncClient(auth=auth) as client:
+ dest = f"{webdav.base_url}/{target}"
+ file_check = await client.head(dest)
+ if file_check.status_code == httpx.codes.NOT_FOUND:
+ with filepath.open("rb") as fh:
+ await client.put(dest, content=fh.read())
+
+
@app.get("/<jobid>")
async def show_job(request, jobid):
job = await get_moombox_job_by_id(jobid)
@@ -148,6 +158,11 @@ async def show_job(request, jobid):
display_date_str = display_date.strftime("%Y%m%d")
torrent_name = f"[{display_date_str}] Unarchived Karaoke ({job['video_id']})"
+ folder_name = None
+ if stream_time:
+ folder_name = stream_time.strftime("%Y-%m-%dT%H:%MZ")
+
+ readme_finalized = False
render_kwargs = {}
if job["output_paths"]:
torrent_file = torrent_output_dir / f"{job['id']} ({job['video_id']}).torrent"
@@ -172,8 +187,6 @@ async def show_job(request, jobid):
t.write(torrent_file)
t.write(torrent_output_dir / f"{torrent_name}.torrent")
- # TODO punt file to remote
-
# send torrent to qbittorrent for seeding
if config.qbittorrent:
if config.qbittorrent.default_save_path:
@@ -202,15 +215,35 @@ async def show_job(request, jobid):
print(t.magnet(size=False))
print(t.files)
- # TODO punt file to remote
+ # punt file to webdav remote
+ if config.webdav and channel and channel.webdav_path:
+ target_base = f"{channel.webdav_path}/{folder_name}"
+ task = asyncio.create_task(
+ do_webdav_upload(
+ config.webdav, torrent_file, f"{target_base}/{torrent_name}.torrent"
+ )
+ )
+ background_tasks.add(task)
+ task.add_done_callback(background_tasks.discard)
render_kwargs["magnet_url"] = t.magnet(size=False)
# punt files to gofile
render_kwargs["gofile_url"] = await do_gofile_upload(job)
- return await microdot.jinja.Template("job.md").render_async(
+ readme_finalized = True
+ rendered_job = await microdot.jinja.Template("job.md").render_async(
job=job,
author_override=channel.name if channel else None,
stream_time=stream_time.strftime("%Y-%m-%dT%H:%MZ") if stream_time else "(unknown)",
**render_kwargs,
)
+ if readme_finalized and config.webdav and channel and channel.webdav_path:
+ rendered_job_file = torrent_output_dir / f"{job['id']} ({job['video_id']}).md"
+ rendered_job_file.write_text(rendered_job)
+ target_base = f"{channel.webdav_path}/{folder_name}"
+ task = asyncio.create_task(
+ do_webdav_upload(config.webdav, rendered_job_file, f"{target_base}/REPORT.md")
+ )
+ background_tasks.add(task)
+ task.add_done_callback(background_tasks.discard)
+ return rendered_job