mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-21 18:47:13 +02:00
feat(diagnostic, archives): install step 4 — proactive check + reactive banner
Two complementary surfaces for the most-missed install step ("Store sent
files on external storage"):
1. Connection diagnostic check (printer-side variant)
- Reads state.store_to_sdcard, parsed from MQTT home_flag bit 11.
- Pass / fail / skip; instant, no I/O.
- Catches the newer-firmware variant where the toggle moved onto the
printer itself (P2S 01.02 / Studio 2.6+).
An FTP upload-and-verify probe was tried first and rejected. /cache
is always writable from Bambuddy regardless of the slicer setting;
only BambuStudio's own behaviour changes when the toggle flips.
Empirically confirmed against X1C + H2D with the slicer option
toggled off: probe still succeeded, home_flag bit 11 stayed True.
2. Archives-page banner (slicer-side variant)
- The slicer-side toggle is invisible to the printer — older
BambuStudio doesn't push the change to the printer. The diagnostic
can't see it.
- Symptom is deterministic: archiver creates rows with
extra_data.no_3mf_available=True (main.py:2770) when it can't pull
the 3MF from /cache after a slicer-initiated print.
- New endpoint GET /archives/no-3mf-warning returns whether any
archive in the last 30 days has the flag (excluding soft-deleted).
- Amber dismissible banner at the top of /archives; one-shot
localStorage dismissal (matches Layout.tsx update-banner pattern,
but persistent across sessions).
- React-Query disabled after dismissal so the endpoint isn't polled
once the user has been told.
This commit is contained in:
@@ -427,6 +427,39 @@ async def list_archives(
|
||||
return result
|
||||
|
||||
|
||||
@router.get("/no-3mf-warning")
|
||||
async def no_3mf_warning(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_: User | None = RequirePermissionIfAuthEnabled(Permission.ARCHIVES_READ),
|
||||
):
|
||||
"""Whether to nudge the user about install step 4 ("Store sent files on
|
||||
external storage"). True iff any archive in the last 30 days was created
|
||||
via the no-3MF fallback path — that's the deterministic symptom of the
|
||||
slicer-side variant of the setting being off.
|
||||
|
||||
Complements the connection-diagnostic ``external_storage`` check, which
|
||||
only catches the printer-side variant of the setting. On older slicers
|
||||
where the toggle lives only in BambuStudio, the printer never reports it
|
||||
and the diagnostic passes — this endpoint surfaces the symptom instead.
|
||||
|
||||
Dismissal is handled client-side via localStorage (one-shot): once the
|
||||
user has been told, no further nudge until they clear browser storage.
|
||||
The backend stays stateless.
|
||||
"""
|
||||
cutoff = datetime.now(timezone.utc) - timedelta(days=30)
|
||||
result = await db.execute(
|
||||
select(PrintArchive.extra_data).where(
|
||||
PrintArchive.created_at >= cutoff,
|
||||
PrintArchive.deleted_at.is_(None),
|
||||
PrintArchive.extra_data.isnot(None),
|
||||
)
|
||||
)
|
||||
for (extra_data,) in result.all():
|
||||
if extra_data and extra_data.get("no_3mf_available"):
|
||||
return {"has_fallback": True}
|
||||
return {"has_fallback": False}
|
||||
|
||||
|
||||
@router.get("/slim", response_model=list[ArchiveSlim])
|
||||
async def list_archives_slim(
|
||||
date_from: date | None = Query(None),
|
||||
|
||||
Reference in New Issue
Block a user