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:
@@ -694,6 +694,8 @@ def blancco_reports():
|
||||
this_month=datetime.now(tz).strftime("%Y-%m"),
|
||||
site=config.BLANCCO_SITE,
|
||||
last_month=blancco_evidence.previous_month(),
|
||||
pack_from=blancco_evidence.month_bounds(blancco_evidence.previous_month())[0].date().isoformat(),
|
||||
pack_to=(blancco_evidence.month_bounds(blancco_evidence.previous_month())[1] - timedelta(days=1)).date().isoformat(),
|
||||
todo=blancco_evidence.todo_counts(),
|
||||
)
|
||||
|
||||
@@ -789,7 +791,27 @@ def blancco_cloud_status():
|
||||
|
||||
@app.route("/reports/evidence")
|
||||
def blancco_evidence_pack():
|
||||
"""CMMC evidence pack (ENT-056/158): one ZIP per site and month."""
|
||||
"""CMMC evidence pack (ENT-056/158) for a site. Either ?from=&to= (dates,
|
||||
YYYY-MM-DD, inclusive, Eastern time) or ?month=YYYY-MM (the monthly pack)."""
|
||||
from datetime import date as _date
|
||||
first, last = request.args.get("from"), request.args.get("to")
|
||||
if first or last:
|
||||
try:
|
||||
first, last = _date.fromisoformat(first or ""), _date.fromisoformat(last or "")
|
||||
except ValueError:
|
||||
flash("Pick a start and an end date for the evidence pack.", "danger")
|
||||
return redirect(url_for("blancco_reports"))
|
||||
if last < first:
|
||||
first, last = last, first
|
||||
if (last - first).days > 400:
|
||||
flash("An evidence pack covers at most about a year (400 days).", "danger")
|
||||
return redirect(url_for("blancco_reports"))
|
||||
out = tempfile.SpooledTemporaryFile(max_size=64 * 1024 * 1024)
|
||||
count = blancco_evidence.build_evidence_zip(None, out, first=first, last=last)
|
||||
out.seek(0)
|
||||
audit("REPORT_EVIDENCE", f"{first.isoformat()}..{last.isoformat()} {count} reports")
|
||||
return send_file(out, mimetype="application/zip", as_attachment=True,
|
||||
download_name=blancco_evidence.evidence_range_name(first, last) + ".zip")
|
||||
month = request.args.get("month") or blancco_evidence.previous_month()
|
||||
if not re.fullmatch(r"20\d\d-(0[1-9]|1[0-2])", month):
|
||||
abort(400)
|
||||
@@ -1822,6 +1844,27 @@ def tojson_ordered(value):
|
||||
return json.dumps(value, ensure_ascii=False)
|
||||
|
||||
|
||||
@app.template_filter("short_date")
|
||||
def short_date(value):
|
||||
"""ISO timestamp -> '14 Oct' in the site's time zone; '' if unreadable."""
|
||||
try:
|
||||
dt = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
|
||||
except ValueError:
|
||||
return ""
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=timezone.utc)
|
||||
return dt.astimezone(blancco_evidence._tz()).strftime("%d %b")
|
||||
|
||||
|
||||
@app.template_filter("month_label")
|
||||
def month_label(value):
|
||||
"""'2026-09' -> 'September 2026'; anything else unchanged."""
|
||||
try:
|
||||
return datetime.strptime(str(value), "%Y-%m").strftime("%B %Y")
|
||||
except ValueError:
|
||||
return value
|
||||
|
||||
|
||||
# Report page: why an erasure failed, straight from the report.
|
||||
app.jinja_env.globals["blancco_failure_reason"] = blancco_report.failure_reason
|
||||
|
||||
|
||||
Reference in New Issue
Block a user