summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tw/services/media.scm69
-rw-r--r--tw/system/lud.scm7
2 files changed, 76 insertions, 0 deletions
diff --git a/tw/services/media.scm b/tw/services/media.scm
new file mode 100644
index 00000000..6d82765a
--- /dev/null
+++ b/tw/services/media.scm
@@ -0,0 +1,69 @@
+(define-module (tw services media)
+ #:use-module (gnu)
+ #:use-module (gnu packages video)
+ #:use-module (gnu services)
+ #:use-module (gnu services configuration)
+ #:use-module (gnu services mcron)
+ #:use-module (gnu services shepherd)
+ #:use-module (guix gexp)
+ #:use-module (guix packages)
+ #:export (yt-dlp-service-type
+ yt-dlp-configuration))
+
+(define (package-or-false? value)
+ (or (package? value) (eq? #f value)))
+(define (string-or-gexp? value)
+ (or (string? value) (gexp? value)))
+
+(define random-hour-every-second-night
+ #~(lambda (now)
+ (let* ((even-day
+ (if (even? (tm:yday (localtime now)))
+ now
+ (next-day-from now)))
+ ;; Between 1 and 6 a.m., randomly, but deterministically for each
+ ;; day (to avoid runs being skipped in case mcron is restarted).
+ (hour-of-day
+ (1+ (random 6 (seed->random-state
+ (tm:yday (localtime even-day)))))))
+ (next-hour-from even-day (list hour-of-day)))))
+
+(define-configuration/no-serialization yt-dlp-configuration
+ (media-directory string "The directory in which to store downloaded media.
+The service expects a @code{.yt-dlp} config directory inside this one.")
+ (yt-dlp (package-or-false yt-dlp) "The yt-dlp package to use; or
+@code{#false} to use the yt-dlp script inside the config directory.")
+ (schedule (string-or-gexp random-hour-every-second-night) "The mcron
+schedule on which to run the download script. By default, picks a random hour
+between 01:00 and 06:00 every second night.")
+ (user (string "root") "The Unix user name to run the script as.")
+ (group (string "root") "The Unix group name to run the script as."))
+
+(define (yt-dlp-cronjob config)
+ (list
+ (let* ((yt-dlp-package (yt-dlp-configuration-yt-dlp config))
+ (yt-dlp-executable
+ (if yt-dlp-package
+ (file-append yt-dlp-package "/bin/yt-dlp")
+ (string-append (yt-dlp-configuration-media-directory config)
+ "/.yt-dlp/yt-dlp"))))
+ #~(job #$(yt-dlp-configuration-schedule config)
+ (lambda ()
+ (chdir #$(yt-dlp-configuration-media-directory config))
+ ;; `setgid' first while we're still root
+ (setgid (group:gid (getgr #$(yt-dlp-configuration-group config))))
+ (setuid (passwd:uid (getpw #$(yt-dlp-configuration-user config))))
+ (execl #$yt-dlp-executable
+ "yt-dlp" "--ignore-config" "--config-location" ".yt-dlp"))
+ ;; Human-readable string for `herd schedule mcron'.
+ (format #f "~a --ignore-config --config-location ~a/.yt-dlp"
+ #$yt-dlp-executable ; this may be a `<file-append>', so #$ it directly
+ #$(yt-dlp-configuration-media-directory config))))))
+
+(define yt-dlp-service-type
+ (service-type
+ (name 'yt-dlp)
+ (extensions
+ (list (service-extension mcron-service-type yt-dlp-cronjob)))
+ (description
+ "Trigger yt-dlp on a schedule to download videos from YouTube.")))
diff --git a/tw/system/lud.scm b/tw/system/lud.scm
index b770fc90..97cef45a 100644
--- a/tw/system/lud.scm
+++ b/tw/system/lud.scm
@@ -7,6 +7,7 @@
#:use-module (tw packages php)
#:use-module (tw services nextcloud)
#:use-module (tw services matrix)
+ #:use-module (tw services media)
#:use-module (tw system))
(use-package-modules admin bash certs databases linux man php python rsync
@@ -112,6 +113,12 @@ SSLSessionCacheTimeout 1200
(user "syncthing")
(group "syncthing")))
+ (service yt-dlp-service-type
+ (yt-dlp-configuration
+ (media-directory "/var/data/syncthing/Videos")
+ (user "syncthing")
+ (group "syncthing")))
+
;; certbot for Synapse + Apache/Nextcloud
;; This also installs a nginx server on port 80, redirecting to port 443.
(service certbot-service-type