Implement built-in cron worker
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -146,3 +146,6 @@ dist
|
||||
# End of https://www.toptal.com/developers/gitignore/api/node
|
||||
|
||||
src/generated
|
||||
*.yaml
|
||||
*.json
|
||||
.direnv
|
||||
|
||||
48
module.nix
48
module.nix
@@ -28,13 +28,6 @@ in
|
||||
default = "root";
|
||||
};
|
||||
|
||||
scanTimer = mkOption {
|
||||
type = types.str;
|
||||
description = "The systemd's timer interval when the app will be performing the scan for new tasks";
|
||||
example = "*-*-* *:00";
|
||||
default = "*-*-* *:10";
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
type = types.attrs;
|
||||
description = "The obsidian-tasks-reminder config which will be eventually converted to yaml";
|
||||
@@ -56,46 +49,17 @@ in
|
||||
config = mkIf cfg.enable {
|
||||
environment.systemPackages = [app];
|
||||
|
||||
systemd.timers.obsidian-tasks-reminder-scanner = {
|
||||
description = "Scan for new Obsidian tasks";
|
||||
wantedBy = ["timers.target"];
|
||||
|
||||
timerConfig = {
|
||||
OnCalendar = cfg.scanTimer;
|
||||
Unit = "obsidian-tasks-reminder-scanner.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers.obsidian-tasks-reminder = {
|
||||
description = "Notify about Obsidian tasks";
|
||||
wantedBy = ["timers.target"];
|
||||
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* *:*:00";
|
||||
Unit = "obsidian-tasks-reminder.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.obsidian-tasks-reminder-scanner = {
|
||||
description = "Scan for new Obsidian tasks";
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = cfg.user;
|
||||
};
|
||||
|
||||
script = "${app}/bin/obsidian-tasks-reminder -s";
|
||||
};
|
||||
|
||||
systemd.services.obsidian-tasks-reminder = {
|
||||
description = "Notify about Obsidian tasks";
|
||||
enable = true;
|
||||
description = "Obsidian Tasks Notifier";
|
||||
|
||||
wantedBy = ["network-online.target"];
|
||||
after = ["network-online.target"];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${app}/bin/obsidian-tasks-reminder";
|
||||
User = cfg.user;
|
||||
};
|
||||
|
||||
script = "${app}/bin/obsidian-tasks-reminder -n";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
29
package-lock.json
generated
29
package-lock.json
generated
@@ -10,6 +10,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"commander": "^13.0.0",
|
||||
"cron": "^4.3.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"peggy": "^4.2.0",
|
||||
"yaml": "^2.7.0"
|
||||
@@ -482,6 +483,12 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/luxon": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.6.2.tgz",
|
||||
"integrity": "sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.6.tgz",
|
||||
@@ -576,6 +583,19 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/cron": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cron/-/cron-4.3.1.tgz",
|
||||
"integrity": "sha512-7x7DoEOxV11t3OPWWMjj1xrL1PGkTV5RV+/54IJTZD7gStiaMploY43EkeBSkDZTLRbUwk+OISbQ0TR133oXyA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/luxon": "~3.6.0",
|
||||
"luxon": "~3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.x"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.13",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
|
||||
@@ -793,6 +813,15 @@
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/luxon": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz",
|
||||
"integrity": "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": "^13.0.0",
|
||||
"cron": "^4.3.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"peggy": "^4.2.0",
|
||||
"yaml": "^2.7.0"
|
||||
|
||||
@@ -7,5 +7,5 @@ buildNpmPackage {
|
||||
pname = "obsidian-tasks-reminder";
|
||||
version = "0.0.1";
|
||||
src = ./.;
|
||||
npmDepsHash = "sha256-ofPAFnHbW+M0uQN/OXDLK+PQ3ls6AtD58/AOmSxn754=";
|
||||
npmDepsHash = "sha256-K06A/j2GfM0nCiFv4Pho907VWLa2pPHjtV9BgKxwdnE=";
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { CLIOptions } from "../types/cli";
|
||||
|
||||
import { loadConfig } from "../config";
|
||||
import { notify, scan, test } from "../runner";
|
||||
import { CronJob } from "cron";
|
||||
|
||||
const getOptions = () => program
|
||||
.name("obsidian-tasks-reminder")
|
||||
@@ -10,9 +11,7 @@ const getOptions = () => program
|
||||
.requiredOption("-c, --config <file>", "sets the path to the YAML file with configuration")
|
||||
.option("-x, --set <arg>", "overrides the config option for this specific run (arg: <key>=<name>, i.e. backend.ntfy.enable=false", (v: string, prev: string[]) => prev.concat([v]), [])
|
||||
.option("-t, --test", "evaluates the query, applies the mapper and prints to stdout the notifications about to be trigger, without actual triggering them")
|
||||
.option("-s, --scan", "scans new tasks for future notifications and generates the database")
|
||||
.option("-n, --notify", "reads the generated database and triggers notifications if any")
|
||||
.option("-p, --profile <name>", "limits the current operation only to specified profile. If missing, all profiles will be affected")
|
||||
.option("-p, --profile <name>", "(applicable only with '--test' option) limits the current operation only to specified profile. If missing, all profiles will be affected")
|
||||
.parse()
|
||||
.opts<CLIOptions>();
|
||||
|
||||
@@ -44,13 +43,15 @@ const getOptions = () => program
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.scan) {
|
||||
await scan(config, options.profile);
|
||||
return;
|
||||
}
|
||||
const scanJob = CronJob.from({
|
||||
cronTime: config.scanCron ?? '0 0 * * * *',
|
||||
onTick () { scan(config) },
|
||||
start: true,
|
||||
});
|
||||
|
||||
if (options.notify) {
|
||||
await notify(config, options.profile);
|
||||
return;
|
||||
}
|
||||
const notifyJob = CronJob.from({
|
||||
cronTime: config.notifyCron ?? '0 * * * * *',
|
||||
onTick() { notify(config) },
|
||||
start: true,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,7 +2,5 @@ export type CLIOptions = {
|
||||
config: string;
|
||||
profile?: string;
|
||||
test: boolean;
|
||||
scan: boolean;
|
||||
notify: boolean;
|
||||
set: string[];
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
export type Config = {
|
||||
profiles: Record<string, ProfileConfig>;
|
||||
notifyCron?: string;
|
||||
scanCron?: string;
|
||||
};
|
||||
|
||||
export type ProfileConfig = {
|
||||
|
||||
Reference in New Issue
Block a user