From 6b8cea647349f53f2d57399535478001bebed053 Mon Sep 17 00:00:00 2001
From: hauskens <hauskens-git@disp.lease>
Date: Sun, 5 Jan 2025 18:03:51 +0100
Subject: [PATCH] easyeffects: add option to import presets

added options to import presets
added tests
added hausken as maintainer
---
 modules/misc/news.nix                         |  8 +++
 modules/services/easyeffects.nix              | 54 +++++++++++++++++++
 tests/default.nix                             |  1 +
 .../modules/services/easyeffects/default.nix  |  4 ++
 .../services/easyeffects/example-preset.json  | 18 +++++++
 .../services/easyeffects/example-preset.nix   | 36 +++++++++++++
 .../modules/services/easyeffects/service.nix  | 14 +++++
 7 files changed, 135 insertions(+)
 create mode 100644 tests/modules/services/easyeffects/default.nix
 create mode 100644 tests/modules/services/easyeffects/example-preset.json
 create mode 100644 tests/modules/services/easyeffects/example-preset.nix
 create mode 100644 tests/modules/services/easyeffects/service.nix

diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index a3fb800f0..06a0b0880 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -2140,6 +2140,14 @@ in {
           you can use `lib.mkOrder` to specify the order of the content you want to insert.
         '';
       }
+      {
+        time = "2025-03-19T18:10:56+00:00";
+        condition = config.services.easyeffects.enable;
+        message = ''
+          The Easyeffects module now supports adding json formatted presets
+          under '$XDG_CONFIG_HOME/easyeffects/{input,output}/'.
+        '';
+      }
     ];
   };
 }
diff --git a/modules/services/easyeffects.nix b/modules/services/easyeffects.nix
index b71ec8d83..41adb6504 100644
--- a/modules/services/easyeffects.nix
+++ b/modules/services/easyeffects.nix
@@ -8,6 +8,51 @@ let
 
   presetOpts = optionalString (cfg.preset != "") "--load-preset ${cfg.preset}";
 
+  jsonFormat = pkgs.formats.json { };
+
+  presetType = let baseType = types.attrsOf jsonFormat.type;
+  in baseType // {
+    check = v:
+      baseType.check v && elem (head (attrNames v)) [ "input" "output" ];
+    description = "EasyEffects input or output JSON preset";
+  };
+
+  presetOptionType = mkOption {
+    type = types.nullOr (types.attrsOf presetType);
+    default = { };
+    description = ''
+      List of presets to import to easyeffects.
+      Presets are written to input and output folder in `$XDG_CONFIG_HOME/easyeffects`.
+      Top level block (input/output) determines the folder the file is written to.
+
+      See community presets at:
+      https://github.com/wwmm/easyeffects/wiki/Community-Presets
+    '';
+    example = literalExpression ''
+      {
+        my-preset = {
+          input = {
+            blocklist = [
+
+            ];
+            "plugins_order" = [
+              "rnnoise#0"
+            ];
+            "rnnoise#0" = {
+              bypass = false;
+              "enable-vad" = false;
+              "input-gain" = 0.0;
+              "model-path" = "";
+              "output-gain" = 0.0;
+              release = 20.0;
+              "vad-thres" = 50.0;
+              wet = 0.0;
+            };
+          };
+        };
+      };
+    '';
+  };
 in {
   meta.maintainers = [ maintainers.fufexan ];
 
@@ -35,6 +80,8 @@ in {
         Will likely need to launch easyeffects to initially create preset.
       '';
     };
+
+    extraPresets = presetOptionType;
   };
 
   config = mkIf cfg.enable {
@@ -47,6 +94,13 @@ in {
     # "AT-SPI: Error retrieving accessibility bus address: org.freedesktop.DBus.Error.ServiceUnknown: The name org.a11y.Bus was not provided by any .service files"
     home.packages = with pkgs; [ cfg.package at-spi2-core ];
 
+    xdg.configFile = mkIf (cfg.extraPresets != { }) (lib.mapAttrs' (k: v:
+      # assuming only one of either input or output block is defined, having both in same file not seem to be supported by the application since it separates it by folder
+      let folder = builtins.head (builtins.attrNames v);
+      in lib.nameValuePair "easyeffects/${folder}/${k}.json" {
+        source = jsonFormat.generate "${folder}-${k}.json" v;
+      }) cfg.extraPresets);
+
     systemd.user.services.easyeffects = {
       Unit = {
         Description = "Easyeffects daemon";
diff --git a/tests/default.nix b/tests/default.nix
index 0949936a5..8d35a8aa4 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -487,6 +487,7 @@ in import nmtSrc {
     ./modules/services/darkman
     ./modules/services/devilspie2
     ./modules/services/dropbox
+    ./modules/services/easyeffects
     ./modules/services/emacs
     ./modules/services/espanso
     ./modules/services/flameshot
diff --git a/tests/modules/services/easyeffects/default.nix b/tests/modules/services/easyeffects/default.nix
new file mode 100644
index 000000000..3994344bb
--- /dev/null
+++ b/tests/modules/services/easyeffects/default.nix
@@ -0,0 +1,4 @@
+{
+  easyeffects-service = ./service.nix;
+  easyeffects-example-preset = ./example-preset.nix;
+}
diff --git a/tests/modules/services/easyeffects/example-preset.json b/tests/modules/services/easyeffects/example-preset.json
new file mode 100644
index 000000000..bc21d8486
--- /dev/null
+++ b/tests/modules/services/easyeffects/example-preset.json
@@ -0,0 +1,18 @@
+{
+  "input": {
+    "blocklist": [],
+    "plugins_order": [
+      "rnnoise#0"
+    ],
+    "rnnoise#0": {
+      "bypass": false,
+      "enable-vad": false,
+      "input-gain": 0.0,
+      "model-path": "",
+      "output-gain": 0.0,
+      "release": 20.0,
+      "vad-thres": 50.0,
+      "wet": 0.0
+    }
+  }
+}
diff --git a/tests/modules/services/easyeffects/example-preset.nix b/tests/modules/services/easyeffects/example-preset.nix
new file mode 100644
index 000000000..e6906d8f2
--- /dev/null
+++ b/tests/modules/services/easyeffects/example-preset.nix
@@ -0,0 +1,36 @@
+{ ... }:
+
+{
+  services.easyeffects = {
+    enable = true;
+    extraPresets = {
+      example-preset = {
+        input = {
+          blocklist = [
+
+          ];
+          "plugins_order" = [ "rnnoise#0" ];
+          "rnnoise#0" = {
+            bypass = false;
+            "enable-vad" = false;
+            "input-gain" = 0.0;
+            "model-path" = "";
+            "output-gain" = 0.0;
+            release = 20.0;
+            "vad-thres" = 50.0;
+            wet = 0.0;
+          };
+        };
+      };
+    };
+  };
+
+  test.stubs.easyeffects = { };
+
+  nmt.script = ''
+    assertFileContent \
+      home-files/.config/easyeffects/input/example-preset.json "${
+        ./example-preset.json
+      }"
+  '';
+}
diff --git a/tests/modules/services/easyeffects/service.nix b/tests/modules/services/easyeffects/service.nix
new file mode 100644
index 000000000..86c46374e
--- /dev/null
+++ b/tests/modules/services/easyeffects/service.nix
@@ -0,0 +1,14 @@
+{ ... }:
+
+{
+  services.easyeffects = { enable = true; };
+
+  test.stubs.easyeffects = { };
+
+  nmt.script = ''
+    serviceFile=home-files/.config/systemd/user/easyeffects.service
+
+    assertFileExists $serviceFile
+    assertFileRegex $serviceFile 'ExecStart=.*/bin/easyeffects'
+  '';
+}