blob: 4bff1818f93ccf28b977f741d291cecdf86227b5 (
about) (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
(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-time-every-second-night
#~(lambda (now)
(let* ((even-day
(if (even? (tm:yday (localtime now)))
now
(next-day-from now)))
(deterministic-value
(number->string (tm:yday (localtime even-day)))))
;; Between 1 and 6 a.m., randomly, but deterministically for each
;; day (to avoid runs being skipped in case mcron is restarted).
;; (random 6 (seed->random-state yday)) isn't chaotic enough.
(next-minute-from
(next-hour-from even-day (list (1+ (string-hash deterministic-value 6))))
(list (string-hash deterministic-value 60))))))
(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.")))
|