Compare commits

...

10 Commits

8 changed files with 122 additions and 28 deletions

7
app.py
View File

@@ -1,5 +1,5 @@
# import requests as r
from flask import jsonify, Flask, render_template
from flask import jsonify, Flask, render_template, send_file
from poll_services import start_async_loop
from mem import services
import threading
@@ -19,6 +19,11 @@ def status():
return jsonify([s.to_dict() for s in services])
@app.route("/favicon.svg")
def favicon():
return send_file("/static/favicon.svg")
# Only run if directly running file
if __name__ == "__main__":

View File

@@ -2,7 +2,7 @@ from typing import Any, Optional
class service:
id = int
id: int
url: str
status: Optional[int]
online: bool
@@ -10,6 +10,7 @@ class service:
error: Optional[str]
ping: Optional[int]
icon_filetype: str
ping_type: int
def __init__(
self,
@@ -18,11 +19,13 @@ class service:
label: str = "",
public: bool = True,
icon_filetype: str = "svg",
ping_type: int = 0,
):
self.id = id
self.url = url
self.public = public
self.label = label
self.ping_type = ping_type
self.online = False
self.status = None
@@ -41,6 +44,7 @@ class service:
"label": self.label,
"icon_filetype": self.icon_filetype,
"id": self.id,
"ping_type": self.ping_type,
}
def set_status(self, status: Optional[int]):
@@ -58,13 +62,19 @@ class service:
services: list[service] = [
service(0, "https://git.ihatemen.uk/", "Gitea"),
service(1, "https://plex.ihatemen.uk/", "Plex"),
service(1, "https://plex.ihatemen.uk/", "Plex", ping_type=1),
service(2, "https://truenas.local/", "TrueNAS", False),
service(3, "https://cloud.ihatemen.uk/", "NextCloud"),
service(4, "https://request.ihatemen.uk/", "Overseerr"),
service(5, "https://id.ihatemen.uk/", "PocketID"),
service(6, "http://tautulli.local", "Tautulli", False),
service(7, "https://transmission.local", "Transmission", False),
service(8, "https://vault.ihatemen.uk", "Vault Warden"),
service(9, "https://nginx.local", "Nginx (NPM)", False),
service(6, "https://tautulli.local/", "Tautulli", False),
service(
7, "https://transmission.local/", "Transmission", False, ping_type=1
),
service(8, "https://vault.ihatemen.uk/", "Vault Warden"),
service(9, "https://nginx.local/", "Nginx (NPM)", False),
service(10, "https://app.ihatemen.uk/", "Kcal Counter"),
service(
id=11, url="https://unifi.local/", label="Unifi Server", public=False
),
]

View File

@@ -7,11 +7,22 @@ import time
async def check_service(client: httpx.AsyncClient, s: service):
try:
before = time.perf_counter()
r = await client.get(
url=s.url,
follow_redirects=True,
timeout=1,
)
match s.ping_type:
case 0:
r = await client.head(
url=s.url,
follow_redirects=True,
timeout=1,
)
case 1:
r = await client.get(
url=s.url,
follow_redirects=True,
timeout=1,
)
case _:
raise httpx.HTTPError("Unknown ping type")
after = time.perf_counter()
s.set_error(None)
s.set_online(r.status_code == 200)
@@ -33,9 +44,10 @@ def start_async_loop():
async def update_services(loop: asyncio.AbstractEventLoop):
print("Starting service updates...")
async with httpx.AsyncClient() as public_client, httpx.AsyncClient(
verify=False
) as local_client:
async with (
httpx.AsyncClient() as public_client,
httpx.AsyncClient(verify=False) as local_client,
):
while True:
tasks = [
check_service(public_client if s.public else local_client, s)

23
static/favicon.svg Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="250px" height="250px" viewBox="-77.997 -77.998 250 250" enable-background="new -77.997 -77.998 250 250"
xml:space="preserve">
<circle fill="#009090" cx="47.003" cy="47.002" r="121.834"/>
<g>
<path fill="#FFFFFF" d="M135.518,28.755c0,5.432-0.891,10.791-2.618,15.942c-8.112,36.712-78.279,81.124-81.264,83.017
c-0.934,0.581-1.978,0.884-3.046,0.884c-1.063,0-2.125-0.271-3.06-0.884c-0.8-0.521-20.569-12.996-40.611-30.144
c-2.4-2.071-2.653-5.639-0.639-8.026c2.062-2.37,5.627-2.661,8.031-0.645c14.94,12.766,30.039,23.081,36.308,27.238
c21.07-13.738,67.592-48.691,73.293-74.471c1.489-4.553,2.164-8.695,2.164-12.899c0-14.636-7.967-28.126-20.797-35.195
c-16.387-9.091-38.32-4.898-50.309,9.551c-2.151,2.61-6.583,2.61-8.778,0C32.171-11.335,10.254-15.495-6.107-6.441
c-12.871,7.083-20.839,20.567-20.839,35.187c0,4.177,0.707,8.335,2.025,12.354c0.845,3.76,2.462,7.437,4.52,11.25h33.237
L24.25,26.116c0.978-2.245,3.313-3.657,5.714-3.405c2.447,0.214,4.487,1.973,5.032,4.363L43.4,62.599l10.868-17.824
c1.024-1.693,2.869-2.727,4.86-2.727h20.629c3.137,0,5.689,2.541,5.689,5.696c0,3.137-2.553,5.693-5.689,5.693H62.323
L45.948,80.335c-1.044,1.714-2.885,2.739-4.842,2.739c-0.311,0-0.611-0.025-0.89-0.067c-2.293-0.369-4.101-2.062-4.652-4.306
l-7.678-32.358l-6.068,13.967c-0.906,2.098-2.96,3.423-5.226,3.423h-66.41c-3.117,0-5.694-2.55-5.694-5.693
c0-3.138,2.577-5.694,5.694-5.694h16.698c-1.185-2.826-2.142-5.57-2.735-8.224c-1.589-4.608-2.449-9.975-2.449-15.379
c0-18.779,10.213-36.071,26.716-45.163c19.114-10.573,44.406-7.249,60.202,7.594c15.754-14.845,41.027-18.167,60.175-7.594
C125.272-7.339,135.518,9.964,135.518,28.755z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

27
static/icons/10.svg Normal file
View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1125.628 1125.628" xml:space="preserve">
<g>
<path d="M562.812,0.002C252.476,0.002,0,252.479,0,562.814s252.476,562.812,562.812,562.812
c310.34,0,562.817-252.476,562.817-562.812S873.152,0.002,562.812,0.002z M309.189,739.263l-68.974-101h-17.735v101h-70v-357h70
v203h15.889l57.901-93h77.963l-79.808,111.736l92.036,135.264H309.189z M468.184,672.88c7.299,13.589,20.325,20.382,38.317,20.382
c11.995,0,21.792-3.329,29.023-10.286c7.226-6.952,11.026-14.712,11.026-27.712h61.131l0.69,1.237
c0.612,25.224-8.88,46.258-28.489,63.246c-19.605,16.997-43.942,25.452-73.007,25.452c-37.218,0-65.962-11.781-86.11-35.309
c-20.144-23.529-30.283-53.763-30.283-90.671v-6.925c0-36.753,10.102-66.968,30.169-90.652
c20.071-23.68,48.745-35.524,85.958-35.524c30.76,0,55.57,8.766,74.412,26.297c18.833,17.531,27.954,41.73,27.342,70.334
l-0.453,2.516H546.55c0-14-3.54-24.775-10.611-33.312c-7.075-8.533-16.837-13.365-29.298-13.365
c-17.837,0-31.158,6.628-38.457,20.446c-7.308,13.818-11.703,31.349-11.703,53.151v6.911
C456.481,641.362,460.876,659.29,468.184,672.88z M793.142,739.263c-2.462-4-4.582-11.157-6.345-17.465
c-1.772-6.304-3.038-12.499-3.805-19.113c-6.925,12.15-16.033,22.354-27.338,30.348c-11.301,7.998-24.798,12.061-40.484,12.061
c-26.141,0-46.285-6.691-60.432-20.148c-14.151-13.457-21.222-31.78-21.222-54.998c0-24.456,9.414-43.221,28.256-56.683
c18.833-13.452,46.327-20.003,82.467-20.003h39.242v-20.18c0-11.995-3.974-21.3-10.282-27.914
c-6.303-6.609-16.019-9.917-28.32-9.917c-10.922,0-19.545,2.65-25.465,7.957c-5.92,5.303-8.982,12.648-8.982,22.026l-65.101-0.228
l-0.259-1.384c-1.073-21.066,8.063-39.251,27.44-54.553c19.377-15.302,44.822-22.953,76.349-22.953
c29.832,0,54.075,7.578,72.684,22.72c18.605,15.151,27.938,36.716,27.938,64.703v103.113c0,11.689,0.854,22.156,2.622,32.461
c1.768,10.3,4.55,21.149,8.396,30.149H793.142z M902.481,739.263v-357h70v357H902.481z"/>
<path d="M711.712,640.846c-7.382,7.153-11.072,16.229-11.072,26.379c0,8.304,2.768,15.211,8.304,20.285
c5.536,5.075,13.069,7.717,22.606,7.717c11.84,0,23.195-2.865,32.422-8.707c9.227-5.847,14.509-12.558,19.509-20.246v-37.012
h-39.242C729.933,629.263,719.093,633.698,711.712,640.846z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

7
static/icons/11.svg Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg xmlns="http://www.w3.org/2000/svg"
aria-label="Ubiquiti" role="img"
viewBox="0 0 512 512"><rect
width="512" height="512"
rx="15%"
fill="#399cdb"/><path d="M112 94v18h18V94h-18zm288 0c-82 0-90 31-90 61v172a147 147 0 01-3 28c43-9 72-36 86-82l7-23V94zm-234 18v18h18v-18h-18zm-18 18v18h18v-18h-18zm36 9v18h18v-18h-18zm-72 4v147c0 73 53 128 144 128 0 0-54-30-54-91V197h-18v66h-18v-39h-18v17h-18v-98h-18zm54 18v18h18v-18h-18zm-18 27v18h18v-18h-18zm252 87c-19 64-65 92-131 89-24-1-43-7-57-16 10 42 46 63 48 64l10 6c82-5 130-59 130-128v-15z" fill="#ffffff"/></svg>

After

Width:  |  Height:  |  Size: 680 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -2,13 +2,11 @@
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8">
<title>Debug Divs</title>
<meta ame="viewport" content="width=device-width, initial-scale=1" charset=" UTF-8">
<title>Dashboard</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
crossorigin="anonymous"></script>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg">
</head>
<body id="main_body" class="m-2 bg-light-subtle d-flex flex-wrap justify-content-center">
@@ -27,7 +25,7 @@
})
.catch(error => console.error("Error fetching data", error))
.finally(() => {
setTimeout(fetchData, 1000); // schedule next request after 1 second
setTimeout(fetchData, 5000); // schedule next request after 5 seconds
});
}
@@ -39,13 +37,16 @@
<a href="${s.url}" class="d-block text-body text-decoration-none m-2 border border-3 ${s.online ? 'border-success' : 'border-danger'}" style="width: 200px">
<div class="bg-body-tertiary d-flex flex-column align-items-center">
<div class="bg-dark w-100">
<h4 class="text-center text-truncate m-0" style="font-size: 1.5rem;">${s.label}</h4>
<h4 class="text-center text-truncate m-0 p-1" style="font-size: 1.9rem;">${s.label}</h4>
</div>
<div class="position-relative ratio ratio-1x1">
<img src="static/icons/${s.id}.${s.icon_filetype}" class="img-fluid">
${s.public ? `` : `<div>
<img src='static/lock.svg' class='img-fluid position-absolute bottom-0 end-0 w-25'>
</div>` }
<div class="d-flex justify-content-center align-items-center">
<img src="static/icons/${s.id}.${s.icon_filetype}" class="img-fluid w-75">
</div>
<div>
${s.public ? `` : `<img src='static/lock.svg' class='img-fluid position-absolute bottom-0 end-0 w-25'>`}
<div class="position-absolute bottom-0 text-body bg-dark bg-opacity-75 px-1 rounded">${s.online ? s.ping + "ms" : ""}</div>
</div>
</div>
</div>
</a>
@@ -53,7 +54,10 @@
}
fetchData(); // start the loop
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
crossorigin="anonymous"></script>
</html>