diff options
| -rwxr-xr-x | .gitignore | 2 | ||||
| -rwxr-xr-x | app.py | 13 | ||||
| -rwxr-xr-x | requirements.txt | 8 | ||||
| -rwxr-xr-x | services.py | 74 | ||||
| -rwxr-xr-x | static/index.md | 2 | ||||
| -rwxr-xr-x | templates/services.html.j2 | 106 | 
6 files changed, 123 insertions, 82 deletions
| @@ -1,3 +1,5 @@ +*.pem +*.pub  homelab-wiki/wiki.env  homelab-wiki/images/*  edaweb.conf @@ -2,7 +2,7 @@ from paste.translogger import TransLogger  from waitress import serve  from PIL import Image  import configparser -import webbrowser +import transmission_rpc  import downloader  import datetime  import database @@ -78,6 +78,17 @@ def index():  def robots():      return flask.send_from_directory("static", "robots.txt") +@app.route("/services") +def serve_services(): +    with database.Database() as db: +        return flask.render_template( +            "services.html.j2", +            **get_template_items("services", db), +            docker = services.get_all_docker_containers(CONFIG.get("ssh", "docker_key_path")), +            trans = services.get_torrent_stats(), +            pihole = services.get_pihole_stats() +        ) +  @app.route("/discord")  def discord():      with database.Database() as db: diff --git a/requirements.txt b/requirements.txt index 0ce280b..581cd7c 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1,13 @@  itsdangerous==2.0.1  PyMySQL==1.0.2 -python_qbittorrent==0.4.2 +transmission_rpc==4.1.0  Werkzeug==2.3.7  Flask==2.2.2  PiHole_api -transmission-clutch  dataclasses  docker -PiHole-api +APiHole  Pillow==9.4.0 -python-qbittorrent==0.4.2  PyGithub  lxml  requests @@ -19,3 +17,5 @@ houdini.py  Pygments  mistune==2.0.3  twython==3.8.2 +fabric +paramiko
\ No newline at end of file diff --git a/services.py b/services.py index b56a07d..5fb7d81 100755 --- a/services.py +++ b/services.py @@ -3,8 +3,9 @@ from io import StringIO  from lxml import html, etree  from github import Github  import multiprocessing -import pihole as ph -import qbittorrent +import paramiko.client +from APiHole import PiHole +import transmission_rpc  import configparser  import math as maths  import requests @@ -12,6 +13,8 @@ import datetime  import urllib  import docker  import random +import subprocess +import fabric  import queue  import json  import time @@ -266,6 +269,68 @@ def scrape_whispa(whispa_url, since):                  })      return qnas +def get_docker_containers(host, ssh_key_path): +    result = fabric.Connection( +        host = host, +        user = "root", +        connect_kwargs = { +            "key_filename": ssh_key_path, +            "look_for_keys": False +        } +    ).run('docker ps -a -s --format "table {{.Names}};{{.Status}};{{.Image}}"', hide = True) +    return [line.split(";") for line in result.stdout.split("\n")[1:-1]] + +def get_all_docker_containers(ssh_key_path): +    containers = {} +    for host, name in CONFIG["docker_hosts"].items(): +        print(host) +        containers[(host, name)] = get_docker_containers(host, ssh_key_path) +    return containers + +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 = 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_torrent_stats(): +    client = transmission_rpc.client.Client( +        host = CONFIG.get("transmission", "host") +    ) +    s = vars(client.session_stats())["fields"] +    return { +        "Active torrents:": s["activeTorrentCount"], +        "Downloaded:": humanbytes(s["cumulative-stats"]["downloadedBytes"]), +        "Uploaded:": humanbytes(s["cumulative-stats"]["uploadedBytes"]), +        "Active time:": str(datetime.timedelta(seconds = s["cumulative-stats"]["secondsActive"])), +        "Files added:": s["cumulative-stats"]["filesAdded"], +        "Current upload speed": humanbytes(s["uploadSpeed"]) + "s/S", +        "Current download speed:": humanbytes(s["downloadSpeed"]) + "s/S" +    } + +@timeout +def get_pihole_stats(): +    return PiHole.GetSummary(CONFIG.get("pihole", "url"), CONFIG.get("pihole", "key"), True)  if __name__ == "__main__":      # print(get_trans_stats()) @@ -277,4 +342,7 @@ if __name__ == "__main__":      # print(request_recent_commits(since = datetime.datetime.now() - datetime.timedelta(days=30))) -    print(scrape_whispa(CONFIG.get("qnas", "url"), datetime.datetime.fromtimestamp(0.0))) +    # print(scrape_whispa(CONFIG.get("qnas", "url"), datetime.datetime.fromtimestamp(0.0))) +    # print(get_all_docker_containers(os.path.join(os.path.dirname(__file__), "edaweb-docker.pem"))) + +    print(get_torrent_stats()) diff --git a/static/index.md b/static/index.md index 99bfa0c..39bbc7c 100755 --- a/static/index.md +++ b/static/index.md @@ -16,6 +16,8 @@ i'll post my thoughts on here sometimes, and use this site to link to other stuf  - [git server - github alternative](https://git.eda.gay/)  - [jellyfin - web player for ~~legally downloaded~~ TV and films](https://jellyfin.eda.gay) - RIP emby! +[see the services im running right now](/services) (takes a couple seconds to load) +  these sites are hosted on my [homelab system](https://wiki.eda.gay)   diff --git a/templates/services.html.j2 b/templates/services.html.j2 index ebf8ebd..9c9e5ec 100755 --- a/templates/services.html.j2 +++ b/templates/services.html.j2 @@ -3,96 +3,54 @@  <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 %} +        <ul> +            {% for host, containers in docker.items() %} +                <h4>{{ "%s - %s" % (host[0], host[1]) }}</h4> +                <table> +                    {% for name, status, image in containers %} +                        <tr> +                            <td>{{ name }}</td> +                            {% if "Up" in status %} +                                <td class=running>{{ status }}</td> +                            {% else %} +                                <td class=notRunning>{{ status }}</td> +                            {% endif %} +                            <td>{{ image }}</td> +                        </tr> +                    {% endfor %} +                </table> +            {% endfor %} +        </ul>      </section> +      <section id="torrents">          <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> -                <tr> -                    <td>active for</td> -                    <td>{{trans["active_for"]}}</td> -                </tr> +                {% for k, v in trans.items() %} +                    <tr> +                        <td>{{ k }}</td> +                        <td>{{ v }}</td> +                    </tr> +                {% endfor %}              </table>          {% endif %} -    <br> -    <a>statistics of some old torrent clients which were shut down recently ;_;</a> -    <br> -    <img src="https://nitter.eda.gay/pic/media%2FFRnF3kcXwAAHE6v.png%3Fname%3Dorig"> -    <img src="https://nitter.eda.gay/pic/media%2FFRnF6I0WUAEq4FD.png%3Fname%3Dorig"> -    <img src="/img/photo_2022-12-07_14-06-03.jpg">      </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 requests</td> -                    <td>{{pihole["blocked"]}}</td> -                </tr> -                <tr> -                    <td>domains in blocklist</td> -                    <td>{{pihole["domains"]}}</td> -                </tr> -                <tr> -                    <td>last updated</td> -                    <td>{{pihole["last_updated"]}}</td> -                </tr> +                {% for k, v in pihole.items() %} +                    <tr> +                        <td>{{ k }}</td> +                        <td>{{ v }}</td> +                    </tr> +                {% endfor %}              </table>          {% endif %}      </section> | 
