diff --git a/baps_types/alert.py b/baps_types/alert.py new file mode 100644 index 0000000..493a544 --- /dev/null +++ b/baps_types/alert.py @@ -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 diff --git a/helpers/alert_manager.py b/helpers/alert_manager.py new file mode 100644 index 0000000..820f45d --- /dev/null +++ b/helpers/alert_manager.py @@ -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) diff --git a/ui-templates/alerts.html b/ui-templates/alerts.html new file mode 100644 index 0000000..edf1b7e --- /dev/null +++ b/ui-templates/alerts.html @@ -0,0 +1,41 @@ +{% extends 'base.html' %} +{% block head %} + +{% endblock %} +{% block content_inner %} + {% if data %} +
BAPSicle is having some issues. Please review the alerts page. + {% else %} +
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.
+ {% endif %} +Version: {{data.server_version}} - Build: {{data.server_build}} - Branch: {{data.server_branch}}
Server Name: {{data.server_name}}
diff --git a/web_server.py b/web_server.py index 90f6527..60dd29c 100644 --- a/web_server.py +++ b/web_server.py @@ -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)