Skip to content

NutriMagnus v2026-08-31-2157

Choose a tag to compare

@tom-cloyd tom-cloyd released this 01 Sep 05:15
· 4 commits to main since this release
f418714

CHOOSE HOW OFTEN YOU'RE TOLD ABOUT NEW VERSIONS, AND ALWAYS SEE YOUR CURRENT ONE

Settings now has an "Update Notifications" section where you can set how often the "new version available" banner shows up on the home page: daily (the default), weekly, or monthly. The banner's build note also names that setting directly, with a link to change it. Separately, the home page now always shows a line under the Welcome heading — "Current version date: yyyy-mm-dd:hhmm" — so you can check exactly what you're running, down to the minute, without scrolling to the page footer; whenever a build note is set it follows in parentheses as "(Version note: ...)" on that same line. The build note no longer gets its own standalone box further up the page. See What you see on the home page for the full rundown, including exactly when the update check itself runs.

Scope: web/backend.py (_current_update_notify_frequency(), _should_show_update_notice()
gating index()'s update_available via a saved prefs.json frequency + last-shown-date pair;
new POST /settings/update-notify-frequency route; version_date passed as the full
VERSION stamp). web/templates/settings.html (new "Update Notifications" section).
web/templates/home.html (frequency note added next to NEW VERSION NOTE in the banner;
the old standalone "NEW VERSION NOTE" box removed; the always-visible "Current version
date" line below Welcome now carries the build note in parentheses). tests/test_web.py
(updated accordingly). user-manual.md (new "What you see on the home page" tour, Part 3
Section A). README-numa-documentation.md (matching, fuller technical writeup).

BUILD-NOTE LINE NOW LABELED "NEW VERSION NOTE:", AND ITS BROKEN RENAME FIXED

The plain-language note about your current build now reads "NEW VERSION NOTE: ..." instead of repeating the version number a second time on that line (the number's already in the line above it, or the page-bottom small print). Separately, version.py's note constant was renamed to NEW_VERSION_NOTE; the web app's own import of the old name was fixed to match (it briefly wouldn't start otherwise), and one of the two places that line is rendered had been missed in the wording update, leaving stale text visible in the UPDATE AVAILABLE banner specifically — that's fixed too.

Scope: version.py (VERSION_NOTE renamed to NEW_VERSION_NOTE), web/backend.py
(import and template-context key updated to match), web/templates/home.html
(both the update_available and standalone renderings of the note now read
"NEW VERSION NOTE: ..."). tests/test_web.py (updated to the new name and
an assertion added that was missing on the merged-into-banner case).

FIX: "UPDATE AVAILABLE" BANNER STILL SHOWED RIGHT AFTER A SUCCESSFUL UPDATE

After clicking Update Now, the just-updated confirmation and the "there's an update available" banner could both show at once — confusing, since one says you're done and the other says you're not. The running process doesn't reload its own version number until it's relaunched, so the availability check still (accurately, but unhelpfully) saw the old version and flagged the release you just installed as available. That check is now skipped for the one page load right after a successful update.

Scope: web/backend.py (index() skips the update_check call when the
updated query param is set). tests/test_web.py (1 new assertion).

FIX: "UPDATE NOW" SUCCESS MESSAGE TOLD YOU TO QUIT AN APP WITH NO VISIBLE WINDOW TO QUIT

After a successful in-place update, the message used to say "Quit and reopen NutriMagnus" — but the packaged install has no visible window or taskbar entry to quit from, only the browser tab. It now says "Close this browser tab, then relaunch NutriMagnus," which is both accurate (the background server process only picks up the new binary on relaunch, not just from closing the tab) and matches what a user actually sees on screen.

Scope: web/templates/home.html (UPDATED banner wording), user-manual.md
(matching wording in the Update Now description). tests/test_web.py (1
new assertion).

FIX: THE CURRENT-BUILD VERSION NOTE WAS BURIED IN FINE PRINT AT THE PAGE BOTTOM

The plain-language note describing what changed in your current build (version.py's VERSION_NOTE) used to appear only in small grey text at the very bottom of the home page — easy to miss entirely. It now shows near the top of the page: when there's an update available, it appears as a second line inside that same UPDATE AVAILABLE box, right below the first line; otherwise it gets its own light box in that same spot. The bare version number stays in the small print at the page bottom either way, for reference.

Scope: web/templates/home.html (version_note now renders as a line inside
the update_available alert box when one is shown — not a separate box
below it — falling back to its own alert-secondary box only when there's
no update available, so it's never shown twice; the bare version number
stays in the page-bottom small print, unchanged). tests/test_web.py (2
new tests covering both placements and no duplication).

NEW: ONE-CLICK "UPDATE NOW" BUTTON ON THE UPDATE-AVAILABLE BANNER

If you're running the packaged Linux install, the home page's UPDATE AVAILABLE banner now has an Update Now button — no terminal, no manual download. It fetches the latest release and replaces the running program in place; your data lives elsewhere and is never touched. A message tells you when it's safe to quit and reopen NuMa to start using the new version — the copy you're currently running keeps working until you do. Running from source instead of the packaged install shows the plain "what's new on GitHub" link as before, since there's no packaged binary for the button to replace.

Scope: numa_app/services/self_update.py (new — perform_update() downloads
the latest release's binary/icon from GitHub and os.replace()s the running
PyInstaller-onefile binary in place, atomic on the same filesystem;
is_available() gates this to a packaged Linux install, checking
sys.frozen and sys.platform), web/backend.py (new POST /update-now route,
index() now reads back updated/update_error query params for the
success/failure flash), web/templates/home.html (Update Now button +
confirm() dialog, success/failure banners). tests/test_self_update.py (7
new tests), tests/test_web.py (2 new tests).

NEW: HOME PAGE NOW CHECKS FOR A NEWER RELEASE, AND SHOWS A SHORT NOTE ABOUT WHAT CHANGED IN YOUR CURRENT VERSION

The home page now checks GitHub for a newer NuMa release each time it loads (cached for a few hours so it isn't re-checked on every visit) and shows an UPDATE AVAILABLE banner with a link to what's new when one exists. The version line at the bottom of the home page also now carries a short plain-language note about what changed in that build (e.g. "minor problem fixes"), instead of just the bare timestamp. The check fails silently if you're offline or GitHub is unreachable — it never delays or blocks the home page from loading.

Scope: version.py (new VERSION_NOTE constant, hand-updated alongside
VERSION and the Appendix A entry it summarizes), numa_app/services/
update_check.py (new — check_for_update() against GitHub's latest-release
API, string-compares the "vYYYY-MM-DD-HHMM" tag format scripts/create_
release.py already uses, in-process cached for 6 hours, never raises),
web/backend.py (index() route calls it via run_in_threadpool so a slow/
offline check can't block the event loop), web/templates/home.html (new
banner + version-note display). tests/test_update_check.py (7 new tests),
tests/test_web.py (1 new test), tests/conftest.py (no_update_check autouse
fixture stubs the network call for every other test, same pattern as
no_off/no_cnf).

MANUAL: "USING THE WEB APP" MOVED RIGHT AFTER THE INTRODUCTION, AND A STALE READING-TIME FIGURE FIXED

Part 6 ("Using the Web App") now comes right after Part 2 (the introduction), as the new Part 3 — the practical how-to-operate-NuMa material now reads before the nutrition-concepts and reference parts, instead of after them. Parts 3–6 renumbered accordingly (old 3→4, 4→5, 5→6), and every cross-reference to a part number throughout the manual was updated to match. Separately, the manual's "Reading time" figure had been silently wrong for a while — undercounting by close to 20,000 words — because the script that computes it treated any three backtick characters anywhere in the text as a code-fence marker, so a single sentence in Part 3 that mentioned the triple-backtick JSON fence syntax by name was misread as the start of a code block, and everything up to the next real fence (thousands of words) got wrongly excluded from the count. Reading time is now the corrected ~4 hours 19 minutes, not the ~2 hours 56 minutes shown before.

Scope: user-manual.md (Parts 3-6 reordered/renumbered, all in-text "Part N"
cross-references updated via a mapping pass, one prose line reworded to
drop the raw backtick sequence that broke word counting), scripts/build_
manual.py (count_words()'s fenced-code-block regex now requires the ```
fence to be alone at the start of its own line, per CommonMark, instead of
matching any three backticks anywhere in the raw text).