211 lines
7.7 KiB
Perl
Executable File
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";
|