Add WIP UI and manager for alerts.
This commit is contained in:
parent
502c7e3bed
commit
ac5409587d
5 changed files with 174 additions and 1 deletions
65
baps_types/alert.py
Normal file
65
baps_types/alert.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
from typing import Any, Dict
|
||||
from datetime import datetime
|
||||
|
||||
CRITICAL = "Critical"
|
||||
WARNING = "Warning"
|
||||
|
||||
class Alert:
|
||||
start_time: int = 0
|
||||
last_time: int = 0
|
||||
end_time: int = -1
|
||||
id: str
|
||||
title: str
|
||||
description: str
|
||||
module: str
|
||||
severity: str
|
||||
|
||||
|
||||
@property
|
||||
def ui_class(self) -> str:
|
||||
if self.severity == CRITICAL:
|
||||
return "danger"
|
||||
if self.severity == WARNING:
|
||||
return "warning"
|
||||
return "info"
|
||||
|
||||
# return self._weight
|
||||
|
||||
# weight.setter
|
||||
# def weight(self, value: int):
|
||||
# self._weight = value
|
||||
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
attrs = ["start_time", "last_time", "end_time", "id", "title", "description", "module", "severity"]
|
||||
out = {}
|
||||
for attr in attrs:
|
||||
out[attr] = self.__getattribute__(attr)
|
||||
|
||||
return out
|
||||
|
||||
def __init__(self, new_data: Dict[str,Any]):
|
||||
required_vars = [
|
||||
"start_time", # Just in case an alert wants to show starting earlier than it is reported.
|
||||
"id",
|
||||
"title",
|
||||
"description",
|
||||
"module",
|
||||
"severity"
|
||||
]
|
||||
|
||||
for key in required_vars:
|
||||
if key not in new_data.keys():
|
||||
raise KeyError("Key {} is missing from data to create Alert.".format(key))
|
||||
|
||||
#if type(new_data[key]) != type(getattr(self,key)):
|
||||
# raise TypeError("Key {} has type {}, was expecting {}.".format(key, type(new_data[key]), type(getattr(self,key))))
|
||||
|
||||
# Account for if the creator didn't want to set a custom time.
|
||||
if key == "start_time" and new_data[key] == -1:
|
||||
new_data[key] = datetime.now()
|
||||
|
||||
setattr(self,key,new_data[key])
|
||||
|
||||
self.last_time = self.start_time
|
29
helpers/alert_manager.py
Normal file
29
helpers/alert_manager.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
from typing import List
|
||||
from baps_types.alert import CRITICAL, Alert
|
||||
|
||||
class AlertManager():
|
||||
_alerts: List[Alert]
|
||||
|
||||
def __init__(self):
|
||||
self._alerts = [Alert(
|
||||
{
|
||||
"start_time": -1,
|
||||
"id": "test",
|
||||
"title": "Test Alert",
|
||||
"description": "This is a test alert.",
|
||||
"module": "Test",
|
||||
"severity": CRITICAL
|
||||
}
|
||||
)]
|
||||
|
||||
@property
|
||||
def alerts_current(self):
|
||||
return self._alerts
|
||||
|
||||
@property
|
||||
def alert_count_current(self):
|
||||
return len(self._alerts)
|
||||
|
||||
@property
|
||||
def alert_count_previous(self):
|
||||
return len(self._alerts)
|
41
ui-templates/alerts.html
Normal file
41
ui-templates/alerts.html
Normal file
|
@ -0,0 +1,41 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block head %}
|
||||
<meta http-equiv="refresh" content="2;url=/alerts" />
|
||||
{% endblock %}
|
||||
{% block content_inner %}
|
||||
{% if data %}
|
||||
<h2>Current Alerts: {{ data.alert_count_current }}</h2>
|
||||
|
||||
<div class="accordion" id="accordionExample">
|
||||
{% for alert in data.alerts_current %}
|
||||
<div class="card alert-{{ alert.ui_class }}">
|
||||
<div class="card-header" id="headingOne">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
||||
{{ alert.title }}
|
||||
</button>
|
||||
<span class="badge badge-{{ alert.ui_class}}">{{ alert.severity }}</span>
|
||||
</h2>
|
||||
<span class="badge">Since {{ alert.start_time }}</span>
|
||||
<span class="badge">Last Seen {{ alert.last_time }}</span>
|
||||
{% if alert.end_time > -1 %}
|
||||
<span class="badge">Ended {{ alert.end_time }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
<strong>Module: </strong>{{ alert.module }}<br>
|
||||
{{ alert.description }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<hr>
|
||||
<h2>Previous Alerts: {{ data.alert_count_previous }}</h2>
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,4 +1,7 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block head %}
|
||||
<meta http-equiv="refresh" content="2;url=/" />
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<div class="card-body p-0">
|
||||
|
@ -16,6 +19,23 @@
|
|||
<a href="/presenter/" class="btn btn-primary btn-user btn-block">
|
||||
Open BAPS Presenter
|
||||
</a>
|
||||
|
||||
<hr>
|
||||
{% if data.alert_count > 0 %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<h4 class="alert-heading">Something's up! <a href="/alerts" class="btn btn-sm btn-danger float-right"><span class="badge badge-light mr-1">{{data.alert_count}}</span>View Alerts</a></h4>
|
||||
<p>BAPSicle is having some issues. Please review the alerts page.
|
||||
{% else %}
|
||||
<div class="alert alert-success" role="alert">
|
||||
<h4 class="alert-heading">We're all good!</h4>
|
||||
<p>BAPSicle seems to be running well. If this doesn't seem to be the case, try restarting or taking a closer look at the logs.</p>
|
||||
{% endif %}
|
||||
<hr>
|
||||
<a href="/logs" class="btn btn-success">Logs</a>
|
||||
<a href="/restart" class="btn btn-info">Restart</a>
|
||||
<a href="/shutdown" class="btn btn-danger">Shutdown</a>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<p>Version: {{data.server_version}} - Build: {{data.server_build}} - Branch: {{data.server_branch}}</p>
|
||||
<p>Server Name: {{data.server_name}}</p>
|
||||
|
|
|
@ -27,6 +27,7 @@ from helpers.state_manager import StateManager
|
|||
from helpers.the_terminator import Terminator
|
||||
from helpers.normalisation import get_normalised_filename_if_available
|
||||
from helpers.myradio_api import MyRadioAPI
|
||||
from helpers.alert_manager import AlertManager
|
||||
|
||||
env = Environment(
|
||||
loader=FileSystemLoader("%s/ui-templates/" % os.path.dirname(__file__)),
|
||||
|
@ -97,6 +98,7 @@ def render_template(file, data, status=200):
|
|||
logger: LoggingManager
|
||||
server_state: StateManager
|
||||
api: MyRadioAPI
|
||||
alerts: AlertManager
|
||||
|
||||
player_to_q: List[Queue] = []
|
||||
player_from_q: List[Queue] = []
|
||||
|
@ -116,6 +118,7 @@ def ui_index(request):
|
|||
data = {
|
||||
"ui_page": "index",
|
||||
"ui_title": "",
|
||||
"alert_count": alerts.alert_count_current,
|
||||
"server_version": config["server_version"],
|
||||
"server_build": config["server_build"],
|
||||
"server_name": config["server_name"],
|
||||
|
@ -135,6 +138,20 @@ def ui_status(request):
|
|||
"ui_page": "status", "ui_title": "Status"}
|
||||
return render_template("status.html", data=data)
|
||||
|
||||
@app.route("/alerts")
|
||||
def ui_alerts(request):
|
||||
channel_states = []
|
||||
for i in range(server_state.get()["num_channels"]):
|
||||
channel_states.append(status(i))
|
||||
|
||||
data = {
|
||||
"alerts_current": alerts.alerts_current,
|
||||
"alerts_count_current": alerts.alert_count_current,
|
||||
"ui_page": "alerts",
|
||||
"ui_title": "Alerts"
|
||||
}
|
||||
return render_template("alerts.html", data=data)
|
||||
|
||||
|
||||
@app.route("/config/player")
|
||||
def ui_config_player(request):
|
||||
|
@ -479,13 +496,14 @@ def restart(request):
|
|||
# Don't use reloader, it causes Nested Processes!
|
||||
def WebServer(player_to: List[Queue], player_from: List[Queue], state: StateManager):
|
||||
|
||||
global player_to_q, player_from_q, server_state, api, app
|
||||
global player_to_q, player_from_q, server_state, api, app, alerts
|
||||
player_to_q = player_to
|
||||
player_from_q = player_from
|
||||
server_state = state
|
||||
|
||||
logger = LoggingManager("WebServer")
|
||||
api = MyRadioAPI(logger, state)
|
||||
alerts = AlertManager()
|
||||
|
||||
process_title = "Web Server"
|
||||
setproctitle(process_title)
|
||||
|
|
Loading…
Reference in a new issue