import { DateTime, parseDate } from "./deps.ts"; import { flags } from "./deps.ts"; import { loadConfig } from "./config.ts"; import { Entry, filterEntries, loadEntries, makeEntry, printEntry, saveEntries, } from "./mod.ts"; function tryDate(d?: string): DateTime | undefined { return d ? DateTime.fromJSDate(parseDate(d)) : undefined; } function readEntries(entries: Entry[], opts: flags.Args) { let from = tryDate(opts.from); let to = tryDate(opts.to); if (opts.on) { const on = tryDate(opts.on); if (typeof on !== "object") { throw new Error("Bad date"); } [from, to] = [on.startOf("day"), on.endOf("day")]; } const tags = opts._.filter((arg) => typeof arg === "string" && arg.match(/^@./) ) as string[]; const limit = opts.limit; const filtered = filterEntries( entries, { from, to, limit, tags, }, ); let first = true; for (const entry of filtered) { if (!first && !opts.summary) { console.log(); } first = false; printEntry(entry, opts.summary); } } async function edit(body: string, editor: string[]) { const temp = Deno.makeTempFileSync({ suffix: ".hayom" }); try { Deno.writeTextFileSync(temp, body); const proc = Deno.run({ cmd: [...editor, temp] }); const status = await proc.status(); if (status.success) { return Deno.readTextFileSync(temp); } } finally { Deno.remove(temp); } } function printHelp() { console.log(` usage: hayom [-j journal] ... options: --summary | -s: print summary line only --from | -f: from timestamp --to | -t: to timestamp --on: on timestamp --count | -n: number of entries to print --journal | -j: journal to use `); } async function main() { const args = [...Deno.args]; const config = loadConfig(); const opts = flags.parse(args, { boolean: ["summary"], alias: { "s": ["summary"], "f": ["from"], "t": ["to"], "n": ["count"], "j": ["journal"], }, }); if (opts.help) { printHelp(); return; } const journal = opts.journal ?? config.default; const path = config.journals[journal].journal; try { Deno.lstatSync(path); } catch (e) { if (e instanceof Deno.errors.NotFound) { Deno.createSync(path).close(); } else throw e; } const entries = loadEntries(path); if ( ["from", "f", "to", "t", "on", "count", "n"].some((arg) => arg in opts) || (opts._.length > 0 && opts._.every((e) => typeof e === "string" && e[0] === "@")) ) { readEntries(entries, opts); } else { const rawEntry = opts._.length > 0 ? opts._.join(" ") : await edit("", config.editor.split(/\s/)); if (rawEntry && rawEntry.trim() !== "") { const entry = makeEntry(rawEntry); entries.push(entry); saveEntries(path, entries); } } } if (import.meta.main) { main(); }