From 6e214feb4aeb5b2d6c750f35aee289db70b6c245 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Sun, 3 Apr 2022 10:18:22 +0800 Subject: [PATCH] services/yt-dlp: init service Structure-wise, it is pretty similar to the gallery-dl service. It was about to be combined into a bigger service module as a dedicated service for multimedia archiving but it is better to have them modularized in the long run. --- modules/home-manager/services/yt-dlp.nix | 157 +++++++++++++++++++++++ modules/nixos/services/yt-dlp.nix | 131 +++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 modules/home-manager/services/yt-dlp.nix create mode 100644 modules/nixos/services/yt-dlp.nix diff --git a/modules/home-manager/services/yt-dlp.nix b/modules/home-manager/services/yt-dlp.nix new file mode 100644 index 00000000..ef857ecb --- /dev/null +++ b/modules/home-manager/services/yt-dlp.nix @@ -0,0 +1,157 @@ +{ config, options, lib, pkgs, ... }: + +let + cfg = config.services.yt-dlp; + + jobType = { name, config, options, ... }: { + options = { + urls = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + description = '' + A list of URLs to be downloaded to yt-dlp. Please + see the list of extractors with . + ''; + example = lib.literalExpression '' + [ + "https://www.youtube.com/c/ronillust" + "https://www.youtube.com/c/Jazza" + ] + ''; + }; + + startAt = lib.mkOption { + type = with lib.types; str; + description = '' + Indicates how frequent the download will occur. The given schedule should follow the format as described from + + systemd.time + 5 + . + ''; + default = "daily"; + example = "*-*-3/4"; + }; + + extraArgs = lib.mkOption { + type = with lib.types; listOf str; + description = + "Job-specific extra arguments to be passed to the yt-dlp."; + default = [ ]; + example = lib.literalExpression '' + [ + "--date 'today'" + ] + ''; + }; + }; + }; +in { + options.services.yt-dlp = { + enable = lib.mkEnableOption "archiving service with yt-dlp"; + + package = lib.mkOption { + type = lib.types.package; + description = + "The derivation that contains yt-dlp binary."; + default = pkgs.yt-dlp; + defaultText = lib.literalExpression "pkgs.yt-dlp"; + example = lib.literalExpression + "pkgs.yt-dlp.override { phantomjsSupport = true; }"; + }; + + archivePath = lib.mkOption { + type = lib.types.str; + description = '' + The location of the archive to be downloaded. Take note it is assumed + to be created at the time of running the service. Must be an absolute + path. + ''; + default = "${lib.replaceStrings ["$HOME"] [config.home.homeDirectory] config.xdg.userDirs.videos}/yt-dlp-service"; + example = lib.literalExpression + "\${config.xdg.userDirs.download}/archiving-service/videos"; + }; + + extraArgs = lib.mkOption { + type = with lib.types; listOf str; + description = + "List of arguments to be passed to yt-dlp."; + default = [ "--download-archive '${cfg.archivePath}/download-list" ]; + example = lib.literalExpression '' + [ + "--download-archive ''${cfg.archivePath}/download-list" + "--concurrent-fragments 2" + "--retries 20" + ] + ''; + }; + + jobs = lib.mkOption { + type = with lib.types; attrsOf (submodule jobType); + description = '' + A map of jobs for the archiving service. + ''; + default = { }; + example = lib.literalExpression '' + { + arts = { + urls = [ + "https://www.youtube.com/c/Jazza" + ]; + startAt = "weekly"; + extraArgs = [ "--date 'today'" ]; + }; + + compsci = { + urls = [ + "https://www.youtube.com/c/K%C3%A1rolyZsolnai" + "https://www.youtube.com/c/TheCodingTrain" + ]; + startAt = "weekly"; + }; + } + ''; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.user.services = lib.mapAttrs' (name: value: + lib.nameValuePair "yt-dlp-archive-service-${name}" { + Unit = { + Description = "yt-dlp archive job for group '${name}'"; + After = "network.target"; + Documentation = "man:yt-dlp(1)"; + }; + + Service = { + WorkingDirectory = cfg.archivePath; + ExecStartPre = '' + ${pkgs.bash}/bin/bash -c "${pkgs.coreutils}/bin/mkdir -p ${lib.escapeShellArg cfg.archivePath}" + ''; + ExecStart = let + scriptName = "yt-dlp-archive-service-${config.home.username}-${name}"; + archiveScript = pkgs.writeShellScriptBin scriptName '' + ${cfg.package}/bin/yt-dlp ${lib.concatStringsSep " " cfg.extraArgs} ${ + lib.concatStringsSep " " value.extraArgs + } ${lib.escapeShellArgs value.urls} + ''; + in "${archiveScript}/bin/${scriptName}"; + }; + }) cfg.jobs; + + systemd.user.timers = lib.mapAttrs' (name: value: + lib.nameValuePair "yt-dlp-archive-service-${name}" { + Unit = { + Description = "yt-dlp archive job for group '${name}'"; + Documentation = "man:yt-dlp(1)"; + }; + + Timer = { + OnCalendar = value.startAt; + Persistent = true; + }; + + Install.WantedBy = [ "timers.target" ]; + }) cfg.jobs; + }; +} diff --git a/modules/nixos/services/yt-dlp.nix b/modules/nixos/services/yt-dlp.nix new file mode 100644 index 00000000..1cdec11a --- /dev/null +++ b/modules/nixos/services/yt-dlp.nix @@ -0,0 +1,131 @@ +{ config, options, lib, pkgs, ... }: + +let + cfg = config.services.yt-dlp; + + jobType = { name, config, options, ... }: { + options = { + urls = lib.mkOption { + type = with lib.types; listOf str; + default = [ ]; + description = '' + A list of URLs to be downloaded to yt-dlp. Please + see the list of extractors with . + ''; + example = lib.literalExpression '' + [ + "https://www.youtube.com/c/ronillust" + "https://www.youtube.com/c/Jazza" + ] + ''; + }; + + startAt = lib.mkOption { + type = with lib.types; str; + description = '' + Indicates how frequent the download will occur. The given schedule should follow the format as described from + + systemd.time + 5 + . + ''; + default = "daily"; + example = "*-*-3/4"; + }; + + extraArgs = lib.mkOption { + type = with lib.types; listOf str; + description = + "Job-specific extra arguments to be passed to the yt-dlp."; + default = [ ]; + example = lib.literalExpression '' + [ + "--date 'today'" + ] + ''; + }; + }; + }; +in { + options.services.yt-dlp = { + enable = lib.mkEnableOption "archiving service with yt-dlp"; + + package = lib.mkOption { + type = lib.types.package; + description = + "The derivation that contains yt-dlp binary."; + default = pkgs.yt-dlp; + defaultText = lib.literalExpression "pkgs.yt-dlp"; + example = lib.literalExpression + "pkgs.yt-dlp.override { phantomjsSupport = true; }"; + }; + + archivePath = lib.mkOption { + type = lib.types.str; + description = '' + The location of the archive to be downloaded. Must be an absolute path. + ''; + default = "/archives/yt-dlp-service"; + example = lib.literalExpression "/archiving-service/videos"; + }; + + extraArgs = lib.mkOption { + type = with lib.types; listOf str; + description = + "List of arguments to be passed to yt-dlp."; + default = [ "--download-archive videos" ]; + example = lib.literalExpression '' + [ + "--download-archive ''${cfg.archivePath}/download-list" + "--concurrent-fragments 2" + "--retries 20" + ] + ''; + }; + + jobs = lib.mkOption { + type = with lib.types; attrsOf (submodule jobType); + description = '' + A map of jobs for the archiving service. + ''; + default = { }; + example = lib.literalExpression '' + { + arts = { + urls = [ + "https://www.youtube.com/c/Jazza" + ]; + startAt = "weekly"; + extraArgs = [ "--date 'today'" ]; + }; + + compsci = { + urls = [ + "https://www.youtube.com/c/K%C3%A1rolyZsolnai" + "https://www.youtube.com/c/TheCodingTrain" + ]; + startAt = "weekly"; + }; + } + ''; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services = lib.mapAttrs' (name: value: + lib.nameValuePair "yt-dlp-archive-service-${name}" { + after = [ "network.target" ]; + description = "yt-dlp archive job for group '${name}'"; + documentation = [ "man:yt-dlp(1)" ]; + enable = true; + path = [ cfg.package pkgs.coreutils ]; + script = '' + mkdir -p ${lib.escapeShellArg cfg.archivePath} \ + && yt-dlp ${lib.concatStringsSep " " cfg.extraArgs} ${ + lib.concatStringsSep " " value.extraArgs + } ${lib.escapeShellArgs value.urls} + ''; + startAt = value.startAt; + }) cfg.jobs; + }; +}