From 19960e5222d50bd93ee00190dc60a4a6b839a08e Mon Sep 17 00:00:00 2001
From: Ethel Morgan <eth@ethulhu.co.uk>
Date: Mon, 27 Jul 2020 20:59:04 +0100
Subject: add eth.services.youtube-dl, for podcast downloads

---
 nixos/modules/module-list.nix         |   1 +
 nixos/modules/services/youtube-dl.nix | 113 ++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+)
 create mode 100644 nixos/modules/services/youtube-dl.nix

diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index e7d7494..8d6656e 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -24,5 +24,6 @@
   ./services/snapclient.nix
   ./services/ssh.nix
   ./services/upmpdcli.nix
+  ./services/youtube-dl.nix
   ./users/eth.nix
 ]
diff --git a/nixos/modules/services/youtube-dl.nix b/nixos/modules/services/youtube-dl.nix
new file mode 100644
index 0000000..11fa091
--- /dev/null
+++ b/nixos/modules/services/youtube-dl.nix
@@ -0,0 +1,113 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+  cfg = config.eth.services.youtube-dl;
+
+  escapeName = name: "youtube-dl-${replaceStrings [ " " "'" ] [ "-" "" ] name}";
+
+  mkService = name: opts: {
+    name = escapeName name;
+    value = {
+      description = "Download ${name}";
+      serviceConfig = {
+	User = cfg.user;
+	Group = cfg.group;
+        ExecStart = ''
+          ${pkgs.youtube-dl}/bin/youtube-dl \
+            --output ${escapeShellArg opts.directory}/${escapeShellArg opts.pattern} \
+            --write-description \
+            --write-info-json \
+            --write-sub \
+            --write-thumbnail \
+            ${escapeShellArg opts.url}
+        '';
+        NoNewPrivileges = true;
+        ProtectHome = true;
+        ProtectKernelTunables = true;
+        ProtectControlGroups = true;
+        ProtectKernelModules = true;
+        RestrictAddressFamilies = "AF_INET AF_INET6";
+      };
+    };
+  };
+
+  mkTimer = name: opts: {
+    name = escapeName name;
+    value = {
+      enable = opts.enable;
+      description = "Periodically download ${name}";
+      wants = [ "network.target" ];
+      after = [ "network.target" ];
+      wantedBy = [ "timers.target" ];
+      timerConfig = {
+        OnCalendar = "daily";
+        Unit = "${escapeName name}.service";
+        Persistent = true;
+        RandomizedDelaySec = "8h";
+      };
+    };
+  };
+
+in {
+  options.eth.services.youtube-dl = {
+    enable = mkEnableOption "Download media with youtube-dl.";
+
+    user = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = "eth";
+    };
+    group = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      example = "users";
+    };
+
+    download = mkOption {
+      type = types.attrsOf (types.submodule {
+        options = {
+          enable = mkEnableOption "Enable downloader.";
+
+          url = mkOption {
+            type = types.str;
+            description = "URL to download.";
+            default = "";
+            example = "http://web.server/rss.xml";
+          };
+
+          directory = mkOption {
+            type = types.path;
+            description = "Directory to download media to.";
+            default = "";
+            example = "/mnt/md0/media/podcasts";
+          };
+
+          pattern = mkOption {
+            type = types.str;
+            description = "Filename pattern";
+            default = "";
+            example = "%(title)s.%(ext)s";
+          };
+        };
+      });
+      default = {};
+      example = {
+        "Fun City" = {
+          enable = true;
+          url = "http://web.server/rss.xml";
+          directory = "/mnt/md0/media/podcasts";
+          pattern = "%(title)s.%(ext)s";
+        };
+      };
+      description = "Things to download";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    systemd = {
+      services = mapAttrs' mkService cfg.download;
+      timers = mapAttrs' mkTimer cfg.download;
+    };
+  };
+}
-- 
cgit v1.2.3