diff options
-rw-r--r-- | app.py | 15 | ||||
-rw-r--r-- | requirements.txt | 11 | ||||
-rw-r--r-- | services.py | 52 | ||||
-rw-r--r-- | static/style.css | 20 | ||||
-rw-r--r-- | templates/services.html | 105 | ||||
-rw-r--r-- | templates/template.html | 1 |
6 files changed, 195 insertions, 9 deletions
@@ -1,5 +1,6 @@ import configparser import database +import services import flask app = flask.Flask(__name__) @@ -27,9 +28,21 @@ def discord(): with database.Database() as db: return flask.render_template( "discord.html", - **get_template_items("Discord", db), + **get_template_items("discord", db), discord = CONFIG["discord"]["username"] ) +@app.route("/services") +def serve_services(): + with database.Database() as db: + return flask.render_template( + "services.html", + **get_template_items("services", db), + docker = services.get_docker_stats(), + qbit = services.get_qbit_stats(), + trans = services.get_trans_stats(), + pihole = services.get_pihole_stats() + ) + if __name__ == "__main__": app.run(host = "0.0.0.0", debug = True) diff --git a/requirements.txt b/requirements.txt index 0fed313..e86483b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,8 @@ -Flask==1.1.2 +python_qbittorrent==0.4.2 PyMySQL==1.0.2 -docker==4.4.1 -python-qbittorrent==0.4.2 -transmission-clutch
\ No newline at end of file +Flask==1.1.2 +PiHole_api==2.6 +clutch==0.1a2 +docker_py==1.10.6 +pihole==0.1.2 +qbittorrent==0.1.6 diff --git a/services.py b/services.py index 16268ef..dd70b33 100644 --- a/services.py +++ b/services.py @@ -1,8 +1,12 @@ import qbittorrent +import multiprocessing import docker import clutch -import app +import pihole +import queue import json +import time +import app def humanbytes(B): 'Return the given bytes as a human friendly KB, MB, GB, or TB string' @@ -23,13 +27,41 @@ def humanbytes(B): elif TB <= B: return '{0:.2f} TB'.format(B/TB) +def timeout(func): + # cant get this to work with queue.Queue() for some reason? + # this works but Manager() uses an extra thread than Queue() + manager = multiprocessing.Manager() + returnVan = manager.list() + ti = time.time() + + def runFunc(q, func): + q.append(func()) + + def beginTimeout(): + t = multiprocessing.Process(target = runFunc, args = (returnVan, func)) + t.start() + + t.join(timeout = app.CONFIG["servicetimeout"].getint("seconds")) + + # print("Request took:", time.time() - ti) + try: + return returnVan[0] + except IndexError: + if t.is_alive(): + t.terminate() + + return beginTimeout + +@timeout def get_docker_stats(): + client = docker.DockerClient(base_url = "tcp://%s:%s" % (app.CONFIG["docker"]["url"], app.CONFIG["docker"]["port"])) return { container.name: container.status for container in client.containers.list(all = True) } +@timeout def get_qbit_stats(): numtorrents = 0 bytes_dl = 0 @@ -46,9 +78,10 @@ def get_qbit_stats(): "bytes_dl": humanbytes(bytes_dl), "bytes_up": humanbytes(bytes_up), "num": numtorrents, - "ratio": bytes_up / bytes_dl + "ratio": "%.3f" % (float(bytes_up) / float(bytes_dl)) } +@timeout def get_trans_stats(): client = clutch.client.Client( address = "http://%s:%s/transmission/rpc" % (app.CONFIG["transmission"]["url"], app.CONFIG["transmission"]["port"]), @@ -60,9 +93,20 @@ def get_trans_stats(): "bytes_dl": humanbytes(stats["arguments"]["cumulative_stats"]["downloaded_bytes"]), "bytes_up": humanbytes(stats["arguments"]["cumulative_stats"]["uploaded_bytes"]), "num": stats["arguments"]["torrent_count"], - "ratio": stats["arguments"]["cumulative_stats"]["uploaded_bytes"] / stats["arguments"]["cumulative_stats"]["downloaded_bytes"] + "ratio": "%.3f" % (float(stats["arguments"]["cumulative_stats"]["uploaded_bytes"]) / float(stats["arguments"]["cumulative_stats"]["downloaded_bytes"])) + } + +@timeout +def get_pihole_stats(): + ph = pihole.PiHole(app.CONFIG["pihole"]["url"]) + return { + "status": ph.status, + "queries": ph.total_queries, + "clients": ph.unique_clients, + "percentage": ph.ads_percentage, + "blocked": ph.blocked } if __name__ == "__main__": - print(get_trans_stats())
\ No newline at end of file + print(get_qbit_stats())
\ No newline at end of file diff --git a/static/style.css b/static/style.css index 952d3ca..7bc2190 100644 --- a/static/style.css +++ b/static/style.css @@ -82,6 +82,26 @@ nav a { background-color: white; } +article section table { + font-family: monospace; +} + +article section table td { + text-align: right; +} + +.running { + background-color: green; + padding: 1, 1, 1, 1; + margin: 0, 0, 2, 3; +} + +.notRunning { + background-color: red; + padding: 1, 1, 1, 1; + margin: 0, 0, 2, 3; +} + header img { max-height: 110px; } diff --git a/templates/services.html b/templates/services.html new file mode 100644 index 0000000..321a7a0 --- /dev/null +++ b/templates/services.html @@ -0,0 +1,105 @@ +{% extends "template.html" %} +{% block content %} +<article id=statusTables> + <section id=docker> + <h2>docker</h2> + {% if docker == None %} + <p>Couldn't access the docker API. Is sherpa running?</p> + {% else %} + <table> + {% for name, status in docker.items() %} + <tr> + <td>{{name}}</td> + {% if status == "running" %} + <td class=running>{{status}}</td> + {% else %} + <td class=notRunning>{{status}}</td> + {% endif %} + </tr> + {% endfor %} + </table> + {% endif %} + </section> + <section id="torrents"> + <h2>qbittorrent</h2> + {% if qbit == None %} + <p>Couldn't access the qbittorrent API. Is docker container running?</p> + {% else %} + <table> + <tr> + <td>downloaded</td> + <td>{{qbit["bytes_dl"]}}</td> + </tr> + <tr> + <td>uploaded</td> + <td>{{qbit["bytes_up"]}}</td> + </tr> + <tr> + <td>torrents</td> + <td>{{qbit["num"]}}</td> + </tr> + <tr> + <td>ratio</td> + <td>{{qbit["ratio"]}}</td> + </tr> + </table> + {% endif %} + <h2>transmission</h2> + {% if trans == None %} + <p>Couldn't access the transmission API. Is docker container running?</p> + {% else %} + <table> + <tr> + <td>downloaded</td> + <td>{{trans["bytes_dl"]}}</td> + </tr> + <tr> + <td>uploaded</td> + <td>{{trans["bytes_up"]}}</td> + </tr> + <tr> + <td>torrents</td> + <td>{{trans["num"]}}</td> + </tr> + <tr> + <td>ratio</td> + <td>{{trans["ratio"]}}</td> + </tr> + </table> + {% endif %} + </section> + <section id=pihole> + <h2>pihole</h2> + {% if pihole == None %} + <p>Couldn't access the pihole API. Is docker container running?</p> + {% else %} + <table> + <tr> + <td>status</td> + {% if pihole["status"] == "enabled" %} + <td class=running>{{pihole["status"]}}</td> + {% else %} + <td class=notRunning>{{pihole["status"]}}</td> + {% endif %} + </tr> + <tr> + <td>queries</td> + <td>{{pihole["queries"]}}</td> + </tr> + <tr> + <td>clients</td> + <td>{{pihole["clients"]}}</td> + </tr> + <tr> + <td>percentage blocked</td> + <td>{{pihole["percentage"]}}%</td> + </tr> + <tr> + <td>blocked</td> + <td>{{pihole["blocked"]}}</td> + </tr> + </table> + {% endif %} + </section> +</article> +{% endblock %}
\ No newline at end of file diff --git a/templates/template.html b/templates/template.html index d6c1a0b..6b0d894 100644 --- a/templates/template.html +++ b/templates/template.html @@ -2,6 +2,7 @@ <html> <head> <link rel='stylesheet' href="{{url_for('static', filename='style.css')}}"> + <title>edaweb :: {{title}}</title> </head> <body> <div id=wrapper> |