"""HTML export for quick local review of human reports."""
from __future__ import annotations
from pathlib import Path
from typing import Sequence
from .models import PlatformHumanReport, ReportBundle
from .quality import PlatformQualityReport
def esc(value: object) -> str:
return (
str(value)
.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace('"', """)
)
def html_shell(title: str, body: str) -> str:
return f"""
{esc(title)}
{body}
"""
def report_card(report: PlatformHumanReport, quality: PlatformQualityReport | None) -> str:
quality_text = ""
if quality is not None:
status_class = "ok" if quality.human_ready else "blocker" if quality.blocker_count else "warn"
quality_text = (
f'technical_ready={quality.technical_ready}; '
f"human_ready={quality.human_ready}; blockers={quality.blocker_count}; warnings={quality.warning_count}
"
)
gaps = "".join(f"{esc(gap)}" for gap in report.missing_for_humans[:4])
return (
''
f"{esc(report.platform.title)}
"
f'{report.average_score}
'
f"{esc(report.summary)}
"
+ quality_text
+ ""
""
)
def index_html(reports: Sequence[PlatformHumanReport], qualities: Sequence[PlatformQualityReport], bundle: ReportBundle | None = None) -> str:
quality_by_platform = {quality.platform_id: quality for quality in qualities}
cards = "".join(report_card(report, quality_by_platform.get(report.platform.platform_id)) for report in reports)
rows = []
for report in sorted(reports, key=lambda item: item.platform.platform_id):
quality = quality_by_platform.get(report.platform.platform_id)
rows.append(
""
f"| {esc(report.platform.platform_id)} | "
f"{report.average_score} | "
f"{report.scan.code_lines} | "
f"{len(report.scan.evidence)} | "
f"{esc(quality.human_ready if quality else 'n/a')} | "
f"{esc('; '.join(report.scan.warnings[:3]))} | "
"
"
)
intro = ""
if bundle is not None:
intro = (
f"Gerados {len(bundle.generated_files)} arquivos, "
f"{bundle.matrix_cells} celulas de matriz e "
f"{bundle.total_code_lines_analyzed} linhas de codigo analisadas.
"
)
body = (
intro
+ '"
+ "Resumo tabular
"
+ "| Plataforma | Score | Linhas | Evidencias | Human ready | Avisos |
"
+ "".join(rows)
+ "
"
)
return html_shell("Mais Humana - indice operacional", body)
def write_index_html(
path: Path,
reports: Sequence[PlatformHumanReport],
qualities: Sequence[PlatformQualityReport],
bundle: ReportBundle | None = None,
) -> Path:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(index_html(reports, qualities, bundle), encoding="utf-8")
return path