portal: more home cards

This commit is contained in:
Iain Learmonth 2022-05-14 11:03:25 +01:00
parent 3d280f391e
commit f417d263f3
2 changed files with 101 additions and 27 deletions

View file

@ -5,6 +5,7 @@ from sqlalchemy import desc, or_
from app.models.activity import Activity from app.models.activity import Activity
from app.models.alarms import Alarm from app.models.alarms import Alarm
from app.models.bridges import Bridge
from app.models.mirrors import Origin, Proxy from app.models.mirrors import Origin, Proxy
from app.models.base import Group from app.models.base import Group
from app.portal.list import NewMirrorListForm from app.portal.list import NewMirrorListForm
@ -48,6 +49,16 @@ def format_datetime(s: datetime) -> str:
return s.strftime("%a, %d %b %Y %H:%M:%S") return s.strftime("%a, %d %b %Y %H:%M:%S")
def total_origins_blocked():
count = 0
for o in Origin.query.filter(Origin.destroyed == None).all():
for a in o.alarms:
if a.alarm_type.startswith("ooni"):
if a.alarm_state == AlarmState.WARNING:
count += 1
break
return count
@portal.route("/") @portal.route("/")
def portal_home(): def portal_home():
groups = Group.query.order_by(Group.group_name).all() groups = Group.query.order_by(Group.group_name).all()
@ -60,9 +71,17 @@ def portal_home():
s: len(Alarm.query.filter(Alarm.alarm_state == s.upper(), Alarm.last_updated > (now - timedelta(days=1))).all()) s: len(Alarm.query.filter(Alarm.alarm_state == s.upper(), Alarm.last_updated > (now - timedelta(days=1))).all())
for s in ["critical", "warning", "ok", "unknown"] for s in ["critical", "warning", "ok", "unknown"]
} }
br_last = {
d: len(Bridge.query.filter(Bridge.deprecated > (now - timedelta(days=d))).all())
for d in [1, 3, 7]
}
activity = Activity.query.filter(Activity.added > (now - timedelta(days=2))).order_by(desc(Activity.added)).all() activity = Activity.query.filter(Activity.added > (now - timedelta(days=2))).order_by(desc(Activity.added)).all()
onionified = len([o for o in Origin.query.filter(Origin.destroyed == None).all() if o.onion() != None])
ooni_blocked = total_origins_blocked()
total_origins = len(Origin.query.filter(Origin.destroyed == None).all())
return render_template("home.html.j2", section="home", groups=groups, last24=last24, last72=last72, return render_template("home.html.j2", section="home", groups=groups, last24=last24, last72=last72,
lastweek=lastweek, proxies=proxies, **alarms, activity=activity) lastweek=lastweek, proxies=proxies, **alarms, activity=activity, total_origins=total_origins,
onionified=onionified, br_last=br_last, ooni_blocked=ooni_blocked)
@portal.route("/search") @portal.route("/search")

View file

@ -10,7 +10,10 @@
<h3 class="h4 card-header">Groups</h3> <h3 class="h4 card-header">Groups</h3>
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Active Groups: {{ groups | count }}</h5> <h5 class="card-title">Active Groups: {{ groups | count }}</h5>
<p class="card-text">{% for group in groups %}<a href="{{ url_for("portal.group.group_edit", group_id=group.id) }}" title="{{ group.description }}">{{ group.group_name }}</a>{{ ", " if not loop.last else "" }}{% endfor %}</p> <p class="card-text">{% for group in groups %}
<a href="{{ url_for("portal.group.group_edit", group_id=group.id) }}"
title="{{ group.description }}">{{ group.group_name }}</a>
{{ ", " if not loop.last else "" }}{% endfor %}</p>
</div> </div>
</div> </div>
</div> </div>
@ -28,6 +31,57 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col">
<div class="card h-100">
<h3 class="h4 card-header">Tor Bridges</h3>
<div class="card-body">
<h5 class="card-title">Total bridges running: {{ bridges | count }}</h5>
<p class="card-text">Marked blocked:
<ul class="card-text">
<li>Last 24 hours: {{ br_last[1] }}</li>
<li>Last 72 hours: {{ br_last[3] }}</li>
<li>Last week: {{ br_last[7] }}</li>
</ul>
</div>
</div>
</div>
</div>
<div class="row row-cols-1 row-cols-md-3 g-4 pt-4">
<div class="col">
<div class="card h-100">
<h3 class="h4 card-header">Onion Services</h3>
<div class="card-body">
<h5 class="card-title">Onionification progress:</h5>
<p class="card-text"><span class="display-1">{{ onionified }}</span>/{{ total_origins }}</p>
<div class="progress">
<div class="progress-bar" role="progressbar"
style="width: {{ onionified / total_origins * 100 }}%"
aria-valuenow="{{ onionified / total_origins * 100 }}" aria-valuemin="0"
aria-valuemax="100">{{ (onionified / total_origins * 100) | int }}%
</div>
</div>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<h3 class="h4 card-header"><abbr title="Open Observatory of Network Interference">OONI</abbr></h3>
<div class="card-body">
<h5 class="card-title">Origins with censorship detected:</h5>
<p class="card-text"><span class="display-1">{{ ooni_blocked }}</span>/{{ total_origins }}</p>
<div class="progress">
<div class="progress-bar" role="progressbar"
style="width: {{ ooni_blocked / total_origins * 100 }}%"
aria-valuenow="{{ ooni_blocked / total_origins * 100 }}" aria-valuemin="0"
aria-valuemax="100">{{ (ooni_blocked / total_origins * 100) | int }}%
</div>
</div>
</div>
</div>
</div>
<div class="col"> <div class="col">
<div class="card h-100"> <div class="card h-100">
<h3 class="h4 card-header">Alarms</h3> <h3 class="h4 card-header">Alarms</h3>
@ -44,6 +98,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row mt-4"> <div class="row mt-4">
<div class="col"> <div class="col">
<div class="card h-100"> <div class="card h-100">