Skip to content

Commit

Permalink
improve usability: add report view (#799)
Browse files Browse the repository at this point in the history
Signed-off-by: Matthias Büchse <[email protected]>
Signed-off-by: Kurt Garloff <[email protected]>
Co-authored-by: Kurt Garloff <[email protected]>
  • Loading branch information
mbuechse and garloff authored Nov 4, 2024
1 parent 1d621ec commit d41d1c4
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 8 deletions.
35 changes: 33 additions & 2 deletions compliance-monitor/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ class ViewType(Enum):
fragment = "fragment"


VIEW_REPORT = {
ViewType.markdown: 'report.md',
ViewType.fragment: 'report.md',
ViewType.page: 'overview.html',
}
VIEW_DETAIL = {
ViewType.markdown: 'details.md',
ViewType.fragment: 'details.md',
Expand All @@ -111,7 +116,7 @@ class ViewType(Enum):
ViewType.fragment: 'scope.md',
ViewType.page: 'overview.html',
}
REQUIRED_TEMPLATES = tuple(set(fn for view in (VIEW_DETAIL, VIEW_TABLE, VIEW_SCOPE) for fn in view.values()))
REQUIRED_TEMPLATES = tuple(set(fn for view in (VIEW_REPORT, VIEW_DETAIL, VIEW_TABLE, VIEW_SCOPE) for fn in view.values()))


# do I hate these globals, but I don't see another way with these frameworks
Expand Down Expand Up @@ -544,14 +549,23 @@ async def get_status(
return convert_result_rows_to_dict2(rows2, get_scopes(), include_report=True)


def _build_report_url(base_url, report, *args, **kwargs):
if kwargs.get('download'):
return f"{base_url}reports/{report}"
url = f"{base_url}page/report/{report}"
if len(args) == 2: # version, testcase_id --> add corresponding fragment specifier
url += f"#{args[0]}_{args[1]}"
return url


def render_view(view, view_type, detail_page='detail', base_url='/', title=None, **kwargs):
media_type = {ViewType.markdown: 'text/markdown'}.get(view_type, 'text/html')
stage1 = stage2 = view[view_type]
if view_type is ViewType.page:
stage1 = view[ViewType.fragment]
def scope_url(uuid): return f"{base_url}page/scope/{uuid}" # noqa: E306,E704
def detail_url(subject, scope): return f"{base_url}page/{detail_page}/{subject}/{scope}" # noqa: E306,E704
def report_url(report): return f"{base_url}reports/{report}" # noqa: E306,E704
def report_url(report, *args, **kwargs): return _build_report_url(base_url, report, *args, **kwargs) # noqa: E306,E704
fragment = templates_map[stage1].render(detail_url=detail_url, report_url=report_url, scope_url=scope_url, **kwargs)
if view_type != ViewType.markdown and stage1.endswith('.md'):
fragment = markdown(fragment, extensions=['extra'])
Expand All @@ -560,6 +574,23 @@ def report_url(report): return f"{base_url}reports/{report}" # noqa: E306,E704
return Response(content=fragment, media_type=media_type)


@app.get("/{view_type}/report/{report_uuid}")
async def get_report_view(
request: Request,
account: Annotated[Optional[tuple[str, str]], Depends(auth)],
conn: Annotated[connection, Depends(get_conn)],
view_type: ViewType,
report_uuid: str,
):
with conn.cursor() as cur:
specs = db_get_report(cur, report_uuid)
if not specs:
raise HTTPException(status_code=404)
spec = specs[0]
check_role(account, spec['subject'], ROLES['read_any'])
return render_view(VIEW_REPORT, view_type, report=spec, base_url=settings.base_url, title=f'Report {report_uuid}')


@app.get("/{view_type}/detail/{subject}/{scopeuuid}")
async def get_detail(
request: Request,
Expand Down
2 changes: 1 addition & 1 deletion compliance-monitor/templates/details.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ No recent test results available.
{% set res = version_result.results[testcase_id] if testcase_id in version_result.results else dict(result=0) -%}
| {% if res.result != 1 %}⚠️ {% endif %}{{ testcase.id }} |
{#- #} {% if res.report -%}
[{{ res.result | verdict_check }}]({{ report_url(res.report) }})
[{{ res.result | verdict_check }}]({{ report_url(res.report, version, testcase_id) }})
{%- else -%}
{{ res.result | verdict_check }}
{%- endif -%}
Expand Down
12 changes: 7 additions & 5 deletions compliance-monitor/templates/overview.html.j2
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>{{ title or 'SCS compliance overview' }}</title>
</head>
<body>
<style type="text/css">
table {border-collapse:collapse;}
table td, table th {vertical-align:top;padding:0.75rem;border:1px solid #dadde1;}
table th {font-weight:700;background-color:#00000008;}
html {text-rendering:optimizelegibility;font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";}
li {margin:0.33em 0;}
pre.line {margin: 0;}
</style>
<head>
<meta charset="utf-8">
<title>{{ title or 'SCS compliance overview' }}</title>
</head>
<body>
{% if title %}<h1>{{title}}</h1>
{% endif %}{{fragment}}</body>
</html>
66 changes: 66 additions & 0 deletions compliance-monitor/templates/report.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## General info

- uuid: [{{ report.run.uuid }}]({{ report_url(report.run.uuid, download=True) }})
- subject: {{ report.subject }}
- scope: [{{ report.spec.name }}]({{ scope_url(report.spec.uuid) }})
- checked at: {{ report.checked_at }}

## Results

{% for version, version_results in report.versions.items() %}{% if version_results %}
### {{ version }}

| test case | result | invocation |
|---|---|---|
{% for testcase_id, result_data in version_results.items() -%}
| {{ testcase_id }} {: #{{ version + '_' + testcase_id }} } | {{ result_data.result | verdict_check }} | [{{ result_data.invocation }}](#{{ result_data.invocation }}) |
{% endfor %}
{% endif %}{% endfor %}

## Run

### Variable assignment

| key | value |
|---|---|
{% for key, value in report.run.assignment.items() -%}
| `{{ key }}` | `{{ value }}` |
{% endfor %}

### Check tool invocations

{% for invid, invdata in report.run.invocations.items() %}
#### Invocation {{invid}} {: #{{ invid }} }

- cmd: `{{ invdata.cmd }}`
- rc: {{ invdata.rc }}
- channel summary
{%- for channel in ('critical', 'error', 'warning') %}
{%- if invdata[channel] %}
- **{{ channel }}: {{ invdata[channel] }}**
{%- else %}
- {{ channel }}: –
{%- endif %}
{%- endfor %}
- results
{%- for resultid, result in invdata.results.items() %}
- {{ resultid }}: {{ result | verdict_check }}
{%- endfor %}

{% if invdata.stdout -%}
<details><summary>Captured stdout</summary>
```text
{{ '\n'.join(invdata.stdout) }}
```
</details>
{%- endif %}

{% if invdata.stderr -%}
<details {% if invdata.warning or invdata.error or invdata.critical %}open{% endif %}><summary>Captured stderr</summary>
{%- for line in invdata.stderr %}
<pre class="line">{% if line.split(':', 1)[0].lower() in ('warning', 'error', 'critical') %}{{ '<strong>' + line + '</strong>' }}{% else %}{{ line }}{% endif %}</pre>
{%- endfor %}
</details>
{%- endif %}

{% endfor %}

0 comments on commit d41d1c4

Please sign in to comment.