Compare commits

...

6 Commits

23 changed files with 80 additions and 36 deletions

View File

@@ -9,9 +9,6 @@ RUN pip install --no-cache-dir -r requirements.txt
COPY . . COPY . .
RUN chmod +x ./entrypoint.sh
ENV FLASK_APP=app.py ENV FLASK_APP=app.py
ENTRYPOINT ["./entrypoint.sh"] CMD ["python", "app.py"]
CMD []

28
app.py
View File

@@ -1,35 +1,23 @@
# import requests as r # import requests as r
from flask import jsonify, Flask, render_template, send_file from flask import jsonify, render_template, send_file
from poll_services import start_async_loop from poll_services import start_async_loop
from mem import services from mem import services, app, db
import threading import threading
from flask_sqlalchemy import SQLAlchemy from flask_migrate import upgrade, stamp
from flask_migrate import Migrate, init, upgrade
from pathlib import Path from pathlib import Path
# Flask app to serve status
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
db = SQLAlchemy(app=app)
migration = Migrate(app=app, db=db)
# Init and upgrade # Init and upgrade
with app.app_context(): with app.app_context():
# Check if DB file or migrations folder is missing # Check if DB file is missing
if not ( if not (Path("./instance/app.db").is_file()):
Path("./instance/app.db").is_file() and Path("./migrations").is_dir() with app.app_context():
): db.create_all()
init() stamp()
# Upgrade db if any new migrations exist # Upgrade db if any new migrations exist
upgrade() upgrade()
class logs(db.Model):
id = db.Column(db.Integer, primary_key=True)
dateCreated = db.Column(db.DateTime, nullable=False)
@app.route("/") @app.route("/")
def homepage(): def homepage():
return render_template("home.html", services=services) return render_template("home.html", services=services)

View File

@@ -1,8 +0,0 @@
#!/bin/sh
set -ex
#echo "Running database migrations..."
#flask db upgrade
echo "Starting Flask app..."
python app.py

View File

@@ -1,4 +1,7 @@
from typing import Any, Optional from typing import Any, Optional
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
class service: class service:
@@ -78,3 +81,10 @@ services: list[service] = [
id=11, url="https://unifi.local/", label="Unifi Server", public=False id=11, url="https://unifi.local/", label="Unifi Server", public=False
), ),
] ]
# Flask app to serve status
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///app.db"
db = SQLAlchemy(app=app)
migration = Migrate(app=app, db=db)

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 191 B

After

Width:  |  Height:  |  Size: 191 B

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 680 B

After

Width:  |  Height:  |  Size: 680 B

View File

Before

Width:  |  Height:  |  Size: 550 B

After

Width:  |  Height:  |  Size: 550 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 389 B

After

Width:  |  Height:  |  Size: 389 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

Before

Width:  |  Height:  |  Size: 950 B

After

Width:  |  Height:  |  Size: 950 B

View File

Before

Width:  |  Height:  |  Size: 642 B

After

Width:  |  Height:  |  Size: 642 B

View File

@@ -0,0 +1,32 @@
"""empty message
Revision ID: d7d380435347
Revises:
Create Date: 2025-09-02 08:43:16.682424
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd7d380435347'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('log',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('dateCreated', sa.DateTime(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('log')
# ### end Alembic commands ###

View File

@@ -0,0 +1,12 @@
from mem import db
from datetime import datetime, timezone
class log(db.Model):
id = db.Column(db.Integer, primary_key=True)
dateCreated = db.Column(db.DateTime, nullable=False)
def __init__(self):
super().__init__()
self.dateCreated = datetime.now(timezone.utc)

View File

@@ -1,10 +1,12 @@
from mem import services, service from mem import services, service, db, app
import httpx import httpx
import asyncio import asyncio
import time import time
from models import log
from sqlalchemy.orm import sessionmaker
async def check_service(client: httpx.AsyncClient, s: service): async def check_service(client: httpx.AsyncClient, s: service) -> log:
try: try:
before = time.perf_counter() before = time.perf_counter()
match s.ping_type: match s.ping_type:
@@ -22,7 +24,6 @@ async def check_service(client: httpx.AsyncClient, s: service):
) )
case _: case _:
raise httpx.HTTPError("Unknown ping type") raise httpx.HTTPError("Unknown ping type")
after = time.perf_counter() after = time.perf_counter()
s.set_error(None) s.set_error(None)
s.set_online(r.status_code == 200) s.set_online(r.status_code == 200)
@@ -33,6 +34,7 @@ async def check_service(client: httpx.AsyncClient, s: service):
s.set_online(False) s.set_online(False)
s.set_status(None) s.set_status(None)
s.set_ping(None) s.set_ping(None)
return log()
def start_async_loop(): def start_async_loop():
@@ -44,14 +46,25 @@ def start_async_loop():
async def update_services(loop: asyncio.AbstractEventLoop): async def update_services(loop: asyncio.AbstractEventLoop):
print("Starting service updates...") print("Starting service updates...")
with app.app_context():
WorkerSession = sessionmaker(bind=db.engine)
async with ( async with (
httpx.AsyncClient() as public_client, httpx.AsyncClient() as public_client,
httpx.AsyncClient(verify=False) as local_client, httpx.AsyncClient(verify=False) as local_client,
): ):
while True: while True:
session = WorkerSession()
tasks = [ tasks = [
check_service(public_client if s.public else local_client, s) check_service(public_client if s.public else local_client, s)
for s in services for s in services
] ]
await asyncio.gather(*tasks) logs = await asyncio.gather(*tasks)
try:
session.add_all(logs)
session.commit()
except Exception as e:
session.rollback()
raise e
finally:
session.close()
await asyncio.sleep(2) await asyncio.sleep(2)