about summary refs log tree commit diff
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2022-01-09T11·30+0100
committerProfpatsch <mail@profpatsch.de>2022-01-09T12·52+0000
commit71fe30a87c2dd2c7f93fd34f3abd596755f0d016 (patch)
treef20ae2dce439274c1715d1e5861aa8a55e40a080
parentebd5c3ad15a693c3437bdc083c0532b1959ee75a (diff)
feat(users/Profpatsch): add ytextr, a sandboxed yt-dlp wrapper r/3580
Change-Id: Id0992e5c1f52ac2c95444721c7565a66ef484e2b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/4836
Tested-by: BuildkiteCI
Reviewed-by: Profpatsch <mail@profpatsch.de>
-rw-r--r--users/Profpatsch/ytextr/create-symlink-farm.nix18
-rw-r--r--users/Profpatsch/ytextr/default.nix59
2 files changed, 77 insertions, 0 deletions
diff --git a/users/Profpatsch/ytextr/create-symlink-farm.nix b/users/Profpatsch/ytextr/create-symlink-farm.nix
new file mode 100644
index 000000000000..583a3a90f5c5
--- /dev/null
+++ b/users/Profpatsch/ytextr/create-symlink-farm.nix
@@ -0,0 +1,18 @@
+{
+  # list of package attribute names to get at run time
+  packageNamesAtRuntimeJsonPath,
+}:
+let
+  pkgs = import <nixpkgs> {};
+
+  getPkg = pkgName: pkgs.${pkgName};
+
+  packageNamesAtRuntime = builtins.fromJSON (builtins.readFile packageNamesAtRuntimeJsonPath);
+
+  runtime = map getPkg packageNamesAtRuntime;
+
+in
+  pkgs.symlinkJoin {
+    name = "symlink-farm";
+    paths = runtime;
+  }
diff --git a/users/Profpatsch/ytextr/default.nix b/users/Profpatsch/ytextr/default.nix
new file mode 100644
index 000000000000..dba6bbb8b400
--- /dev/null
+++ b/users/Profpatsch/ytextr/default.nix
@@ -0,0 +1,59 @@
+{ depot, pkgs, lib, ... }:
+
+# ytextr is a wrapper arount yt-dlp (previously youtube-dl)
+# that extracts a single video according to my preferred settings.
+#
+# It will be sandboxed to the current directory, since I don’t particularly
+# trust the massive codebase of that tool (with hundreds of contributors).
+#
+# Since the rules for downloading videos is usually against the wishes
+# of proprietary vendors, and a video is many megabytes anyway,
+# it will be fetched from the most recent nixpkgs unstable channel before running.
+
+let
+  bins = depot.nix.getBins pkgs.nix [ "nix-build" ]
+      // depot.nix.getBins pkgs.bubblewrap [ "bwrap" ];
+
+  # Run a command, with the given packages in scope, and `packageNamesAtRuntime` being fetched at the start in the given nix `channel`.
+  nix-run-with-channel = {
+    # The channel to get `packageNamesAtRuntime` from
+    channel,
+    # executable to run with `packageNamesAtRuntime` in PATH
+    # and the argv
+    executable,
+    # A list of nixpkgs package attribute names that should be put into PATH when running `command`.
+    packageNamesAtRuntime,
+  }: depot.nix.writeExecline "nix-run-with-channel-${channel}" {} [
+    # TODO: prevent race condition by writing a temporary gc root
+    "backtick" "-iE" "storepath" [
+      bins.nix-build
+        "-I" "nixpkgs=channel:${channel}"
+        "--arg"
+          "packageNamesAtRuntimeJsonPath"
+          (pkgs.writeText "packageNamesAtRuntime.json" (builtins.toJSON packageNamesAtRuntime))
+        ./create-symlink-farm.nix
+    ]
+    "importas" "-ui" "PATH" "PATH"
+    "export" "PATH" "\${storepath}/bin:\${PATH}"
+    executable "$@"
+  ];
+
+in nix-run-with-channel {
+  channel = "nixos-unstable";
+  packageNamesAtRuntime = [ "yt-dlp" ];
+  executable = depot.nix.writeExecline "ytextr" { readNArgs = 1; } [
+    "getcwd" "-E" "cwd"
+    bins.bwrap
+      "--ro-bind" "/nix/store" "/nix/store"
+      "--ro-bind" "/etc" "/etc"
+      "--bind" "$cwd" "$cwd"
+        "yt-dlp"
+        "--no-playlist"
+        "--write-sub"
+        "--all-subs"
+        "--embed-subs"
+        "--merge-output-format" "mkv"
+        "-f" "bestvideo[height<=?1080]+bestaudio/best"
+        "$1"
+  ];
+}