homemanager module

This commit is contained in:
Robin Appelman 2025-10-13 20:10:18 +02:00
commit 0e572744bf
5 changed files with 108 additions and 5 deletions

View file

@ -1,6 +1,6 @@
# Galton
*Let your downloads fall into the right place*
_Let your downloads fall into the right place_
Galton sorts your new downloads based on a set of rules.

View file

@ -24,5 +24,19 @@
packages = {
galton = pkgs: pkgs.galton;
};
homeModules = {
default = {
pkgs,
config,
lib,
...
}: {
imports = [./nix/hm-module.nix];
config = lib.mkIf config.services.galton.enable {
services.galton.package = lib.mkDefault pkgs.galton;
};
};
};
};
}

88
nix/hm-module.nix Normal file
View file

@ -0,0 +1,88 @@
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.services.galton;
format = pkgs.formats.toml {};
removeNulls = filterAttrs (_: val: val != null);
configFile = format.generate "galton.toml" {
watch = removeNulls {inherit (cfg) symlink;};
rule = map removeNulls cfg.rules;
};
in {
options.services.galton = {
enable = mkEnableOption "galton";
directory = mkOption {
type = types.str;
example = "~/Downloads";
description = "Directory to watch for new files";
};
symlink = mkOption {
type = types.nullOr types.str;
default = null;
description = "Create a symlink to matched files";
};
rules = mkOption {
default = [];
type = types.listOf (types.submodule {
options = {
name = mkOption {
type = types.nullOr types.str;
default = null;
};
url = mkOption {
type = types.nullOr types.str;
default = null;
};
referrer = mkOption {
type = types.nullOr types.str;
default = null;
};
move = mkOption {
type = types.nullOr types.str;
default = null;
};
rename = mkOption {
type = types.nullOr types.str;
default = null;
};
};
});
};
logLevel = mkOption {
type = types.str;
default = "info";
};
package = mkOption {
type = types.package;
defaultText = literalExpression "pkgs.galton";
description = "package to use";
};
};
config = mkIf cfg.enable {
systemd.user.services.galton = {
Unit = {
Description = "Galton directory watcher";
};
Service = {
Environment = "RUST_LOG=${cfg.logLevel}";
ExecStart = "${getExe cfg.package} --config ${configFile} watch ${cfg.directory}";
Restart = "on-failure";
RestartSec = 10;
};
Install = {
WantedBy = ["default.target"];
};
};
};
}

View file

@ -39,7 +39,7 @@ impl WatchConfig {
}
}
fn normalize_path<P: Into<String> + AsRef<str>>(path: P) -> String {
pub fn normalize_path<P: Into<String> + AsRef<str>>(path: P) -> String {
if let Some(suffix) = path.as_ref().strip_prefix("~/") {
let home = home_dir().unwrap_or_default();
home.join(suffix)

View file

@ -1,4 +1,4 @@
use crate::config::GaltonConfig;
use crate::config::{normalize_path, GaltonConfig};
use crate::file::FileInfo;
use crate::rule::{Rule, RuleMatch};
use clap::builder::styling::{AnsiColor, Effects};
@ -44,12 +44,12 @@ enum Commands {
/// Apply rules on a single file
File {
/// Path to apply rules on
path: PathBuf,
path: String,
},
/// Watch for new files and apply rules on them
Watch {
/// Directory to watch for new files
path: PathBuf,
path: String,
#[arg(long)]
recursive: bool,
},
@ -66,6 +66,7 @@ fn main() -> MainResult {
handle_file(&file, &config.rule);
}
Commands::Watch { path, recursive } => {
let path = normalize_path(path);
let rules = config.rule;
let symlink = config.watch.symlink();
let (tx, rx) = channel();