diff --git a/flake.lock b/flake.lock index 2cd2a2b..1f4c50c 100644 --- a/flake.lock +++ b/flake.lock @@ -35,11 +35,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1737621947, - "narHash": "sha256-8HFvG7fvIFbgtaYAY2628Tb89fA55nPm2jSiNs0/Cws=", + "lastModified": 1742042642, + "narHash": "sha256-D0gP8srrX0qj+wNYNPdtVJsQuFzIng3q43thnHXQ/es=", "owner": "cachix", "repo": "cachix", - "rev": "f65a3cd5e339c223471e64c051434616e18cc4f5", + "rev": "a624d3eaf4b1d225f918de8543ed739f2f574203", "type": "github" }, "original": { @@ -95,11 +95,11 @@ "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1743521698, - "narHash": "sha256-bvl7YmNZjGEZhyH86mGiJdhZGMaRot1TMM6cjwrwH6k=", + "lastModified": 1743783972, + "narHash": "sha256-5wPsNCnWmeLpLxavsftA9L7tnYgtlexV7FwLegxtpy4=", "owner": "cachix", "repo": "devenv", - "rev": "4917f16d045f12d938d0a29fb1cbfb9e24ae6d0d", + "rev": "2f53e2f867e0c2ba18b880e66169366e5f8ca554", "type": "github" }, "original": { @@ -211,11 +211,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1741352980, - "narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=", + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", "type": "github" }, "original": { @@ -245,6 +245,24 @@ "type": "github" } }, + "flake-parts_4": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, + "locked": { + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flatpak": { "locked": { "lastModified": 1739444422, @@ -273,11 +291,11 @@ ] }, "locked": { - "lastModified": 1740849354, - "narHash": "sha256-oy33+t09FraucSZ2rZ6qnD1Y1c8azKKmQuCvF2ytUko=", + "lastModified": 1742649964, + "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", "owner": "cachix", "repo": "git-hooks.nix", - "rev": "4a709a8ce9f8c08fa7ddb86761fe488ff7858a07", + "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", "type": "github" }, "original": { @@ -406,6 +424,25 @@ "type": "github" } }, + "musicomp": { + "inputs": { + "flake-parts": "flake-parts_4", + "nixpkgs": "nixpkgs_6" + }, + "locked": { + "lastModified": 1744068246, + "narHash": "sha256-ZrLuwXT0uRxa4hyMyCe/IG9lKZEqAM+lUgLKcCiZjbA=", + "ref": "refs/heads/main", + "rev": "66aa356585132605e8bd9cc630fab7416f3caf3d", + "revCount": 2, + "type": "git", + "url": "https://codeberg.org/helveticanonstandard/musicomp.git" + }, + "original": { + "type": "git", + "url": "https://codeberg.org/helveticanonstandard/musicomp.git" + } + }, "nix": { "inputs": { "flake-compat": [ @@ -446,11 +483,11 @@ ] }, "locked": { - "lastModified": 1743306489, - "narHash": "sha256-LROaIjSLo347cwcHRfSpqzEOa2FoLSeJwU4dOrGm55E=", + "lastModified": 1743911143, + "narHash": "sha256-4j4JPwr0TXHH4ZyorXN5yIcmqIQr0WYacsuPA4ktONo=", "owner": "nix-community", "repo": "nix-index-database", - "rev": "b3696bfb6c24aa61428839a99e8b40c53ac3a82d", + "rev": "a36f6a7148aec2c77d78e4466215cceb2f5f4bfb", "type": "github" }, "original": { @@ -462,16 +499,16 @@ "nixos-cosmic": { "inputs": { "flake-compat": "flake-compat_3", - "nixpkgs": "nixpkgs_6", + "nixpkgs": "nixpkgs_7", "nixpkgs-stable": "nixpkgs-stable_2", "rust-overlay": "rust-overlay_2" }, "locked": { - "lastModified": 1743531084, - "narHash": "sha256-IOfLnebyXv2v8srLwKOx7TSi2NhHrvqL5AtpDEGVhJ4=", + "lastModified": 1744137608, + "narHash": "sha256-KEuKL7lM2ZqKzvaGIptVDAce29CAR4ZSgWtFD3PnpB0=", "owner": "lilyinstarlight", "repo": "nixos-cosmic", - "rev": "c231cbbfdd897b86efc9138a37ac302d5a29fb5d", + "rev": "d20b15f629985fe6900925bef462f947e4a75b2f", "type": "github" }, "original": { @@ -498,11 +535,26 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1740877520, - "narHash": "sha256-oiwv/ZK/2FhGxrCkQkB83i7GnWXPPLzoqFHpDD3uYpk=", + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "147dee35aab2193b174e4c0868bd80ead5ce755c", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs-lib_2": { + "locked": { + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", "type": "github" }, "original": { @@ -529,11 +581,11 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1743367904, - "narHash": "sha256-sOos1jZGKmT6xxPvxGQyPTApOunXvScV4lNjBCXd/CI=", + "lastModified": 1743975612, + "narHash": "sha256-o4FjFOUmjSRMK7dn0TFdAT0RRWUWD+WsspPHa+qEQT8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "7ffe0edc685f14b8c635e3d6591b0bbb97365e6c", + "rev": "a880f49904d68b5e53338d1e8c7bf80f59903928", "type": "github" }, "original": { @@ -609,11 +661,11 @@ }, "nixpkgs_6": { "locked": { - "lastModified": 1743315132, - "narHash": "sha256-6hl6L/tRnwubHcA4pfUUtk542wn2Om+D4UnDhlDW9BE=", + "lastModified": 1743964447, + "narHash": "sha256-nEo1t3Q0F+0jQ36HJfbJtiRU4OI+/0jX/iITURKe3EE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "52faf482a3889b7619003c0daec593a1912fddc1", + "rev": "063dece00c5a77e4a0ea24e5e5a5bd75232806f8", "type": "github" }, "original": { @@ -625,11 +677,27 @@ }, "nixpkgs_7": { "locked": { - "lastModified": 1743076231, - "narHash": "sha256-yQugdVfi316qUfqzN8JMaA2vixl+45GxNm4oUfXlbgw=", + "lastModified": 1743964447, + "narHash": "sha256-nEo1t3Q0F+0jQ36HJfbJtiRU4OI+/0jX/iITURKe3EE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6c5963357f3c1c840201eda129a99d455074db04", + "rev": "063dece00c5a77e4a0ea24e5e5a5bd75232806f8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_8": { + "locked": { + "lastModified": 1743689281, + "narHash": "sha256-y7Hg5lwWhEOgflEHRfzSH96BOt26LaYfrYWzZ+VoVdg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2bfc080955153be0be56724be6fa5477b4eefabb", "type": "github" }, "original": { @@ -642,15 +710,15 @@ "phps": { "inputs": { "flake-compat": "flake-compat_4", - "nixpkgs": "nixpkgs_7", + "nixpkgs": "nixpkgs_8", "utils": "utils" }, "locked": { - "lastModified": 1743395855, - "narHash": "sha256-1OZa0T1PSRTHqQG2eiMDiqJPB8XSseoe7bKUCkG5C0U=", + "lastModified": 1744001863, + "narHash": "sha256-0pYw0Idtion++srUKsmGX7mq1weozdVE8gR+inoedUo=", "owner": "fossar", "repo": "nix-phps", - "rev": "87aa57df1dffc535756256efbd141c735852145f", + "rev": "220ed74315dc7cd64a6181efd3d583a3607ef01f", "type": "github" }, "original": { @@ -695,6 +763,7 @@ "flatpak": "flatpak", "hardware": "hardware", "lanzaboote": "lanzaboote", + "musicomp": "musicomp", "nix-index-database": "nix-index-database", "nixos-cosmic": "nixos-cosmic", "nixpkgs": [ @@ -733,11 +802,11 @@ ] }, "locked": { - "lastModified": 1743475035, - "narHash": "sha256-uLjVsb4Rxnp1zmFdPCDmdODd4RY6ETOeRj0IkC0ij/4=", + "lastModified": 1744079607, + "narHash": "sha256-5cog6Qd6w/bINdLO5mOysAHOHey8PwFXk4IWo+y+Czg=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "bee11c51c2cda3ac57c9e0149d94b86cc1b00d13", + "rev": "f6b62cc99c25e79a1c17e9fca91dc6b6faebec6c", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index f527322..3ff0627 100644 --- a/flake.nix +++ b/flake.nix @@ -20,6 +20,7 @@ url = "github:nix-community/nix-index-database"; inputs.nixpkgs.follows = "nixpkgs"; }; + musicomp.url = "git+https://codeberg.org/helveticanonstandard/musicomp.git"; }; nixConfig = { diff --git a/hosts/headful/flamingo/spotify.nix b/hosts/headful/flamingo/supersonic.nix similarity index 52% rename from hosts/headful/flamingo/spotify.nix rename to hosts/headful/flamingo/supersonic.nix index 79817b7..8b4dba9 100644 --- a/hosts/headful/flamingo/spotify.nix +++ b/hosts/headful/flamingo/supersonic.nix @@ -1,5 +1,5 @@ { services.flatpak.packages = [ - "com.spotify.Client" + "io.github.dweymouth.supersonic" ]; } diff --git a/hosts/headful/insomniac/spotify.nix b/hosts/headful/glacier/supersonic.nix similarity index 52% rename from hosts/headful/insomniac/spotify.nix rename to hosts/headful/glacier/supersonic.nix index 79817b7..8b4dba9 100644 --- a/hosts/headful/insomniac/spotify.nix +++ b/hosts/headful/glacier/supersonic.nix @@ -1,5 +1,5 @@ { services.flatpak.packages = [ - "com.spotify.Client" + "io.github.dweymouth.supersonic" ]; } diff --git a/hosts/headful/glacier/users.nix b/hosts/headful/glacier/users.nix new file mode 100644 index 0000000..2ad58bc --- /dev/null +++ b/hosts/headful/glacier/users.nix @@ -0,0 +1,8 @@ +{ + users.users.futura = { + description = "Futura"; + uid = 1001; + isNormalUser = true; + password = "futura"; + }; +} diff --git a/hosts/headful/work/spotify.nix b/hosts/headful/insomniac/supersonic.nix similarity index 52% rename from hosts/headful/work/spotify.nix rename to hosts/headful/insomniac/supersonic.nix index 79817b7..8b4dba9 100644 --- a/hosts/headful/work/spotify.nix +++ b/hosts/headful/insomniac/supersonic.nix @@ -1,5 +1,5 @@ { services.flatpak.packages = [ - "com.spotify.Client" + "io.github.dweymouth.supersonic" ]; } diff --git a/hosts/headful/work/phps.nix b/hosts/headful/work/php.nix similarity index 68% rename from hosts/headful/work/phps.nix rename to hosts/headful/work/php.nix index be4b232..7e8e644 100644 --- a/hosts/headful/work/phps.nix +++ b/hosts/headful/work/php.nix @@ -25,6 +25,7 @@ xdebug.client_host = localhost ''; + # Wrap all PHP versions with the extensions I need and bundle composer phps = lib.genAttrs supportedPhps ( phpName: let phpBase = inputs.phps.packages.${pkgs.system}.${phpName}; @@ -47,7 +48,6 @@ paths = [ phpWithEnv phpWithEnv.packages.composer - pkgs.symfony-cli ]; }; in @@ -55,12 +55,32 @@ ); prefix = "/var/lib/phps"; + + # Tell Symfony's CLI where it can access the different PHP versions + symfony-cli = let + package = pkgs.symfony-cli; + in + pkgs.symlinkJoin { + inherit (package) pname version meta; + + paths = [package]; + + buildInputs = [pkgs.makeWrapper]; + + postBuild = '' + wrapProgram $out/bin/${package.meta.mainProgram} \ + --suffix PATH : ${pkgs.lib.makeBinPath ( + builtins.attrValues phps + )} + ''; + }; in { nix.settings = { substituters = ["https://fossar.cachix.org/"]; trusted-public-keys = ["fossar.cachix.org-1:Zv6FuqIboeHPWQS7ysLCJ7UT7xExb4OE8c4LyGb5AsE="]; }; + # Link PHP installations so that PhpStorm knows about them systemd.tmpfiles.settings = builtins.mapAttrs (name: drv: { "${prefix}/${name}"."L+".argument = drv.outPath; @@ -68,6 +88,8 @@ in { phps; environment.systemPackages = [ - phps.${selectedPhp}.packages.composer + pkgs.jetbrains.phpstorm + phps.${selectedPhp} + symfony-cli ]; } diff --git a/hosts/headful/work/phpstorm.nix b/hosts/headful/work/phpstorm.nix deleted file mode 100644 index 0796603..0000000 --- a/hosts/headful/work/phpstorm.nix +++ /dev/null @@ -1,5 +0,0 @@ -{pkgs, ...}: { - environment.systemPackages = [ - pkgs.jetbrains.phpstorm - ]; -} diff --git a/hosts/headful/work/plasma.nix b/hosts/headful/work/plasma.nix new file mode 100644 index 0000000..03996b4 --- /dev/null +++ b/hosts/headful/work/plasma.nix @@ -0,0 +1,35 @@ +{ + lib, + pkgs, + ... +}: { + services = { + desktopManager = { + cosmic.enable = lib.mkForce false; + plasma6.enable = true; + }; + displayManager = { + cosmic-greeter.enable = lib.mkForce false; + sddm = { + enable = true; + wayland.enable = true; + }; + }; + }; + + environment.systemPackages = [ + pkgs.kdePackages.sddm-kcm + pkgs.kdePackages.discover + pkgs.kdePackages.kate + ]; + + programs = { + kdeconnect.enable = true; + partition-manager.enable = true; + }; + + xdg.portal = { + xdgOpenUsePortal = true; + extraPortals = [pkgs.xdg-desktop-portal-gtk]; + }; +} diff --git a/hosts/headful/work/supersonic.nix b/hosts/headful/work/supersonic.nix new file mode 100644 index 0000000..8b4dba9 --- /dev/null +++ b/hosts/headful/work/supersonic.nix @@ -0,0 +1,5 @@ +{ + services.flatpak.packages = [ + "io.github.dweymouth.supersonic" + ]; +} diff --git a/hosts/headful/work/tools.nix b/hosts/headful/work/tools.nix new file mode 100644 index 0000000..2c2281e --- /dev/null +++ b/hosts/headful/work/tools.nix @@ -0,0 +1,10 @@ +{pkgs, ...}: { + environment.systemPackages = [ + pkgs.gnumake + pkgs.unzip + pkgs.pv + pkgs.jq + pkgs.mariadb + pkgs.openssl + ]; +} diff --git a/hosts/headless/abacus/backup.nix b/hosts/headless/abacus/backup.nix index 9156ae9..d6cef2f 100644 --- a/hosts/headless/abacus/backup.nix +++ b/hosts/headless/abacus/backup.nix @@ -12,6 +12,12 @@ paths = [ config.services.vaultwarden.backupDir config.services.syncthing.dataDir + config.services.forgejo.stateDir + config.services.postgresqlBackup.location + config.services.postgresqlBackup.location + # TODO: Add stateDir options for these + "/var/lib/headscale" + "/var/lib/navidrome" ]; passwordFile = config.age.secrets."restic-${attrName}".path; pruneOpts = ["--keep-daily 7" "--keep-weekly 5" "--keep-monthly 12"]; diff --git a/hosts/headless/abacus/firefox-syncserver.nix b/hosts/headless/abacus/firefox-syncserver.nix new file mode 100644 index 0000000..40e274a --- /dev/null +++ b/hosts/headless/abacus/firefox-syncserver.nix @@ -0,0 +1,37 @@ +# TODO: do this via tailscale? +# { +# config, +# lib, +# pkgs, +# ... +# }: let +# virtualHostName = "syncserver.helveticanonstandard.net"; +# in { +# age.secrets = lib.mkSecrets {syncserver = {};}; +# +# services.firefox-syncserver = { +# enable = true; +# secrets = config.age.secrets.syncserver.path; +# singleNode = { +# enable = true; +# hostname = virtualHostName; +# url = "https://${virtualHostName}"; +# }; +# settings = { +# port = 8070; +# }; +# }; +# +# services.nginx.virtualHosts.${config.services.firefox-syncserver.singleNode.hostname} = { +# enableACME = true; +# forceSSL = true; +# +# locations."/".proxyPass = let +# host = "127.0.0.1"; +# port = builtins.toString config.services.firefox-syncserver.settings.port; +# in "http://${host}:${port}"; +# }; +# +# services.mysql.package = pkgs.mariadb; +# } +{} diff --git a/hosts/headless/abacus/forgejo.nix b/hosts/headless/abacus/forgejo.nix index 69911ed..4cc5186 100644 --- a/hosts/headless/abacus/forgejo.nix +++ b/hosts/headless/abacus/forgejo.nix @@ -1,6 +1,7 @@ { config, lib, + pkgs, ... }: let virtualHostName = "forgejo.helveticanonstandard.net"; @@ -50,24 +51,26 @@ in { secrets.mailer.PASSWD = config.age.secrets.forgejo-mailer.path; }; - systemd.services.forgejo.preStart = let - forgejo = lib.getExe config.services.forgejo.package; - passwordFile = config.age.secrets.forgejo-admin.path; - user = "helvetica"; - email = "helvetica@helveticanonstandard.net"; - in '' - if ! \ - ${forgejo} admin user change-password \ - --username ${lib.escapeShellArg user} \ - --password "$(cat -- ${lib.escapeShellArg passwordFile})" - then - ${forgejo} admin user create \ - --admin \ - --email ${lib.escapeShellArg email} \ - --username ${lib.escapeShellArg user} \ - --password "$(cat -- ${lib.escapeShellArg passwordFile})" - fi - ''; + systemd.services.forgejo.preStart = lib.getExe pkgs.writeShellApplication { + name = "forgejo-init-admin"; + runtimeInputs = [ + config.services.forgejo.package + ]; + text = let + passwordFile = config.age.secrets.forgejo-admin.path; + in '' + admins=$(admin user list --admin) + admins=$((admins - 1)) + + if ((admins < 1)); then + gitea admin user create \ + --admin \ + --email helvetica@helveticanonstandard.net \ + --username helvetica \ + --password "$(cat -- ${passwordFile})" + fi + ''; + }; services.nginx.virtualHosts.${virtualHostName} = { enableACME = true; diff --git a/hosts/headless/abacus/mariadb.nix b/hosts/headless/abacus/mariadb.nix new file mode 100644 index 0000000..6f40a90 --- /dev/null +++ b/hosts/headless/abacus/mariadb.nix @@ -0,0 +1,10 @@ +# {pkgs, ...}: { +# services.mysql.package = pkgs.mariadb; +# +# services.mysqlBackup = { +# enable = true; +# startAt = "*-*-* 02:00:00"; +# location = "/srv/backup/postgresql"; +# }; +# } +{} diff --git a/hosts/headless/abacus/mealie.nix b/hosts/headless/abacus/mealie.nix new file mode 100644 index 0000000..7601750 --- /dev/null +++ b/hosts/headless/abacus/mealie.nix @@ -0,0 +1,23 @@ +{config, ...}: let + virtualHostName = "mealie.helveticanonstandard.net"; +in { + services.mealie = { + enable = true; + settings = { + BASE_URL = "https://${virtualHostName}"; + ALLOW_SIGNUP = false; + }; + listenAddress = "127.0.0.1"; + port = 8040; + }; + + services.nginx.virtualHosts.${virtualHostName} = { + enableACME = true; + forceSSL = true; + + locations."/".proxyPass = let + host = config.services.mealie.listenAddress; + port = builtins.toString config.services.mealie.port; + in "http://${host}:${port}"; + }; +} diff --git a/hosts/headless/abacus/postgresql.nix b/hosts/headless/abacus/postgresql.nix new file mode 100644 index 0000000..7bff95f --- /dev/null +++ b/hosts/headless/abacus/postgresql.nix @@ -0,0 +1,8 @@ +{ + services.postgresqlBackup = { + enable = true; + startAt = "*-*-* 02:00:00"; + location = "/srv/backup/postgresql"; + backupAll = true; + }; +} diff --git a/hosts/headless/vessel/musicomp.nix b/hosts/headless/vessel/musicomp.nix index ed4c090..56b75b2 100644 --- a/hosts/headless/vessel/musicomp.nix +++ b/hosts/headless/vessel/musicomp.nix @@ -1,9 +1,14 @@ { + inputs, self, lib, pkgs, ... }: { + imports = [ + inputs.musicomp.nixosModules.default + ]; + services.musicomp.jobs.main = { music = "/srv/music"; comp = "/srv/compmusic"; diff --git a/modules/musicomp.nix b/modules/musicomp.nix deleted file mode 100644 index e78ed31..0000000 --- a/modules/musicomp.nix +++ /dev/null @@ -1,116 +0,0 @@ -{ - self, - lib, - pkgs, - utils, - config, - ... -}: let - inherit (lib) types; - inherit (utils.systemdUtils.unitOptions) unitOption; -in { - options.services.musicomp.jobs = lib.mkOption { - description = '' - Compression jobs to run with musicomp. - ''; - default = {}; - type = types.attrsOf (types.submodule { - options = { - music = lib.mkOption { - type = types.str; - description = '' - Source directory. - ''; - example = "/srv/music"; - }; - - comp = lib.mkOption { - type = types.str; - description = '' - Destination directory for compressed music. - ''; - example = "/srv/comp"; - }; - - post = lib.mkOption { - type = types.lines; - default = ""; - description = '' - Shell commands that are run after compression has finished. - ''; - }; - - workers = lib.mkOption { - type = lib.types.int; - default = 0; - description = '' - Number of workers. - ''; - }; - - timerConfig = lib.mkOption { - type = lib.types.nullOr (lib.types.attrsOf unitOption); - default = { - OnCalendar = "daily"; - Persistent = true; - }; - description = '' - When to run the job. - ''; - }; - - package = lib.mkPackageOption self.packages.${pkgs.system} "musicomp" {}; - - inhibitsSleep = lib.mkOption { - default = false; - type = lib.types.bool; - example = true; - description = '' - Prevents the system from sleeping while running the job. - ''; - }; - }; - }); - }; - - config = { - systemd.services = - lib.mapAttrs' - ( - name: job: - lib.nameValuePair "musicomp-jobs-${name}" { - wantedBy = ["multi-user.target"]; - restartIfChanged = false; - - script = '' - ${lib.optionalString job.inhibitsSleep '' - ${lib.getExe' pkgs.systemd "systemd-inhibit"} \ - --mode block \ - --who musicomp \ - --what sleep \ - --why ${lib.escapeShellArg "Scheduled musicomp ${name}"} - ''} - - ${lib.getExe job.package} \ - ${lib.optionalString (job.workers > 0) "--workers ${job.workers}"} \ - --verbose \ - -- ${job.music} ${job.comp} - ''; - - postStart = job.post; - - serviceConfig.Type = "oneshot"; - } - ) - config.services.musicomp.jobs; - - systemd.timers = - lib.mapAttrs' - (name: job: - lib.nameValuePair "musicomp-jobs-${name}" { - wantedBy = ["timers.target"]; - inherit (job) timerConfig; - }) - (lib.filterAttrs (_: job: job.timerConfig != null) config.services.musicomp.jobs); - }; -} diff --git a/packages/musicomp/README.md b/packages/musicomp/README.md deleted file mode 100644 index fcec2e7..0000000 --- a/packages/musicomp/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# musicomp - -A music compression tool. diff --git a/packages/musicomp/package.nix b/packages/musicomp/package.nix deleted file mode 100644 index 28f7348..0000000 --- a/packages/musicomp/package.nix +++ /dev/null @@ -1,26 +0,0 @@ -{ - lib, - python3Packages, - opusTools, -}: -python3Packages.buildPythonApplication { - pname = "musicomp"; - version = "0.1.0"; - - src = ./.; - - pyproject = true; - - doCheck = false; - - build-system = [python3Packages.hatchling]; - - makeWrapperArgs = [ - "--prefix" - "PATH" - ":" - (lib.makeBinPath [opusTools]) - ]; - - meta.mainProgram = "musicomp"; -} diff --git a/packages/musicomp/pyproject.toml b/packages/musicomp/pyproject.toml deleted file mode 100644 index 4a0d811..0000000 --- a/packages/musicomp/pyproject.toml +++ /dev/null @@ -1,17 +0,0 @@ -[project] -name = "musicomp" -version = "0.1.0" -description = "Music compression tool" -authors = [{ name = "Lukas Wurzinger", email = "lukas@wrz.one" }] -readme = "README.md" -requires-python = ">=3.12" - -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[project.scripts] -musicomp = "musicomp.cli:main" - -[tool.hatch.build.targets.wheel] -packages = ["src/musicomp"] diff --git a/packages/musicomp/src/musicomp/__main__.py b/packages/musicomp/src/musicomp/__main__.py deleted file mode 100644 index 4e28416..0000000 --- a/packages/musicomp/src/musicomp/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .cli import main - -main() diff --git a/packages/musicomp/src/musicomp/clean.py b/packages/musicomp/src/musicomp/clean.py deleted file mode 100644 index 2e2107d..0000000 --- a/packages/musicomp/src/musicomp/clean.py +++ /dev/null @@ -1,6 +0,0 @@ -from os import PathLike -from pathlib import Path - - -def clean(dst: str | PathLike[str]) -> None: - Path(dst).unlink(missing_ok=True) diff --git a/packages/musicomp/src/musicomp/cli.py b/packages/musicomp/src/musicomp/cli.py deleted file mode 100644 index c9fc7aa..0000000 --- a/packages/musicomp/src/musicomp/cli.py +++ /dev/null @@ -1,117 +0,0 @@ -import sys -from multiprocessing import Pool, cpu_count -from argparse import ArgumentParser, ArgumentTypeError, Namespace -from pathlib import Path -from .todo import Todo - -args = Namespace() - - -def task(todo: Todo) -> None: - todo.run() - if args.verbose: - print("finished", todo, file=sys.stderr) - - -def main(): - def workers_type_func(value: object) -> int: - try: - value = int(value) # pyright: ignore[reportArgumentType] - if value <= 0: - raise ArgumentTypeError(f"{value} is not a positive integer") - except ValueError: - raise ArgumentTypeError(f"{value} is not an integer") - - return value - - parser = ArgumentParser() - - _ = parser.add_argument( - "-w", - "--workers", - default=cpu_count(), - type=workers_type_func, - help="amount of worker processes", - ) - _ = parser.add_argument( - "-i", - "--interactive", - action="store_true", - help="prompt before running", - ) - _ = parser.add_argument( - "-k", - "--keep", - action="store_true", - help="whether source files should be kept if both directories are the same", - ) - _ = parser.add_argument( - "-r", - "--redo", - action="store_true", - help="whether everything should be re-encoded regardless of whether they have already been transcoded", - ) - _ = parser.add_argument( - "-v", - "--verbose", - action="count", - default=0, - help="verbose output", - ) - - _ = parser.add_argument( - "music", - nargs=1, - type=Path, - help="the source directory", - ) - _ = parser.add_argument( - "comp", - nargs=1, - type=Path, - help="the destination directory for compressed files", - ) - - global args - args = parser.parse_args(sys.argv[1:]) - - assert isinstance(args.workers, int) # pyright: ignore[reportAny] - assert isinstance(args.interactive, bool) # pyright: ignore[reportAny] - assert isinstance(args.keep, bool) # pyright: ignore[reportAny] - assert isinstance(args.redo, bool) # pyright: ignore[reportAny] - assert isinstance(args.verbose, int) # pyright: ignore[reportAny] - assert isinstance(args.music, list) # pyright: ignore[reportAny] - assert len(args.music) == 1 # pyright: ignore[reportUnknownMemberType, reportUnknownArgumentType] - assert isinstance(args.music[0], Path) # pyright: ignore[reportUnknownMemberType] - assert isinstance(args.comp, list) # pyright: ignore[reportAny] - assert len(args.comp) == 1 # pyright: ignore[reportUnknownMemberType, reportUnknownArgumentType] - assert isinstance(args.comp[0], Path) # pyright: ignore[reportUnknownMemberType] - - src_dir = args.music[0] # pyright: ignore[reportUnknownMemberType] - dst_dir = args.comp[0] # pyright: ignore[reportUnknownMemberType] - - plan = list( - Todo.plan( - src_dir, - dst_dir, - replace=src_dir.samefile(dst_dir) and not args.keep, - redo=args.redo, - ) - ) - - if len(plan) == 0: - print("Nothing to do", file=sys.stderr) - sys.exit(0) - - if args.verbose >= 1 or args.interactive: - print("Plan:", file=sys.stderr) - for todo in plan: - print(todo, file=sys.stderr) - - if args.interactive: - result = input("Do you want to continue? [Y/n] ") - if result.lower() not in ("", "y", "yes"): - sys.exit(1) - - with Pool(args.workers) as pool: - _ = pool.map(task, plan) diff --git a/packages/musicomp/src/musicomp/replace.py b/packages/musicomp/src/musicomp/replace.py deleted file mode 100644 index 097f5f3..0000000 --- a/packages/musicomp/src/musicomp/replace.py +++ /dev/null @@ -1,6 +0,0 @@ -from os import PathLike -from pathlib import Path - - -def replace(src: str | PathLike[str]) -> None: - Path(src).unlink(missing_ok=True) diff --git a/packages/musicomp/src/musicomp/todo.py b/packages/musicomp/src/musicomp/todo.py deleted file mode 100644 index b9e2142..0000000 --- a/packages/musicomp/src/musicomp/todo.py +++ /dev/null @@ -1,68 +0,0 @@ -from pathlib import Path -from os import PathLike -from enum import StrEnum -from dataclasses import dataclass -from typing import Self, override -from collections.abc import Generator -from .transcode import transcode as todo_transcode -from .clean import clean as todo_clean -from .replace import replace as todo_replace - -SRC_SUFFIX = ".flac" -DST_SUFFIX = ".opus" - - -class TodoAct(StrEnum): - TRANSCODE = "transcode" - CLEAN = "clean" - REPLACE = "replace" - - -@dataclass -class Todo: - act: TodoAct - src: str | PathLike[str] - dst: str | PathLike[str] - - @classmethod - def plan( - cls: type[Self], - src_dir: str | PathLike[str], - dst_dir: str | PathLike[str], - replace: bool = False, - redo: bool = False, - ) -> Generator[Self]: - def list_files(dir: str | PathLike[str], suffix: str) -> list[Path]: - files: list[Path] = [] - for f in Path(dir).rglob("*"): - if f.is_file() and f.suffix == suffix: - files.append(f) - return files - - src_files = list_files(src_dir, SRC_SUFFIX) - dst_files = list_files(dst_dir, DST_SUFFIX) - - for f in src_files: - e = dst_dir / (f.relative_to(src_dir).with_suffix(DST_SUFFIX)) - if redo or e not in dst_files: - yield cls(TodoAct.TRANSCODE, f, e) - if replace: - yield cls(TodoAct.REPLACE, f, e) - - for f in dst_files: - e = src_dir / (f.relative_to(dst_dir).with_suffix(SRC_SUFFIX)) - if e not in src_files: - yield cls(TodoAct.CLEAN, f, e) - - def run(self) -> None: - match self.act: - case TodoAct.TRANSCODE: - todo_transcode(self.src, self.dst) - case TodoAct.CLEAN: - todo_clean(self.dst) - case TodoAct.REPLACE: - todo_replace(self.src) - - @override - def __str__(self) -> str: - return f"{self.act} {self.src} -> {self.dst}" diff --git a/packages/musicomp/src/musicomp/transcode.py b/packages/musicomp/src/musicomp/transcode.py deleted file mode 100644 index 7ccd74b..0000000 --- a/packages/musicomp/src/musicomp/transcode.py +++ /dev/null @@ -1,34 +0,0 @@ -from pathlib import Path -from subprocess import run -from os import PathLike - - -class TranscodingError(Exception): - pass - - -def transcode(src: str | PathLike[str], dst: str | PathLike[str]) -> None: - dst = Path(dst) - - dst.parent.mkdir(parents=True, exist_ok=True) - - if dst.is_file(): - dst.unlink() - - opusenc: tuple[str, ...] = ( - "opusenc", - "--quiet", - "--bitrate", - "96.000", - "--music", - "--vbr", - "--comp", - "10", - "--", - str(src), - str(dst), - ) - - cp = run(opusenc) - if cp.returncode != 0: - raise TranscodingError(f"opusenc exited with code {cp.returncode}") diff --git a/secrets/secrets.nix b/secrets/secrets.nix index adda8aa..0a37768 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -14,4 +14,6 @@ in { "restic-vessel.age".publicKeys = (builtins.attrValues users) ++ [hosts.vessel]; "restic-abacus.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; + + "syncserver.age".publicKeys = (builtins.attrValues users) ++ [hosts.abacus]; } diff --git a/secrets/syncserver.age b/secrets/syncserver.age new file mode 100644 index 0000000..6256bf7 Binary files /dev/null and b/secrets/syncserver.age differ