{ config, options, lib, pkgs, ... }: let cfg = config.tasks.multimedia-archive; mountName = "/mnt/archives"; in { options.tasks.multimedia-archive.enable = lib.mkEnableOption "multimedia archiving setup"; config = lib.mkIf cfg.enable (let yt-dlp-args = [ # Make a global list of successfully downloaded videos as a cache for yt-dlp. "--download-archive ${config.services.yt-dlp.archivePath}/videos" # No overwriting of videos and related files. "--no-force-overwrites" # Embed metadata in the file. "--write-info-json" # Embed chapter markers, if possible. "--embed-chapters" # Write the subtitle file. "--write-subs" # Write the description in a separate file. "--write-description" # The global output for all of the jobs. "--output '%(uploader,artist,creator|Unknown)s/%(release_date>%F,upload_date>%F|Unknown)s-%(title)s.%(ext)s'" # Select only the most optimal format for my usecases. "--format '(webm,mkv,mp4)[height<=?1280]'" # Prefer MKV whenever possible for video formats. "--merge-output-format mkv" # Don't download any videos that are originally live streams. "--match-filters '!was_live'" # Prefer Vorbis when audio-only downloads are used. "--audio-format vorbis" "--audio-quality 2" ]; yt-dlp-archive-variant = pkgs.writeScriptBin "yt-dlp-archive-variant" '' ${pkgs.yt-dlp}/bin/yt-dlp ${lib.escapeShellArgs yt-dlp-args} ''; in { environment.systemPackages = [ yt-dlp-archive-variant ]; fileSystems."${mountName}" = { device = "/dev/disk/by-partuuid/____CHANGE_THIS_PLEASE____"; fsType = "btrfs"; noCheck = true; options = [ # These are btrfs-specific mount options which can found in btrfs.5 # manual page. "subvol=@" "noatime" "compress=zstd:4" "space_cache=v2" # General mount options from mount.5 manual page. "noauto" "nofail" "user" # See systemd.mount.5 and systemd.automount.5 manual page for more # details. "x-systemd.automount" "x-systemd.idle-timeout=2" "x-systemd.device-timeout=2" ]; }; services.yt-dlp = { enable = true; archivePath = "${mountName}/yt-dlp-service"; # This is applied on all jobs. It is best to be minimal as much as # possible for this. extraArgs = yt-dlp-args; jobs = { arts = { urls = [ "https://www.youtube.com/channel/UCjdHbo8_vh3rxQ-875XGkvw" # 3DSage "https://www.youtube.com/channel/UCHv_hNLkxqlcY20MwVyayfw" # Ali Bahabadi "https://www.youtube.com/c/boroCG" # BoroCG "https://www.youtube.com/c/DavidRevoy" # David Revoy "https://www.youtube.com/channel/UCGMyyn2FdEFcDfP1wQRh5lQ" # Erindale "https://www.youtube.com/c/Jazza" # Jazza "https://www.youtube.com/channel/UCcBnT6LsxANZjUWqpjR8Jpw" # Marcello Barenghi "https://www.youtube.com/c/ronillust" # ronillust ]; startAt = "Friday"; extraArgs = [ "--playlist-end 20" # Only check the first N videos. ]; }; compsci = { urls = [ "https://www.youtube.com/channel/UC_mYaQAE6-71rjSN6CeCA-g" # NeetCode "https://www.youtube.com/c/ThePrimeagen" # ThePrimeagen "https://www.youtube.com/c/EasyTheory" # EasyTheory "https://www.youtube.com/c/K%C3%A1rolyZsolnai" # Two Minute Papers "https://www.youtube.com/c/TheCodingTrain" # TheCodingTrain ]; startAt = "Thursday"; extraArgs = [ "--playlist-end 20" # Only check the first N videos. ]; }; cooking = { urls = [ "https://www.youtube.com/channel/UCJHA_jMfCvEnv-3kRjTCQXw" # Babish Culinary Universe "https://www.youtube.com/channel/UCb5QRUn5w8_g0j8QVaWzcjQ" # BORE.D "https://www.youtube.com/channel/UCzqbfYjQmf9nLQPMxVgPhiA" # emmymade "https://www.youtube.com/channel/UCgmOd6sRQRK7QoSazOfaIjQ" # Emma's Goodies "https://www.youtube.com/channel/UCcp9uRaBwInxl_SZqGRksDA" # Hidamari Cooking "https://www.youtube.com/channel/UCvQrjgLj841wiQAKDgtKFOw" # Ninong Ry "https://www.youtube.com/channel/UCekQr9znsk2vWxBo3YiLq2w" # You Suck at Cooking "https://www.youtube.com/channel/UCUAKaXyq2hVBCph1LOUtuqg" # 집밥요리 Home Cooking ]; startAt = "Sunday"; extraArgs = [ "--playlist-end 15" # Check the first N videos. ]; }; }; }; services.archivebox = { enable = true; archivePath = "${mountName}/archivebox-service"; withDependencies = true; webserver.enable = true; jobs = { arts = { links = [ "https://www.davidrevoy.com/feed/rss" "https://librearts.org/index.xml" ]; startAt = "monthly"; }; computer = { links = [ "https://blog.mozilla.org/en/feed/" "https://distill.pub/rss.xml" "https://drewdevault.com/blog/index.xml" "https://fasterthanli.me/index.xml" "https://jvns.ca/atom.xml" "https://www.bytelab.codes/rss/" "https://www.collabora.com/feed" "https://www.jntrnr.com/atom.xml" "https://yosoygames.com.ar/wp/?feed=rss" "https://simblob.blogspot.com/feeds/posts/default" ]; startAt = "weekly"; }; projects = { links = [ "https://veloren.net/rss.xml" "https://guix.gnu.org/feeds/blog.atom" "https://fedoramagazine.org/feed/" "https://nixos.org/blog/announcements-rss.xml" ]; # Practically every 14 days. startAt = "Mon *-*-1/14"; }; }; }; services.gallery-dl = { enable = true; archivePath = "${mountName}/gallery-dl-service"; extraArgs = [ # Record all downloaded files in an archive file. "--download-archive ${config.services.gallery-dl.archivePath}/photos" # Write metadata to separate JSON files. "--write-metadata" ]; jobs = { arts = { urls = [ "https://www.deviantart.com/xezeno" # Xezeno #"https://www.pixiv.net/en/users/60562229" # Ravioli "https://www.artstation.com/kuvshinov_ilya" # Ilya Kuvshinov "https://www.artstation.com/meiipng" # Meiiart "https://www.artstation.com/bassem_wageeh" # Bassem wageeh "https://hyperjerk.newgrounds.com" # HyperJerk ]; startAt = "weekly"; }; }; }; }); }