diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | app.py | 35 | ||||
| -rw-r--r-- | database.py | 33 | ||||
| -rw-r--r-- | example.conf | 32 | ||||
| -rw-r--r-- | requirements.txt | 5 | ||||
| -rw-r--r-- | services.py | 68 | ||||
| -rw-r--r-- | static/style.css | 108 | ||||
| -rw-r--r-- | templates/discord.html | 5 | ||||
| -rw-r--r-- | templates/index.html | 31 | ||||
| -rw-r--r-- | templates/template.html | 47 | 
10 files changed, 366 insertions, 0 deletions
| @@ -1,3 +1,5 @@ +edaweb.conf +  # Byte-compiled / optimized / DLL files  __pycache__/  *.py[cod] @@ -0,0 +1,35 @@ +import configparser +import database +import flask + +app = flask.Flask(__name__) +CONFIG = configparser.ConfigParser() +CONFIG.read("edaweb.conf") + +def get_template_items(title, db): +    return { +        "links": db.get_header_links(), +        "image": db.get_image("telegrampic"), +        "title": title, +        "articles": db.get_header_articles() +    } + +@app.route("/") +def index(): +    with database.Database() as db: +        return flask.render_template( +            "index.html",  +            **get_template_items("edaweb.co.uk", db) +        ) + +@app.route("/discord") +def discord(): +    with database.Database() as db: +        return flask.render_template( +            "discord.html",  +            **get_template_items("Discord", db), +            discord = CONFIG["discord"]["username"] +        ) + +if __name__ == "__main__": +    app.run(host = "0.0.0.0", debug = True) diff --git a/database.py b/database.py new file mode 100644 index 0000000..05e8a7e --- /dev/null +++ b/database.py @@ -0,0 +1,33 @@ +import pymysql +import app + +class Database: +    def __enter__(self): +        self.__connection = pymysql.connect( +            **app.CONFIG["mysql"], +            charset = "utf8mb4" +        ) +        return self + +    def __exit__(self, type, value, traceback): +        self.__connection.close() + +    def get_header_links(self): +        with self.__connection.cursor() as cursor: +            cursor.execute("SELECT name, link FROM headerLinks ORDER BY name;") +            return cursor.fetchall() + +    def get_image(self, imageName): +        with self.__connection.cursor() as cursor: +            cursor.execute("SELECT alt, url FROM images WHERE imageName = %s;", (imageName, )) +            return cursor.fetchone() + +    def get_header_articles(self): +        with self.__connection.cursor() as cursor: +            cursor.execute("SELECT articleName, link FROM headerArticles;") +            return cursor.fetchall() + + +if __name__ == "__main__": +    with Database() as db: +        print(db.get_header_articles())
\ No newline at end of file diff --git a/example.conf b/example.conf new file mode 100644 index 0000000..bd16037 --- /dev/null +++ b/example.conf @@ -0,0 +1,32 @@ +[mysql] +host = 192.168.0.40 +; port = 3306   ; ConfigParser will parse this as a string (not int) which will cause pymysql to moan +user = webro +passwd = *********** +db = edaweb + +[nitter] +url = 192.168.0.40 +port = 7777 + +[docker] +url = 192.168.0.40 +port = 4550 + +[pihole] +url = 192.168.0.25 + +[qbittorrent] +url = 192.168.0.25 +port = 8080 +user = admin +passwd = *********** + +[transmission] +url = 192.168.0.25 +port = 9091 +user = admin +passwd = *********** + +[discord] +username = @jwnskanzkwk#9757
\ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0fed313 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Flask==1.1.2 +PyMySQL==1.0.2 +docker==4.4.1 +python-qbittorrent==0.4.2 +transmission-clutch
\ No newline at end of file diff --git a/services.py b/services.py new file mode 100644 index 0000000..16268ef --- /dev/null +++ b/services.py @@ -0,0 +1,68 @@ +import qbittorrent +import docker +import clutch +import app +import json + +def humanbytes(B): +   'Return the given bytes as a human friendly KB, MB, GB, or TB string' +   B = float(B) +   KB = float(1024) +   MB = float(KB ** 2) # 1,048,576 +   GB = float(KB ** 3) # 1,073,741,824 +   TB = float(KB ** 4) # 1,099,511,627,776 + +   if B < KB: +      return '{0} {1}'.format(B,'Bytes' if 0 == B > 1 else 'Byte') +   elif KB <= B < MB: +      return '{0:.2f} KB'.format(B/KB) +   elif MB <= B < GB: +      return '{0:.2f} MB'.format(B/MB) +   elif GB <= B < TB: +      return '{0:.2f} GB'.format(B/GB) +   elif TB <= B: +      return '{0:.2f} TB'.format(B/TB) + +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) +    } + +def get_qbit_stats(): +    numtorrents = 0 +    bytes_dl = 0 +    bytes_up = 0 +    qb = qbittorrent.Client('http://%s:%s/' % (app.CONFIG["qbittorrent"]["url"], app.CONFIG["qbittorrent"]["port"])) +    qb.login(username = app.CONFIG["qbittorrent"]["user"], password = app.CONFIG["qbittorrent"]["passwd"]) + +    for torrent in qb.torrents(): +        numtorrents += 1 +        bytes_up += torrent["uploaded"]  +        bytes_dl += torrent["downloaded"] +         +    return { +       "bytes_dl": humanbytes(bytes_dl), +       "bytes_up": humanbytes(bytes_up), +       "num": numtorrents, +       "ratio": bytes_up / bytes_dl +    } + +def get_trans_stats(): +    client = clutch.client.Client( +        address = "http://%s:%s/transmission/rpc" % (app.CONFIG["transmission"]["url"], app.CONFIG["transmission"]["port"]), +        username = app.CONFIG["transmission"]["user"], +        password = app.CONFIG["transmission"]["passwd"] +    ) +    stats = json.loads(client.session.stats().json()) +    return { +       "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"] +    } + + +if __name__ == "__main__": +    print(get_trans_stats())
\ No newline at end of file diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..952d3ca --- /dev/null +++ b/static/style.css @@ -0,0 +1,108 @@ +html { +    background-color: black; +    font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif; +} + +body { +    /* background: linear-gradient(red,orange,yellow,green,blue,indigo,violet); */ +    margin-left: 0px; +    margin-right: 0px; +    margin-bottom: 0px; +    position: relative; +    background: black; +} + +#wrapper { +    background-color: #f1f3f3; +    max-width: 974px; +    min-width: 850px; +    margin: auto; +    margin-top: -10px; +} + +header { +    background-color: #8fbce7; +} + + +#headerflex { +    display: flex; +} + +#headers { +    flex-grow: 1; +} + +header nav { +    flex-grow: 1; +    display: inline; +} + +#links { +    text-align: center; +    font-size: x-small; +} + +header span nav ul { +    background-color: black; +} + +header span nav ul li a { +    color: white; +} + +nav ul { +    margin: 0; +    padding: 0; +} + +nav li { +    display: inline-block; +    list-style-type: none; +} + +nav a { +    text-decoration: none; +    display: block; +    padding: 5px 6px 5px 6px; +    color: black; +} + +#TheTitle { +    text-decoration: none; +    color: black; +} + +#TheTitle h1 { +    padding-left: 6px; +} + +#articles { +    text-align: left; +    background-color: white; +} + +header img { +    max-height: 110px; +} + +body div article { +    padding-left: 6px; +} + +footer { +    background-color: gray; +    padding: 3px; +} + +@media (max-width: 1023px) { +    body { +        margin: 0; +        padding: 0; +    } + +    #wrapper { +        min-width: 100%; +        margin-top: 0; +    } +} diff --git a/templates/discord.html b/templates/discord.html new file mode 100644 index 0000000..b4504a2 --- /dev/null +++ b/templates/discord.html @@ -0,0 +1,5 @@ +{% extends "template.html" %} +{% block content %} +   <p>You can contact me on discord (telegram preferred):</p> +   <h1>{{discord}}</h1> + {% endblock %}
\ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..93138d0 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,31 @@ +{% extends "template.html" %} +{% block content %} +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> +   <p>Haiiiiiiii, this is the index page uwu</p> + {% endblock %}
\ No newline at end of file diff --git a/templates/template.html b/templates/template.html new file mode 100644 index 0000000..d6c1a0b --- /dev/null +++ b/templates/template.html @@ -0,0 +1,47 @@ +<!doctype html> +<html> +    <head> +        <link rel='stylesheet' href="{{url_for('static', filename='style.css')}}"> +    </head> +    <body> +        <div id=wrapper> +            <header> +                <span> +                    <nav id=links> +                        <ul> +                            {% for name, link in links %} +                            <li> +                                <a href={{link}}>{{name}}</a> +                            </li> +                            {% endfor %} +                        </ul> +                    </nav> +                </span>          +                <div id=headerflex> +                    <div id=headers> +                        <a href="/" id=TheTitle><h1>{{title}}</h1></a> +                        <nav id=articles> +                            <ul> +                                {% for name, link in articles %} +                                <li> +                                    <a href={{link}}>{{name}}</a> +                                </li> +                                {% endfor %} +                            </ul> +                        </nav> +                    </div> +                    <a href="/"> +                        <img alt={{image[0]}} src={{image[1]}}> +                    </a>          +                </div> +            </header> +            <article> +                {% block content %} +                {% endblock %} +            </article> +            <footer> +                <p>Web design is my passion</p> +            </footer> +        </div> +    </body> +</html>
\ No newline at end of file | 
