mnemosyne/scripts/print-digest

211 lines
7.7 KiB
Perl
Executable File

#!/usr/bin/env perl
# print-digest — seeds a temporary in-memory database with sample tasks covering
# all five task classes and every status bucket, then prints the Day at a Glance
# digest to the terminal. No Telegram connection required.
#
# Reference date: 2026-06-04 (Thu) ← pinned so the output is reproducible.
# Pass --date YYYY-MM-DD to use a different date.
#
# Usage:
# perl scripts/print-digest
# perl scripts/print-digest --date 2026-07-01
use strict;
use warnings;
use utf8;
use open ':std', ':encoding(UTF-8)';
use FindBin qw($RealBin);
use lib "$RealBin/../lib";
use DateTime;
use Mnemosyne::DB;
use Mnemosyne::Digest;
# ---- reference date -------------------------------------------------------
my $ref_date_str = '2026-06-04';
while (@ARGV) {
my $arg = shift @ARGV;
if ($arg eq '--date' && @ARGV) { $ref_date_str = shift @ARGV }
}
$ref_date_str =~ /^(\d{4})-(\d{2})-(\d{2})$/ or die "Bad date: $ref_date_str\n";
my $TODAY = DateTime->new(year => $1+0, month => $2+0, day => $3+0);
# ---- in-memory database ---------------------------------------------------
my $db = Mnemosyne::DB->new(':memory:');
my $dbh = $db->dbh;
# Helper: insert a task row, return its new id
sub insert_task {
my (%h) = @_;
$dbh->do(q{
INSERT INTO tasks
(title, notes, class, active,
day_of_month, weekday, ordinal,
interval_n, period_unit, anchor_date,
interval_days, priority, created_at)
VALUES (?,?,?,?, ?,?,?, ?,?,?, ?,?,?)
}, undef,
$h{title}, $h{notes}//'', $h{class}, $h{active}//1,
$h{day_of_month}, $h{weekday}, $h{ordinal},
$h{interval_n}, $h{period_unit},$h{anchor_date},
$h{interval_days},$h{priority}, $h{created_at}//'2026-01-01T00:00:00Z',
);
return $dbh->last_insert_id(undef,undef,'tasks',undef);
}
sub complete { # mark task done on a given date
my ($task_id, $date_str) = @_;
$dbh->do("INSERT INTO completions (task_id, completed_at) VALUES (?,?)",
undef, $task_id, "${date_str}T12:00:00Z");
}
# ===========================================================================
# Seed data — all dates chosen relative to TODAY = 2026-06-04 (Thu)
#
# Jun 2026: Jun 1=Mon, Jun 4=Thu, Jun 6=Sat, Jun 8=Mon, Jun 11=Thu
# May 2026: May 1=Fri, May 7=Thu, May 8=Fri, May 28=Thu
# ===========================================================================
# ── OVERDUE ─────────────────────────────────────────────────────────────────
# monthly_date: fires on the 1st; Jun 1 was 3 days ago, no completion
my $id1 = insert_task(
title => 'Pay credit card',
class => 'monthly_date',
day_of_month => 1,
notes => 'Autopay is off — do it manually',
);
# interval: every 90 days from 2026-01-01 → due 2026-04-01, now 64 days overdue
my $id2 = insert_task(
title => 'Rotate tires',
class => 'interval',
interval_days => 90,
created_at => '2026-01-01T00:00:00Z',
);
# ── DUE TODAY (2026-06-04) ──────────────────────────────────────────────────
# monthly_weekday: 1st Thursday of every month; May's was May 7 (completed), June's is Jun 4
my $id3 = insert_task(
title => 'Weekly review',
class => 'monthly_weekday',
weekday => 4, # 4 = Thursday (DateTime: 1=Mon..7=Sun)
ordinal => 1,
);
complete($id3, '2026-05-07'); # completed last month's occurrence
# interval: every 7 days; last done 2026-05-28 → next due 2026-06-04
my $id4 = insert_task(
title => 'Backup servers',
class => 'interval',
interval_days => 7,
);
complete($id4, '2026-05-28');
# ── UPCOMING ────────────────────────────────────────────────────────────────
# monthly_date: fires on the 8th; May 8 completed → Jun 8 is 4 days out
my $id5 = insert_task(
title => 'Pay rent',
class => 'monthly_date',
day_of_month => 8,
);
complete($id5, '2026-05-08');
# every_n_period: anchor 2026-06-06 (future) → 2 days out; recurs weekly
my $id6 = insert_task(
title => 'Newsletter draft',
class => 'every_n_period',
interval_n => 1,
period_unit => 'week',
anchor_date => '2026-06-06',
);
# every_n_period: anchor 2026-06-11 (future) → 7 days out; recurs weekly
my $id7 = insert_task(
title => 'Team meeting prep',
class => 'every_n_period',
interval_n => 1,
period_unit => 'week',
anchor_date => '2026-06-11',
);
# ── FLOATING ────────────────────────────────────────────────────────────────
# id=8: low priority, created Jun 4 → days_since=0; (0+8)%7=1 → NOT shown (rotation)
# id=9: low priority, created Jun 4 → days_since=0; (0+9)%7=2 → NOT shown
# We want id=7 for a shown low item: (0+7)%7=0 → shown.
# Insert order above gives us id 1-7 already used; next inserts get 8+.
# So: insert a "shown low" task at a created_at where days_since makes it work.
# days_since=6, id=8: (6+8)%7=0 → shown. created_at = Jun 4 - 6 days = May 29.
my $id8 = insert_task(
title => 'Learn Spanish',
class => 'floating',
priority => 'low',
created_at => '2026-05-29T00:00:00Z', # days_since=6; (6+8)%7=0 → shown
);
# medium: created Jun 1 → days_since=3; 3%3=0 → shown
my $id9 = insert_task(
title => 'Call parents',
class => 'floating',
priority => 'medium',
created_at => '2026-06-01T00:00:00Z',
);
# high: always shown
my $id10 = insert_task(
title => 'Plan summer vacation',
class => 'floating',
priority => 'high',
);
# low task that is NOT shown today (demonstrates rotation)
my $id11 = insert_task(
title => 'Read more books',
class => 'floating',
priority => 'low',
created_at => '2026-06-04T00:00:00Z', # days_since=0; (0+11)%7=4 → not shown
);
# inactive task — should never appear
insert_task(
title => 'Old habit tracker',
class => 'floating',
active => 0,
);
# ===========================================================================
# Build and render
# ===========================================================================
my $digest = Mnemosyne::Digest->build($db, $TODAY);
print Mnemosyne::Digest->render_text($digest);
# Also dump a quick summary of what's hidden (for verification)
print "\n[Hidden floating tasks — not shown today by rotation/frequency:\n";
my $all = $db->active_tasks;
my $lc_map = $db->last_completions;
for my $task (grep { $_->{class} eq 'floating' } @$all) {
my $r = Mnemosyne::Schedule->resolve($task, $TODAY);
if ($r->{status} eq 'not_relevant') {
my $id = $task->{id};
my $created = substr($task->{created_at}, 0, 10);
my $days_since = DateTime->compare(
DateTime->new(year=>substr($created,0,4)+0,
month=>substr($created,5,2)+0,
day=>substr($created,8,2)+0),
$TODAY
);
# compute days_since manually
my $cd = DateTime->new(year=>substr($created,0,4)+0,
month=>substr($created,5,2)+0,
day=>substr($created,8,2)+0);
my $ds = int($TODAY->jd - $cd->jd);
print " • $task->{title} (id=$id, priority=$task->{priority}, days_since=$ds, "
. "show_check=" . (($ds + $id) % 7) . " mod 7)\n";
}
}
print "]\n";