Files
meshcore-bot/modules/web_viewer
Adam Gessaman abd39acfa3 feat(scheduler): add positional day-of-month and date bounds
Standard 5-field cron cannot express "the 4th Tuesday" or "the last
Friday" — patterns recurring nets need — so operators were hand-rolling
day-of-month lists that drift across months of different lengths.

APScheduler's day field already understands these ("last fri", "4th
tue"); the only obstacle is the space, which collides with crontab's
field separator. Accept "-" or "_" in its place and restore it before
handing the field over:

    0 19 last-fri * *          last Friday of the month
    0 19 4th-tue * *           fourth Tuesday
    0 19 1st-tue,3rd-tue * *   first and third Tuesday

Neither separator is ambiguous — crontab range endpoints are digits, so
"last-fri" cannot read as a range. Positional expressions are valid only
in day-of-month; "0 19 * * last-fri" is rejected.

Also adds optional start=/end= date bounds, which limit a schedule to a
date range. They live on the option value rather than the key, ahead of
the channel and keyed with "=", so they never collide with the ":"
separating channel from message, and a body mentioning "start=" is not
misread as a bound. Either may be omitted, order does not matter, and
the end date is inclusive of that whole day. A schedule with no runs
left is skipped at startup with a log line saying why.

The web viewer gains start/end pickers, shows a bounded entry's window
and marks an exhausted one Finished. Bounds round-trip through the edit
cycle, so editing an entry cannot silently drop them.

Expressions without a positional escape are passed to APScheduler
untouched: a 6000-expression sweep over valid crontab forms shows no
behavioural change.
2026-08-29 13:34:05 -07:00
..