Add support for '--test' CLI option
This commit is contained in:
@@ -3,20 +3,21 @@ import { BackendSettings } from "../types/config";
|
||||
import { Notification } from "../types/notification";
|
||||
import { Backend } from "./base";
|
||||
import { TaskPriority } from "../types/task";
|
||||
import { enhancedStringConfig } from "../util/config";
|
||||
|
||||
type Config = {
|
||||
url: string;
|
||||
tokenFile: string;
|
||||
token: string;
|
||||
topic?: string;
|
||||
} & BackendSettings;
|
||||
|
||||
export class NtfySH extends Backend<Config> {
|
||||
public name = "ntfy";
|
||||
|
||||
protected requiredFields = ['url', 'tokenFile'] as const;
|
||||
protected requiredFields = ['url', 'token'] as const;
|
||||
|
||||
protected notify(config: Config, notification: Notification): void {
|
||||
const token = fs.readFileSync(config.tokenFile, 'utf-8');
|
||||
const token = enhancedStringConfig(config.token);
|
||||
|
||||
fetch(`https://${config.url}/${config.topic || 'obsidian'}`, {
|
||||
method: 'POST',
|
||||
|
||||
@@ -2,13 +2,14 @@ import { program } from "commander";
|
||||
import { CLIOptions } from "../types/cli";
|
||||
|
||||
import { loadConfig } from "../config";
|
||||
import { notify, scan } from "../runner";
|
||||
import { notify, scan, test } from "../runner";
|
||||
|
||||
const getOptions = () => program
|
||||
.name("obsidian-tasks-reminder")
|
||||
.version("0.0.1")
|
||||
.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]), [])
|
||||
.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")
|
||||
.parse()
|
||||
@@ -36,12 +37,19 @@ const getOptions = () => program
|
||||
current = current[segment];
|
||||
});
|
||||
}
|
||||
|
||||
if (options.test) {
|
||||
await test(config);
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.scan) {
|
||||
scan(config);
|
||||
await scan(config);
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.notify) {
|
||||
notify(config);
|
||||
await notify(config);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "fs";
|
||||
import { Task } from "../types/task";
|
||||
import { Notification, NotificationDatabase } from "../types/notification";
|
||||
import { jsMapper } from "../util";
|
||||
import { jsMapper } from "../util/code";
|
||||
|
||||
|
||||
/**
|
||||
@@ -16,19 +16,24 @@ export function dumpDatabase(file: string, tasks: Task[], mapper?: string) {
|
||||
* Applies the mapper for each task from list, groups them by time and serializes into JSON format.
|
||||
*/
|
||||
export function serializeDatabase(tasks: Task[], mapper?: string): string {
|
||||
const transformer = mapper
|
||||
? jsMapper<Task, Notification>(mapper, {})
|
||||
: defaultMapper;
|
||||
return JSON.stringify(createDatabase(tasks, mapper));
|
||||
}
|
||||
|
||||
const output = tasks.map(wrapWithTimeFiller(transformer)).reduce((acc, n) => {
|
||||
/**
|
||||
* Applies the mapper for each task from list and groups them by time.
|
||||
*/
|
||||
export function createDatabase(tasks: Task[], mapper?: string): NotificationDatabase {
|
||||
const transformer = mapper
|
||||
? jsMapper<Task, Notification>(mapper, {})
|
||||
: defaultMapper;
|
||||
|
||||
return tasks.map(wrapWithTimeFiller(transformer)).reduce((acc, n) => {
|
||||
if (n.time) {
|
||||
(acc[n.time] = (acc[n.time] || [])).push(n);
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {} as NotificationDatabase);
|
||||
|
||||
return JSON.stringify(output);
|
||||
}
|
||||
|
||||
function wrapWithTimeFiller(mapper: (task: Task) => Notification): (task: Task) => Notification {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { parse } from "../generated/grammar/task";
|
||||
import { Task as DefaultTask } from "../model";
|
||||
import { ParseResult } from "../types/grammar";
|
||||
import { Task, TaskPriority } from "../types/task";
|
||||
import { jsMapper } from "../util";
|
||||
import { jsMapper } from "../util/code";
|
||||
|
||||
/**
|
||||
* Returns all tasks from specified directory and filters them with optional query.
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
import { loadTasks } from "../loader";
|
||||
import { dumpDatabase } from "../database/serializer";
|
||||
import { createDatabase, dumpDatabase } from "../database/serializer";
|
||||
import { loadDatabase } from "../database/deserializer";
|
||||
import { remind } from "../backend";
|
||||
import { Config } from "../types/config";
|
||||
|
||||
export async function test(config: Config) {
|
||||
const tasks = await loadTasks(config.sources, config.query);
|
||||
const db = createDatabase(tasks, config.mapper);
|
||||
|
||||
for (const time of Object.keys(db)) {
|
||||
console.log(time);
|
||||
|
||||
for (const notification of db[time]) {
|
||||
console.log(` - title: ${notification.title}\n text: ${notification.text}\n priority: ${notification.priority}\n tags: ${notification.tags?.join(",")}`)
|
||||
}
|
||||
|
||||
console.log();
|
||||
}
|
||||
}
|
||||
|
||||
export async function scan(config: Config) {
|
||||
const tasks = await loadTasks(config.sources, config.query);
|
||||
dumpDatabase(config.databaseFile, tasks, config.mapper);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type CLIOptions = {
|
||||
config: string;
|
||||
test: boolean;
|
||||
scan: boolean;
|
||||
notify: boolean;
|
||||
set: string[];
|
||||
|
||||
17
src/util/config.ts
Normal file
17
src/util/config.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
const specialOptions: Record<string, (text: string) => string> = {
|
||||
$__file: (arg: string) => readFileSync(arg, 'utf8').trim()
|
||||
};
|
||||
|
||||
export const enhancedStringConfig = (value: string) => {
|
||||
const trimmed = value.trim();
|
||||
|
||||
for(const opt of Object.keys(specialOptions)) {
|
||||
if(trimmed.startsWith(`${opt}:`) && opt in specialOptions) {
|
||||
return specialOptions[opt](trimmed.slice(opt.length + 1).trim());
|
||||
}
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
};
|
||||
Reference in New Issue
Block a user