Commit f37b10bddeb0

Vincent Demeester <vincent@sbr.pm>
2025-12-18 11:10:34
refactor(modules): Standardize structure and scheduling API
- Establish consistent folder-based organization for all modules - Simplify timer configuration with unified schedule option - Improve maintainability by following rsync-replica pattern Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 6ff8871
Changed files (9)
modules
audible-sync
gosmee
govanityurl
jellyfin-auto-collections
music-playlist-dl
wireguard
systems
modules/audible-sync.nix → modules/audible-sync/default.nix
@@ -9,6 +9,20 @@ with lib;
 
 let
   cfg = config.services.audible-sync;
+
+  # Convert schedule shortcuts to systemd OnCalendar format
+  scheduleToCalendar =
+    schedule:
+    if schedule == "hourly" then
+      "hourly"
+    else if schedule == "daily" then
+      "daily"
+    else if schedule == "weekly" then
+      "weekly"
+    else if schedule == "monthly" then
+      "monthly"
+    else
+      schedule;
 in
 {
   options.services.audible-sync = {
@@ -52,22 +66,14 @@ in
       description = "Output format for converted audiobooks";
     };
 
-    interval = mkOption {
-      type = types.enum [
-        "hourly"
-        "daily"
-        "weekly"
-        "monthly"
-      ];
+    schedule = mkOption {
+      type = types.str;
       default = "daily";
-      description = "How often to run the sync";
-    };
-
-    onCalendar = mkOption {
-      type = types.nullOr types.str;
-      default = null;
-      description = "Custom OnCalendar specification for systemd timer (overrides interval)";
-      example = "*-*-* 04:00:00";
+      description = ''
+        When to run the sync. Can be "hourly", "daily", "weekly", "monthly", or a systemd OnCalendar format.
+        See systemd.time(7) for OnCalendar format details.
+      '';
+      example = "daily";
     };
 
     notification = {
@@ -97,19 +103,7 @@ in
     systemd.timers.audible-sync = {
       wantedBy = [ "timers.target" ];
       timerConfig = {
-        OnCalendar =
-          if cfg.onCalendar != null then
-            cfg.onCalendar
-          else
-            (
-              {
-                hourly = "*-*-* *:00:00";
-                daily = "*-*-* 03:00:00";
-                weekly = "Sun *-*-* 03:00:00";
-                monthly = "*-*-01 03:00:00";
-              }
-              .${cfg.interval}
-            );
+        OnCalendar = scheduleToCalendar cfg.schedule;
         Persistent = true;
         RandomizedDelaySec = "10m";
       };
modules/gosmee.nix → modules/gosmee/default.nix
File renamed without changes
modules/govanityurl.nix → modules/govanityurl/default.nix
File renamed without changes
modules/jellyfin-auto-collections.nix → modules/jellyfin-auto-collections/default.nix
@@ -10,6 +10,20 @@ with lib;
 let
   cfg = config.services.jellyfin-auto-collections;
 
+  # Convert schedule shortcuts to systemd OnCalendar format
+  scheduleToCalendar =
+    schedule:
+    if schedule == "hourly" then
+      "hourly"
+    else if schedule == "daily" then
+      "daily"
+    else if schedule == "weekly" then
+      "weekly"
+    else if schedule == "monthly" then
+      "monthly"
+    else
+      schedule;
+
   # Generate complete YAML config
   # We'll use a template and substitute secrets at runtime
   configYaml = lib.generators.toYAML { } (
@@ -71,22 +85,14 @@ in
       description = "The jellyfin-auto-collections package to use.";
     };
 
-    interval = mkOption {
-      type = types.enum [
-        "hourly"
-        "daily"
-        "weekly"
-        "monthly"
-      ];
+    schedule = mkOption {
+      type = types.str;
       default = "daily";
-      description = "How often to run the collection update";
-    };
-
-    onCalendar = mkOption {
-      type = types.nullOr types.str;
-      default = null;
-      description = "Custom OnCalendar specification for systemd timer (overrides interval)";
-      example = "*-*-* 04:00:00";
+      description = ''
+        When to run the collection update. Can be "hourly", "daily", "weekly", "monthly", or a systemd OnCalendar format.
+        See systemd.time(7) for OnCalendar format details.
+      '';
+      example = "daily";
     };
 
     jellyfinUrl = mkOption {
@@ -234,19 +240,7 @@ in
       wantedBy = [ "timers.target" ];
 
       timerConfig = {
-        OnCalendar =
-          if cfg.onCalendar != null then
-            cfg.onCalendar
-          else
-            (
-              {
-                hourly = "*-*-* *:00:00";
-                daily = "*-*-* 00:00:00";
-                weekly = "Sun *-*-* 00:00:00";
-                monthly = "*-*-01 00:00:00";
-              }
-              .${cfg.interval}
-            );
+        OnCalendar = scheduleToCalendar cfg.schedule;
         Persistent = true;
         RandomizedDelaySec = "5m";
       };
modules/music-playlist-dl.nix → modules/music-playlist-dl/default.nix
@@ -9,6 +9,20 @@ with lib;
 
 let
   cfg = config.services.music-playlist-dl;
+
+  # Convert schedule shortcuts to systemd OnCalendar format
+  scheduleToCalendar =
+    schedule:
+    if schedule == "hourly" then
+      "hourly"
+    else if schedule == "daily" then
+      "daily"
+    else if schedule == "weekly" then
+      "weekly"
+    else if schedule == "monthly" then
+      "monthly"
+    else
+      schedule;
 in
 {
   options.services.music-playlist-dl = {
@@ -38,22 +52,14 @@ in
       description = "Base directory for downloads (library and playlists subdirectories)";
     };
 
-    interval = mkOption {
-      type = types.enum [
-        "hourly"
-        "daily"
-        "weekly"
-        "monthly"
-      ];
+    schedule = mkOption {
+      type = types.str;
       default = "weekly";
-      description = "How often to run the downloader";
-    };
-
-    onCalendar = mkOption {
-      type = types.nullOr types.str;
-      default = null;
-      description = "Custom OnCalendar specification for systemd timer (overrides interval)";
-      example = "Sun *-*-* 02:00:00";
+      description = ''
+        When to run the downloader. Can be "hourly", "daily", "weekly", "monthly", or a systemd OnCalendar format.
+        See systemd.time(7) for OnCalendar format details.
+      '';
+      example = "weekly";
     };
 
     notification = {
@@ -84,19 +90,7 @@ in
     systemd.timers.music-playlist-dl = {
       wantedBy = [ "timers.target" ];
       timerConfig = {
-        OnCalendar =
-          if cfg.onCalendar != null then
-            cfg.onCalendar
-          else
-            (
-              {
-                hourly = "*-*-* *:00:00";
-                daily = "*-*-* 02:00:00";
-                weekly = "Sun *-*-* 02:00:00";
-                monthly = "*-*-01 02:00:00";
-              }
-              .${cfg.interval}
-            );
+        OnCalendar = scheduleToCalendar cfg.schedule;
         Persistent = true;
         RandomizedDelaySec = "15m";
       };
modules/wireguard-client.nix → modules/wireguard/client.nix
File renamed without changes
modules/wireguard-server.nix → modules/wireguard/server.nix
File renamed without changes
systems/rhea/extra.nix
@@ -51,9 +51,9 @@ in
   imports = [
     ../common/services/samba.nix
     ../common/services/homepage.nix
-    ../../modules/audible-sync.nix
-    ../../modules/jellyfin-auto-collections.nix
-    ../../modules/music-playlist-dl.nix
+    ../../modules/audible-sync
+    ../../modules/jellyfin-auto-collections
+    ../../modules/music-playlist-dl
   ];
 
   # Age secrets: gandi.env + generated exportarr secrets
@@ -434,7 +434,7 @@ in
       tempDir = "/neo/audiobooks/zz_import"; # Keep AAX files for reuse
       quality = "best";
       format = "m4b";
-      interval = "daily"; # Run daily at 3 AM
+      schedule = "daily"; # Run daily at 3 AM
       notification = {
         enable = true;
         ntfyUrl = "https://ntfy.sbr.pm";
@@ -446,7 +446,7 @@ in
       jellyfinUrl = "http://localhost:8096";
       userId = "400fef4e0ab2448cb8a2bc8ca2facc4f";
       apiKeyFile = config.age.secrets."jellyfin-auto-collections-api-key".path;
-      interval = "daily"; # Run daily at midnight
+      schedule = "daily"; # Run daily at midnight
 
       jellyseerr = {
         enable = false; # Enable when password secret is created
@@ -542,7 +542,7 @@ in
       user = "vincent";
       configFile = "/neo/music/music-playlist-dl.yaml";
       baseDir = "/neo/music";
-      interval = "weekly"; # Run weekly on Sundays at 2 AM
+      schedule = "weekly"; # Run weekly on Sundays at 2 AM
       notification = {
         enable = true;
         ntfyUrl = "https://ntfy.sbr.pm";
flake.nix
@@ -134,10 +134,10 @@
 
       nixosModules = {
         # provided modules (to be upstreamed)
-        wireguard-client = ./modules/wireguard-client.nix;
-        wireguard-server = ./modules/wireguard-server.nix;
-        govanityurl = ./modules/govanityurl.nix;
-        gosmee = ./modules/gosmee.nix;
+        wireguard-client = ./modules/wireguard/client.nix;
+        wireguard-server = ./modules/wireguard/server.nix;
+        govanityurl = ./modules/govanityurl;
+        gosmee = ./modules/gosmee;
         rsync-replica = ./modules/rsync-replica;
       };