app/templates/tracker_detail.html (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
{% extends "base.html" %}
{% block title %}{{ tracker.canonical_url }} — {{ app_name }}{% endblock %}
{% block content %}
<p><a href="/">← {{ t('back') }}</a></p>
<h2 class="mono">{{ tracker.canonical_url }}</h2>
<p>
<span class="status status-{{ tracker.current_status }}">
<span class="dot" aria-hidden="true"></span>{{ tracker.current_status }}
</span>
· {{ t('score') }}:
{% if metrics.score is not none %}{{ metrics.score }}{% else %}{{ t('score_insufficient') }}{% endif %}
{% if metrics.provisional %}<span class="badge">{{ t('provisional') }}</span>{% endif %}
</p>
<div class="metrics-grid">
<div><strong>{{ t('uptime_24h') }}</strong> {{ metrics.uptime_24h|pct }}</div>
<div><strong>{{ t('uptime_7d') }}</strong> {{ metrics.uptime_7d|pct }}</div>
<div><strong>{{ t('uptime_30d') }}</strong> {{ metrics.uptime_30d|pct }}</div>
<div><strong>{{ t('latency_med_7d') }}</strong> {{ metrics.latency_median_7d|ms }}</div>
<div><strong>{{ t('latency_p95') }}</strong> {{ metrics.latency_p95_7d|ms }}</div>
<div><strong>{{ t('valid_rate') }}</strong> {{ metrics.valid_rate_7d|pct }}</div>
<div><strong>{{ t('measurements') }}</strong> {{ metrics.measurement_count }}</div>
<div><strong>{{ t('tracking') }}</strong> {{ '%.1f'|format(metrics.tracking_days) }} {{ t('days') }}</div>
</div>
{% if spark %}
<svg class="sparkline" viewBox="0 0 240 40" role="img" aria-label="{{ t('spark_label') }}">
{% set mx = spark|max if spark|max > 0 else 1 %}
{% for v in spark %}
{% set x = loop.index0 * (240 / ([spark|length - 1, 1]|max)) %}
{% set y = 38 - (v / mx * 34) %}
<circle cx="{{ '%.1f'|format(x) }}" cy="{{ '%.1f'|format(y) }}" r="2" />
{% if not loop.first %}
{% set px = (loop.index0 - 1) * (240 / ([spark|length - 1, 1]|max)) %}
{% set py = 38 - (spark[loop.index0 - 1] / mx * 34) %}
<line x1="{{ '%.1f'|format(px) }}" y1="{{ '%.1f'|format(py) }}" x2="{{ '%.1f'|format(x) }}" y2="{{ '%.1f'|format(y) }}" />
{% endif %}
{% endfor %}
</svg>
{% endif %}
<h3>{{ t('sources') }}</h3>
<ul>
{% for s in tracker.sources %}
<li>
{{ s.source_name }}
{% if s.is_best_at_source %}· {{ t('best_at_source') }}{% endif %}
{% if s.is_stable_at_source %}· {{ t('stable_at_source') }}{% endif %}
{% if s.is_live_at_source %}· {{ t('live_at_source') }}{% endif %}
<span class="muted">({{ t('seen') }} {{ s.last_seen_at|dt }})</span>
</li>
{% else %}
<li>{{ t('no_source') }}</li>
{% endfor %}
</ul>
<h3>{{ t('dns') }}</h3>
<p>{{ t('terminal_cname') }}: <code>{{ tracker.terminal_cname or '—' }}</code></p>
<p>{{ t('infra_fp') }}: <code>{{ tracker.infrastructure_fingerprint or '—' }}</code></p>
<p>{{ t('asn') }}: {% if tracker.asn %}AS{{ tracker.asn }} {{ tracker.network_name or '' }}{% else %}{{ t('unknown') }}{% endif %}
· {{ t('country') }}: {{ tracker.country_code or t('unknown') }}</p>
<ul>
{% for d in tracker.dns_records %}
<li><code>{{ d.record_type }}</code> {{ d.value }}</li>
{% else %}
<li>{{ t('no_dns') }}</li>
{% endfor %}
</ul>
{% if aliases %}
<h3>{{ t('shared_infra') }}</h3>
<p>{{ t('shared_infra_blurb') }}</p>
<ul>
{% for a in aliases %}
<li><a class="mono" href="/trackers/{{ a.id }}">{{ a.canonical_url }}</a></li>
{% endfor %}
</ul>
{% endif %}
<h3>{{ t('recent_history') }}</h3>
<div class="table-wrap">
<table>
<thead>
<tr><th>{{ t('when') }}</th><th>{{ t('col_status') }}</th><th>{{ t('th_latency') }}</th><th>{{ t('valid') }}</th><th>{{ t('error') }}</th></tr>
</thead>
<tbody>
{% for p in probes %}
<tr>
<td>{{ p.checked_at|dt }}</td>
<td>{{ p.status }}</td>
<td>{{ p.latency_ms|ms }}</td>
<td>{{ t('yes') if p.response_valid else t('no') }}</td>
<td>{% if p.error_kind %}{{ p.error_kind }}{% if p.error_detail %}: {{ p.error_detail }}{% endif %}{% else %}—{% endif %}</td>
</tr>
{% else %}
<tr><td colspan="5">{{ t('no_probes') }}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
|