summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/systemd.nix
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/gkleen@sif/systemd.nix')
-rw-r--r--accounts/gkleen@sif/systemd.nix43
1 files changed, 40 insertions, 3 deletions
diff --git a/accounts/gkleen@sif/systemd.nix b/accounts/gkleen@sif/systemd.nix
index 2ccbaea0..955fe9f5 100644
--- a/accounts/gkleen@sif/systemd.nix
+++ b/accounts/gkleen@sif/systemd.nix
@@ -306,6 +306,7 @@ in {
306 Service = { 306 Service = {
307 Type = "notify"; 307 Type = "notify";
308 CacheDirectory = "yt-dlp/%N"; 308 CacheDirectory = "yt-dlp/%N";
309 RuntimeDirectory = "yt-dlp/%N";
309 StandardInput = "socket"; 310 StandardInput = "socket";
310 StandardOutput = "journal"; 311 StandardOutput = "journal";
311 WatchdogSec = "30min"; 312 WatchdogSec = "30min";
@@ -315,6 +316,7 @@ in {
315 ]; 316 ];
316 ExecStart = ''${lib.getExe pkgs.dscp} ${pkgs.writers.writePython3 "yt-dlp" { 317 ExecStart = ''${lib.getExe pkgs.dscp} ${pkgs.writers.writePython3 "yt-dlp" {
317 libraries = with pkgs.python3Packages; [ yt-dlp sdnotify ]; 318 libraries = with pkgs.python3Packages; [ yt-dlp sdnotify ];
319 flakeIgnore = [ "E501" ];
318 } '' 320 } ''
319 import json 321 import json
320 from yt_dlp import YoutubeDL, parse_options 322 from yt_dlp import YoutubeDL, parse_options
@@ -322,14 +324,46 @@ in {
322 from sdnotify import SystemdNotifier 324 from sdnotify import SystemdNotifier
323 from os import environ 325 from os import environ
324 from pathlib import Path 326 from pathlib import Path
327 import threading
328 import socketserver
325 329
326 330
327 n = SystemdNotifier() 331 status = None
332 status_notifier = threading.Condition()
333
334
335 class StatusRequestHandler(socketserver.BaseRequestHandler):
336 def handle(self):
337 with self.request.makefile('w', encoding='utf-8') as fh:
338 while True:
339 with status_notifier:
340 json.dump(status, fh)
341 fh.write('\n')
342 fh.flush()
343 status_notifier.wait()
344
345
346 class ThreadedUnixStreamServer(socketserver.ThreadingMixIn, socketserver.UnixStreamServer):
347 pass
348
349
350 def progress_hook(d):
351 global status
352 n.notify('WATCHDOG=1\nSTATUS=' + d['status'])
353 with status_notifier:
354 status = {
355 **{k: v for k, v in d.items() if k in {'status', 'downloaded_bytes', 'total_bytes', 'total_bytes_estimate', 'fragment_count', 'fragment_index'}},
356 **{k: v for k, v in (d['info_dict'] if 'info_dict' in d else {}).items() if k in {'title', 'filename'}},
357 }
358 status_notifier.notify_all()
359
360
361 n = SystemdNotifier(debug=True)
328 args = json.load(stdin) 362 args = json.load(stdin)
329 ydl_opts = { 363 ydl_opts = {
330 **parse_options().ydl_opts, 364 **parse_options().ydl_opts,
331 'progress_hooks': [lambda _d: n.notify('WATCHDOG=1')], 365 'progress_hooks': [progress_hook],
332 'postprocessor_hooks': [lambda _d: n.notify('WATCHDOG=1')], 366 'postprocessor_hooks': [progress_hook],
333 'progress_with_newline': True, 367 'progress_with_newline': True,
334 'progress_delta': 5, 368 'progress_delta': 5,
335 'paths': { 369 'paths': {
@@ -339,6 +373,9 @@ in {
339 'noplaylist': True, 373 'noplaylist': True,
340 **(args['params'] if 'params' in args else {}), 374 **(args['params'] if 'params' in args else {}),
341 } 375 }
376 status_server = ThreadedUnixStreamServer(str(Path(environ['RUNTIME_DIRECTORY']) / 'status.sock'), StatusRequestHandler)
377 status_server.daemon_threads = True
378 threading.Thread(target=status_server.serve_forever, daemon=True).start()
342 with YoutubeDL(ydl_opts) as ytdl: 379 with YoutubeDL(ydl_opts) as ytdl:
343 n.notify('READY=1') 380 n.notify('READY=1')
344 ytdl.download(args['urls']) 381 ytdl.download(args['urls'])