Webapp: evidence pack date range, US month labels, hardware gap rows

Evidence pack takes ?from=&to= (inclusive, Eastern time) with From/To
pickers and quick ranges; ZIP is named ENT-056_<site>_<from>_to_<to>.
Month keys show as 'September 2026'. Hardware gap rows on the to-do
use the shared one-line grid with chips for the missing pack or BIOS.
This commit is contained in:
cproudlock
2026-10-14 15:08:36 -04:00
parent a54df7ebd9
commit 2dbaaded44
4 changed files with 116 additions and 15 deletions

View File

@@ -182,16 +182,47 @@ def evidence_name(month: str, site: str | None = None) -> str:
return f"ENT-056_{site_slug(site)}_{month}"
def build_evidence_zip(month: str, fileobj) -> int:
"""Write the evidence pack for `month` into fileobj; return report count."""
start, end = month_bounds(month)
def evidence_range_name(first, last, site: str | None = None) -> str:
"""File names stay year-first so they sort; the pages show US dates."""
return f"ENT-056_{site_slug(site)}_{first.isoformat()}_to_{last.isoformat()}"
def day_bounds(first, last):
"""date, date -> start of `first` and of the day after `last`, in the
site's display timezone (America/New_York): a whole-day range."""
from datetime import timedelta
start = datetime(first.year, first.month, first.day, tzinfo=_tz())
nxt = last + timedelta(days=1)
return start, datetime(nxt.year, nxt.month, nxt.day, tzinfo=_tz())
def us_date(d) -> str:
"""10/14/2026: the date format the site reads."""
return f"{d.month:02d}/{d.day:02d}/{d.year:04d}"
def range_label(first, last) -> str:
return f"{us_date(first)} to {us_date(last)}"
def build_evidence_zip(month, fileobj, first=None, last=None) -> int:
"""Write an evidence pack into fileobj; return the report count. Either a
calendar month ('2026-09', the monthly pack) or a day range first..last
(dates, inclusive, Eastern time)."""
if first and last:
start, end = day_bounds(first, last)
stem = evidence_range_name(first, last)
period = range_label(first, last)
else:
start, end = month_bounds(month)
stem = evidence_name(month)
period = month
reports = collect(start, end)
state = load_state()
stem = evidence_name(month)
with zipfile.ZipFile(fileobj, "w", zipfile.ZIP_DEFLATED) as zf:
zf.writestr(f"{stem}/summary.csv", summary_csv(reports, state))
zf.writestr(f"{stem}/README.txt", (
f"Blancco erasure evidence, {config.BLANCCO_SITE}, {month} ({config.DISPLAY_TZ})\n"
f"Blancco erasure evidence, {config.BLANCCO_SITE}, {period} ({config.DISPLAY_TZ})\n"
f"{len(reports)} report(s). summary.csv has one row per erased drive,\n"
"with failure_reason for failed wipes and cloud_upload as recorded by\n"
"the PXE server. Certificates of record are in the Blancco Management\n"