{ pkgs, lib, config, ... }: let cfg = config.frogeye.nextcloud; in { config = { systemd.user = lib.mkIf (builtins.length cfg > 0) { services.nextcloud_sync = { Service = { Type = "oneshot"; ExecStart = lib.getExe ( pkgs.writeShellApplication { name = "nextcloud_sync"; runtimeInputs = with pkgs; [ nextcloud-client ]; text = '' sync() { url="$1" remote="$2" local="$3" echo "Syncing $url $remote to $local" # Adding to Syncthing ignores (so it's not double-synced) dir="$local" while [ "$dir" != "/" ] do if [ -d "$dir/.stfolder" ] then if [ ! -f "$dir/.stignore" ] then touch "$dir/.stignore" fi rule="''${local#"$dir/"}/**" if ! grep -qFx "$rule" "$dir/.stignore" then echo "$rule" >> "$dir/.stignore" fi fi dir="$(dirname "$dir")" done # Actual syncing mkdir -p "$local" nextcloudcmd -n -h --path "$remote" "$local" "$url" } '' + (lib.trivial.pipe cfg [ (builtins.map (n: '' sync ${ lib.strings.escapeShellArgs [ n.url n.remote "${config.home.homeDirectory}/${n.local}" ] } '')) lib.strings.concatLines ]); } ); }; }; timers.nextcloud_sync = { Timer = { OnCalendar = "*:1/5"; }; Install = { WantedBy = [ "timers.target" ]; }; }; }; }; options = { frogeye.nextcloud = lib.mkOption { default = [ ]; description = "Sync Nextcloud folders. Uses netrc for authentication"; type = lib.types.listOf ( lib.types.submodule ( { config, ... }: { options = { url = lib.mkOption { type = lib.types.str; description = "URL of the Nextcloud instance"; }; local = lib.mkOption { type = lib.types.str; description = "Local path (relative to home) to sync"; }; remote = lib.mkOption { type = lib.types.str; description = "Remote path to sync"; default = "/"; }; }; } ) ); }; }; }