153 lines
3.5 KiB
HTML
153 lines
3.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>ANABASIS CLIENTS</title>
|
|
<meta http-equiv="refresh" content="60" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;600&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
<style>
|
|
body {
|
|
font-family: "IBM Plex Sans", sans-serif;
|
|
color: white;
|
|
background: black;
|
|
text-align: center;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
h1,
|
|
h2 {
|
|
margin-top: 1.5em;
|
|
margin-bottom: 0 !important;
|
|
}
|
|
|
|
.status {
|
|
font-size: 24pt;
|
|
font-weight: 600;
|
|
border: 2px solid;
|
|
border-radius: 3px;
|
|
padding: 0.5em 0.75em;
|
|
}
|
|
|
|
.status-container {
|
|
margin: 1rem 0;
|
|
}
|
|
|
|
.status-container div {
|
|
margin-bottom: 0.5em;
|
|
}
|
|
|
|
.status-empty {
|
|
background: darkred;
|
|
}
|
|
|
|
.status-populated {
|
|
background: darkgreen;
|
|
}
|
|
|
|
td {
|
|
padding: 0.1em 0.5em;
|
|
}
|
|
|
|
.nonhuman {
|
|
opacity: .66;
|
|
}
|
|
|
|
.log {
|
|
padding: 1em 0;
|
|
}
|
|
|
|
.log-out {
|
|
color: red;
|
|
}
|
|
|
|
.log-in {
|
|
color: green;
|
|
}
|
|
|
|
.datetime {
|
|
font-weight: 600;
|
|
margin: 1em 0;
|
|
}
|
|
|
|
.level {
|
|
display: none;
|
|
}
|
|
</style>
|
|
<link
|
|
rel="stylesheet"
|
|
href="https://necolas.github.io/normalize.css/8.0.1/normalize.css"
|
|
integrity="sha384-M86HUGbBFILBBZ9ykMAbT3nVb0+2C7yZlF8X2CiKNpDOQjKroMJqIeGZ/Le8N2Qp"
|
|
crossorigin="anonymous"
|
|
/>
|
|
</head>
|
|
<body>
|
|
<h1>/|\ Anabasis Clients</h1>
|
|
<div class="datetime">{{now.strftime("%c")}}</div>
|
|
|
|
<h2>STATUS</h2>
|
|
<div class="status-container">
|
|
<div
|
|
class="status status-{{'populated' if status.level > 0 else 'empty'}}"
|
|
>
|
|
{{status.description}}
|
|
</div>
|
|
<div class="status-explanation">{{status.text}}</div>
|
|
<div class="level">{{status.level}}</div>
|
|
<div>
|
|
<strong>Since:</strong> {% if last_change %} {{last_change['ts'].strftime("%c")}} {% if
|
|
status.level == 0 %}({{last_change.leases | map(attribute='display') |
|
|
join(', ')}}){% endif %} {% else %} forever? {% endif %}
|
|
</div>
|
|
</div>
|
|
<h2>Current clients</h2>
|
|
<table>
|
|
<tr>
|
|
<th>MAC</th>
|
|
<th>hostname</th>
|
|
<th>IP address</th>
|
|
</tr>
|
|
{% for lease in leases %}
|
|
<tr class="current-lease {{'nonhuman' if not lease.is_human else ''}}">
|
|
<td>{{lease.mac}}</td>
|
|
<td>{{lease.hostname or "???"}}</td>
|
|
<td>{{lease.ip}}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
|
|
{%if internal %}
|
|
<h2>Log</h2>
|
|
<table class="log">
|
|
{% for entry in log %}
|
|
<tr>
|
|
<td>{{entry.ts.strftime("%c")}}</td>
|
|
<td>
|
|
{% if entry.state %}
|
|
<span class="log-in">IN</span>
|
|
{% else %}
|
|
<span class="log-out">OUT</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{entry.lease.display}}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
|
|
<h2>Leaderboard</h2>
|
|
<ol>
|
|
{% for entry in leaderboard %}
|
|
<li>{{entry.name}} ({{entry.total}})</li>
|
|
{% endfor %}
|
|
</ol>
|
|
{% endif %}
|
|
</body>
|
|
</html>
|