From caab166af8c018cb367a85cbb18788a0129b075a Mon Sep 17 00:00:00 2001 From: Erik Simon Date: Fri, 24 Jul 2026 00:35:13 +0200 Subject: [PATCH] terra: package Tome, add vivaldi + dotnet dev tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tome (née AudibleLibrary) is darman's own Photino/.NET desktop app, private repo on our own gitea. Fetched as a flake input over ssh with darman's ambient key — same mechanism as any other git input, private or not. buildDotnetModule package: the Preact/Vite frontend (Tome.App/ClientApp) builds as its own buildNpmPackage derivation and gets copied into the published app's wwwroot, since upstream's in-project MSBuild npm target has no network access in the Nix sandbox. Photino.Native's runtime deps (gtk3, webkitgtk_4_1, libnotify) are wrapped in — confirmed via readelf/ldd that this Photino build already targets webkit2gtk-4.1, not the now-removed 4.0. Also added dotnet-sdk + nodejs to terra for developing Tome locally, and vivaldi (unfree, extends the existing allowUnfreePredicate). Co-Authored-By: Claude Sonnet 5 --- flake.lock | 19 +- flake.nix | 12 ++ pkgs/tome-deps.json | 282 ++++++++++++++++++++++++++++++ pkgs/tome.nix | 82 +++++++++ services/desktop/desktop-apps.nix | 10 +- 5 files changed, 403 insertions(+), 2 deletions(-) create mode 100644 pkgs/tome-deps.json create mode 100644 pkgs/tome.nix diff --git a/flake.lock b/flake.lock index ef043ed..ac5155a 100644 --- a/flake.lock +++ b/flake.lock @@ -425,7 +425,8 @@ "nixpkgs": "nixpkgs_2", "nixpkgs-unstable": "nixpkgs-unstable", "proton-pass-cli": "proton-pass-cli", - "sops-nix": "sops-nix" + "sops-nix": "sops-nix", + "tome": "tome" } }, "sops-nix": { @@ -463,6 +464,22 @@ "type": "github" } }, + "tome": { + "flake": false, + "locked": { + "lastModified": 1784844989, + "narHash": "sha256-b9cr5QeVx+GSUTU0Wc85jqhg8FCFIKZ5TI1k4CE2Ca0=", + "ref": "refs/heads/master", + "rev": "4b48640dcd66cdb2e6922a1fc50b28dbfb8b67ef", + "revCount": 45, + "type": "git", + "url": "ssh://gitea@git.mgaction.town:2222/darman/TOME.git" + }, + "original": { + "type": "git", + "url": "ssh://gitea@git.mgaction.town:2222/darman/TOME.git" + } + }, "uv2nix": { "inputs": { "nixpkgs": [ diff --git a/flake.nix b/flake.nix index 7841405..b092588 100644 --- a/flake.nix +++ b/flake.nix @@ -38,6 +38,14 @@ url = "github:tomsch/proton-pass-cli-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + # Tome (formerly AudibleLibrary) — darman's own .NET/Photino desktop app. + # Private repo on our own gitea; fetched over ssh with darman's ambient key, + # same as any other git flake input. `flake = false`: it's a plain source + # tree, not itself a flake. See pkgs/tome.nix. + tome = { + url = "git+ssh://gitea@git.mgaction.town:2222/darman/TOME.git"; + flake = false; + }; }; outputs = { self, nixpkgs, disko, sops-nix, nixos-images, home-manager, mediamanager-nix, authentik-nix, ... }@inputs: @@ -45,6 +53,10 @@ system = "x86_64-linux"; in { + packages.${system}.tome = nixpkgs.legacyPackages.${system}.callPackage ./pkgs/tome.nix { + src = inputs.tome; + }; + nixosConfigurations = { # Real host — install on the ZimaBlade. # disko owns the OS-disk partitioning + filesystems (see disk-config.nix). diff --git a/pkgs/tome-deps.json b/pkgs/tome-deps.json new file mode 100644 index 0000000..5c356a1 --- /dev/null +++ b/pkgs/tome-deps.json @@ -0,0 +1,282 @@ +[ + { + "pname": "AAXClean", + "version": "3.0.2", + "hash": "sha256-orz5qHU440qYIPKP92aPHUALHP6+RphJWU8vYGl/2Qo=" + }, + { + "pname": "CaseConverter", + "version": "2.0.1", + "hash": "sha256-6tcUIfKDACbQfBJ2pERmYG3j4+rAcGFZLgwJu9LnD0I=" + }, + { + "pname": "FastExpressionCompiler", + "version": "5.1.1", + "hash": "sha256-58mSrlp08akN145R3f+MV71REvjrajf1LRQX9g7QWog=" + }, + { + "pname": "HtmlAgilityPack", + "version": "1.11.71", + "hash": "sha256-ddNrIXTfiu8gwrUs/5xYDjpD0sOth90kut6qCgxGUSE=" + }, + { + "pname": "ImTools", + "version": "4.0.0", + "hash": "sha256-pP01ssU4cRhtqjaCfvTHgvAG9IhKKJHCx9cEg7OZeb0=" + }, + { + "pname": "JasperFx", + "version": "1.10.1", + "hash": "sha256-jvpPkAX2QQXy8MGLNA1/6QRxuy769EBwqcREom2VMMA=" + }, + { + "pname": "Lamar", + "version": "16.0.0", + "hash": "sha256-03f6sbBCTf0h3499lJNOx2nAzuWKfdOEV/Ig/ouP1Bc=" + }, + { + "pname": "Lamar.Microsoft.DependencyInjection", + "version": "16.0.0", + "hash": "sha256-GoaRQ4DoOHzMFMK6k71cfHSfCDIoJrUUfg2wYEwyCyY=" + }, + { + "pname": "Microsoft.AspNetCore.App.Ref", + "version": "8.0.27", + "hash": "sha256-nwBrMFATFwpJS1iq9Bf+vvWQ1dDGergMuY809tUqo60=" + }, + { + "pname": "Microsoft.AspNetCore.App.Ref", + "version": "9.0.16", + "hash": "sha256-lBbgyPyZOrPsRMtd0UOHJuB5dbMQFysVIk4RAFx2Rk0=" + }, + { + "pname": "Microsoft.AspNetCore.App.Runtime.linux-x64", + "version": "8.0.27", + "hash": "sha256-7DX4XBTx8a6sFRnTrJ3zJhJzQVC81OwzOZnYOo+nO20=" + }, + { + "pname": "Microsoft.AspNetCore.App.Runtime.linux-x64", + "version": "9.0.16", + "hash": "sha256-JDdPuh01rffoWnKekJU34/QKWFFnyTljmqq6DM5vYs8=" + }, + { + "pname": "Microsoft.Bcl.TimeProvider", + "version": "8.0.1", + "hash": "sha256-TQRaWjk1aZu+jn/rR8oOv8BJEG31i6mPkf3BkIR7C+c=" + }, + { + "pname": "Microsoft.Build.Tasks.Git", + "version": "10.0.102", + "hash": "sha256-JobfcsngZ3NjWtrfb03ZiGQ0xLEXUeFjC5MRjBEJ+Qo=" + }, + { + "pname": "Microsoft.Extensions.Configuration", + "version": "10.0.5", + "hash": "sha256-6rOmJD7Jzq5MPLDd1aV+7gCQwIM9j4c+iT1pGea/daI=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Abstractions", + "version": "10.0.5", + "hash": "sha256-DNK+lL2jeHFYyd43zfgVY32UskEfQ4YsTapztuQbYwo=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Binder", + "version": "10.0.5", + "hash": "sha256-cVG2NEW1rgLfeq/Gnh/XXqzDx2Tt8ecvgCAB4uFzcQo=" + }, + { + "pname": "Microsoft.Extensions.Configuration.CommandLine", + "version": "10.0.5", + "hash": "sha256-q5KS8ZtQTkc4WSjqczVIWbFZzdGNxbannVocNSi+coI=" + }, + { + "pname": "Microsoft.Extensions.Configuration.EnvironmentVariables", + "version": "10.0.5", + "hash": "sha256-ngWw/kwYWNmK67ErLFoJDKULd4GOXv6MlD6P+eZ4q6A=" + }, + { + "pname": "Microsoft.Extensions.Configuration.FileExtensions", + "version": "10.0.5", + "hash": "sha256-PUIRpSxnT41HnF/6ZPMe7oAAAJ8gm6mNGRuPhw5Zy6k=" + }, + { + "pname": "Microsoft.Extensions.Configuration.Json", + "version": "10.0.5", + "hash": "sha256-jxcGaQpr8RRQVtCobxvCOyn+8k/U2m5H5/ltFYhdKAk=" + }, + { + "pname": "Microsoft.Extensions.Configuration.UserSecrets", + "version": "10.0.5", + "hash": "sha256-ROkQPXDOFU3hOrKtdwvRNR3so5eFLaJxJDxqhDX8IpU=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection", + "version": "10.0.5", + "hash": "sha256-ofDRirUV9XLSz4oksCqErwBJFtAieHACFfyZukHKFng=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "10.0.5", + "hash": "sha256-KrP+hE3gk7pATbJYZsJ1LHiXjzLA+ntHW7G/VGgHk2g=" + }, + { + "pname": "Microsoft.Extensions.DependencyInjection.Abstractions", + "version": "10.0.9", + "hash": "sha256-YzQpGAsrjLU18s016LmM7DMJKml0MzKl1bPPYJ/erEk=" + }, + { + "pname": "Microsoft.Extensions.Diagnostics", + "version": "10.0.5", + "hash": "sha256-LlFT3ZzFH9QfymvP9DY4NteJKTdT+mqSGpzUDpsLNhM=" + }, + { + "pname": "Microsoft.Extensions.Diagnostics.Abstractions", + "version": "10.0.5", + "hash": "sha256-pwQltVfaqx0jRpO0d9k/dYtyOpnGixK2MB3aHVVbo0E=" + }, + { + "pname": "Microsoft.Extensions.FileProviders.Abstractions", + "version": "10.0.5", + "hash": "sha256-6RwvzBQTJzbypUQAM9WNRkpn3gON63DLxY3gH0ZcrH4=" + }, + { + "pname": "Microsoft.Extensions.FileProviders.Physical", + "version": "10.0.5", + "hash": "sha256-36irJIKuzhCmA28CC4U8+3W8EJ5U9PwMMdCSXRCp4J0=" + }, + { + "pname": "Microsoft.Extensions.FileSystemGlobbing", + "version": "10.0.5", + "hash": "sha256-FdwPwpyNejk8YEw4doaouas0oe+8d7K2m49WH+7k0RE=" + }, + { + "pname": "Microsoft.Extensions.Hosting", + "version": "10.0.5", + "hash": "sha256-NJFH/l2wutMISKLZzMqFZfY1/QuMskSAhgWelo9V6Nc=" + }, + { + "pname": "Microsoft.Extensions.Hosting.Abstractions", + "version": "10.0.5", + "hash": "sha256-mqxu+PvqYP/J/9UWEbLIAfSNnsABhdl6m5wkZFf1DDM=" + }, + { + "pname": "Microsoft.Extensions.Logging", + "version": "10.0.5", + "hash": "sha256-4gVrKZfo/YHZKgKNsgGZZYqa79XWK9wDUuiVfguUV6U=" + }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "10.0.5", + "hash": "sha256-e3A/l+II+n+D7/OPwjdyQM1IBtKHfHeIdlkJmuRw77w=" + }, + { + "pname": "Microsoft.Extensions.Logging.Abstractions", + "version": "10.0.9", + "hash": "sha256-su2q/OZuG7nB3wnUTVcimy3oHSdetFh4hhmjI3f/ym8=" + }, + { + "pname": "Microsoft.Extensions.Logging.Configuration", + "version": "10.0.5", + "hash": "sha256-yp0WZcCm+SAkMP9U/B3Dg/v282pFMXbZHVzAp2GLGwA=" + }, + { + "pname": "Microsoft.Extensions.Logging.Console", + "version": "10.0.5", + "hash": "sha256-Epf70cMofVjqKQxTTgsmNNRW8YcpHj5c80nX8cJTv40=" + }, + { + "pname": "Microsoft.Extensions.Logging.Debug", + "version": "10.0.5", + "hash": "sha256-g6jXBWDCXXUpmygKkVChZq8vUqJgG7qFTJPI0BD32oo=" + }, + { + "pname": "Microsoft.Extensions.Logging.EventLog", + "version": "10.0.5", + "hash": "sha256-RWePIK3PZcc6ULwQa+zZMx+LCJf3jlVERnyPMVJl1ks=" + }, + { + "pname": "Microsoft.Extensions.Logging.EventSource", + "version": "10.0.5", + "hash": "sha256-YV2ff+tl3fpFkYZ3xOqosugYR5ai4oWKovK/HqDGdTc=" + }, + { + "pname": "Microsoft.Extensions.Options", + "version": "10.0.5", + "hash": "sha256-nw+m6VWXjmaBqZ1aH/l9SR9Oy62N9dmiMKloJ78kxv8=" + }, + { + "pname": "Microsoft.Extensions.Options.ConfigurationExtensions", + "version": "10.0.5", + "hash": "sha256-VQPPvrvYWY/QpmilerCyTNLVejWeBE9mHtGTMOxXUlg=" + }, + { + "pname": "Microsoft.Extensions.Primitives", + "version": "10.0.5", + "hash": "sha256-uvrur+0dg4zAAQcpLkkhPA77ST0tA3+EpGdDlCckC+E=" + }, + { + "pname": "Microsoft.NETCore.App.Host.linux-x64", + "version": "8.0.27", + "hash": "sha256-ZI5ByoSqJIcQAnH1dyGcK8uyvPB7yUNznD6BLY2V8Hs=" + }, + { + "pname": "Microsoft.NETCore.App.Host.linux-x64", + "version": "9.0.16", + "hash": "sha256-HaIx6pwpKUwdseu3tOhuVtqnpGCubhWbi9BEvijHd+M=" + }, + { + "pname": "Microsoft.NETCore.App.Ref", + "version": "8.0.27", + "hash": "sha256-F/FL0ptluwCfxN4S93/UAKs4fRtyL+D4NoSPc5CGyJo=" + }, + { + "pname": "Microsoft.NETCore.App.Ref", + "version": "9.0.16", + "hash": "sha256-VLwChaPID3roiQw6qU8IuPaUOPAHl3wzCIjVtG4D6ZM=" + }, + { + "pname": "Microsoft.NETCore.App.Runtime.linux-x64", + "version": "8.0.27", + "hash": "sha256-GejthwcyJAmNTFvWEZXis6lRM2sJyNrKHYsq79Fn/WI=" + }, + { + "pname": "Microsoft.NETCore.App.Runtime.linux-x64", + "version": "9.0.16", + "hash": "sha256-3nDEdBN1jHIy2PiLffnE4+Snt7MiGP2hEDEi924DXww=" + }, + { + "pname": "Microsoft.SourceLink.Common", + "version": "10.0.102", + "hash": "sha256-1aeVLhXNi4Fpi0w4zQ+85L7Sphe7k4gmMfxwWiFierM=" + }, + { + "pname": "Microsoft.SourceLink.GitHub", + "version": "10.0.102", + "hash": "sha256-5aBeXy674sKp6wrlpPb4Psht43mF1OMJkmEggsTGUDg=" + }, + { + "pname": "Photino.Native", + "version": "4.0.22", + "hash": "sha256-owM7RGwFd6X5bw1ttMgaQ6qf+157d2OHv5IJp+VlYXs=" + }, + { + "pname": "Polly.Core", + "version": "8.5.2", + "hash": "sha256-PAwsWqrCieCf/7Y87fV7XMKoaY2abCQNtI+4oyyMifk=" + }, + { + "pname": "Spectre.Console", + "version": "0.53.0", + "hash": "sha256-XnzZoDD32DZqK/tmPVaXaclJJzb25SyMLzQ7xX3XLQw=" + }, + { + "pname": "System.Diagnostics.DiagnosticSource", + "version": "10.0.9", + "hash": "sha256-atVKtt+sHv0bAcJwchFYYT5PO/dcDnaeidrN42GqgSg=" + }, + { + "pname": "System.Diagnostics.EventLog", + "version": "10.0.5", + "hash": "sha256-SwmQif5X/T4cIPPNkVf6QsvA3oBLb85iJXNkb3GT+sU=" + } +] diff --git a/pkgs/tome.nix b/pkgs/tome.nix new file mode 100644 index 0000000..6d03595 --- /dev/null +++ b/pkgs/tome.nix @@ -0,0 +1,82 @@ +{ lib +, buildDotnetModule +, buildNpmPackage +, importNpmLock +, dotnetCorePackages +, gtk3 +, webkitgtk_4_1 +, libnotify +, makeDesktopItem +, copyDesktopItems +, src +}: + +# Tome (née AudibleLibrary) — darman's own Photino/.NET desktop app for +# converting/managing an Audible library. Private repo on our own gitea; +# `src` is threaded in by the caller from the `tome` flake input rather than +# fetched here, so this file has no credentials or URL baked in. +# +# Two-stage build: the Preact/Vite frontend (Tome.App/ClientApp) is built as +# its own npm derivation, then copied into the published app's wwwroot. +# Upstream normally does this via an in-project MSBuild npm target, +# which has no network access in the Nix sandbox — skipped here +# (-p:SkipNpmBuild=true) in favor of doing it as a proper Nix derivation. +let + frontend = buildNpmPackage { + pname = "tome-frontend"; + version = "0.0.0"; + src = "${src}/Tome.App/ClientApp"; + npmDeps = importNpmLock { npmRoot = "${src}/Tome.App/ClientApp"; }; + npmConfigHook = importNpmLock.npmConfigHook; + installPhase = '' + runHook preInstall + cp -r dist $out + runHook postInstall + ''; + }; +in +buildDotnetModule (finalAttrs: { + pname = "tome"; + version = "0-unstable"; + + inherit src; + + projectFile = "Tome.App/Tome.App.csproj"; + nugetDeps = ./tome-deps.json; + + dotnet-sdk = dotnetCorePackages.sdk_10_0; + dotnet-runtime = dotnetCorePackages.runtime_10_0; + + dotnetFlags = [ "-p:SkipNpmBuild=true" ]; + + executables = [ "Tome.App" ]; + + nativeBuildInputs = [ copyDesktopItems ]; + + runtimeDeps = [ + gtk3 + webkitgtk_4_1 + libnotify + ]; + + postInstall = '' + cp -r ${frontend} $out/lib/${finalAttrs.pname}/wwwroot + ''; + + desktopItems = [ + (makeDesktopItem { + name = "tome"; + exec = "Tome.App"; + desktopName = "Tome"; + comment = "Audible library manager"; + categories = [ "AudioVideo" ]; + }) + ]; + + meta = { + description = "Audible library manager (Photino/.NET desktop app)"; + homepage = "https://git.mgaction.town/darman/TOME"; + platforms = [ "x86_64-linux" ]; + mainProgram = "Tome.App"; + }; +}) diff --git a/services/desktop/desktop-apps.nix b/services/desktop/desktop-apps.nix index 2e589fa..09a9a18 100644 --- a/services/desktop/desktop-apps.nix +++ b/services/desktop/desktop-apps.nix @@ -1,7 +1,8 @@ -{ pkgs, lib, ... }: +{ pkgs, lib, inputs, ... }: let rishot = pkgs.callPackage ../../pkgs/rishot.nix { }; + tome = pkgs.callPackage ../../pkgs/tome.nix { src = inputs.tome; }; in # Desktop applications for a workstation host (currently: terra). Split from @@ -16,6 +17,7 @@ in "steam-unwrapped" "steam-run" "claude-code" + "vivaldi" ]; programs.steam = { @@ -32,7 +34,13 @@ in gitkraken jetbrains-toolbox kdePackages.dolphin + vivaldi rishot + tome + + # Tome development (Tome.App targets net10.0; ClientApp is Preact/Vite). + dotnetCorePackages.sdk_10_0 + nodejs ]; fonts.packages = [ pkgs.nerd-fonts.departure-mono ];