diff --git a/app.py b/app.py index 9aee422..72874a9 100644 --- a/app.py +++ b/app.py @@ -1,18 +1,11 @@ # 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 mem import services +from mem import services, app import threading -from flask_sqlalchemy import SQLAlchemy -from flask_migrate import Migrate, init, upgrade +from flask_migrate import init, upgrade 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 with app.app_context(): diff --git a/mem/__init__.py b/mem/__init__.py index 45b3540..07cdf0a 100644 --- a/mem/__init__.py +++ b/mem/__init__.py @@ -1,4 +1,7 @@ from typing import Any, Optional +from flask import Flask +from flask_sqlalchemy import SQLAlchemy +from flask_migrate import Migrate class service: @@ -78,3 +81,10 @@ services: list[service] = [ 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) diff --git a/static/favicon.svg b/mem/static/favicon.svg similarity index 100% rename from static/favicon.svg rename to mem/static/favicon.svg diff --git a/static/icons/0.svg b/mem/static/icons/0.svg similarity index 100% rename from static/icons/0.svg rename to mem/static/icons/0.svg diff --git a/static/icons/1.svg b/mem/static/icons/1.svg similarity index 100% rename from static/icons/1.svg rename to mem/static/icons/1.svg diff --git a/static/icons/10.svg b/mem/static/icons/10.svg similarity index 100% rename from static/icons/10.svg rename to mem/static/icons/10.svg diff --git a/static/icons/11.svg b/mem/static/icons/11.svg similarity index 100% rename from static/icons/11.svg rename to mem/static/icons/11.svg diff --git a/static/icons/2.svg b/mem/static/icons/2.svg similarity index 100% rename from static/icons/2.svg rename to mem/static/icons/2.svg diff --git a/static/icons/3.svg b/mem/static/icons/3.svg similarity index 100% rename from static/icons/3.svg rename to mem/static/icons/3.svg diff --git a/static/icons/4.svg b/mem/static/icons/4.svg similarity index 100% rename from static/icons/4.svg rename to mem/static/icons/4.svg diff --git a/static/icons/5.svg b/mem/static/icons/5.svg similarity index 100% rename from static/icons/5.svg rename to mem/static/icons/5.svg diff --git a/static/icons/6.svg b/mem/static/icons/6.svg similarity index 100% rename from static/icons/6.svg rename to mem/static/icons/6.svg diff --git a/static/icons/7.svg b/mem/static/icons/7.svg similarity index 100% rename from static/icons/7.svg rename to mem/static/icons/7.svg diff --git a/static/icons/8.svg b/mem/static/icons/8.svg similarity index 100% rename from static/icons/8.svg rename to mem/static/icons/8.svg diff --git a/static/icons/9.svg b/mem/static/icons/9.svg similarity index 100% rename from static/icons/9.svg rename to mem/static/icons/9.svg diff --git a/static/lock.svg b/mem/static/lock.svg similarity index 100% rename from static/lock.svg rename to mem/static/lock.svg diff --git a/static/no_access.svg b/mem/static/no_access.svg similarity index 100% rename from static/no_access.svg rename to mem/static/no_access.svg diff --git a/templates/home.html b/mem/templates/home.html similarity index 100% rename from templates/home.html rename to mem/templates/home.html diff --git a/migrations/versions/d7d380435347_.py b/migrations/versions/d7d380435347_.py new file mode 100644 index 0000000..f2efb2e --- /dev/null +++ b/migrations/versions/d7d380435347_.py @@ -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 ### diff --git a/models.py b/models.py index 7558197..0535df8 100644 --- a/models.py +++ b/models.py @@ -1,6 +1,12 @@ -from app import db +from mem import db +from datetime import datetime, timezone -class logs(db.Model): +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) diff --git a/poll_services.py b/poll_services.py index 0e285e3..1b19c62 100644 --- a/poll_services.py +++ b/poll_services.py @@ -1,10 +1,12 @@ -from mem import services, service +from mem import services, service, db, app import httpx import asyncio 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: before = time.perf_counter() match s.ping_type: @@ -22,7 +24,6 @@ async def check_service(client: httpx.AsyncClient, s: service): ) case _: raise httpx.HTTPError("Unknown ping type") - after = time.perf_counter() s.set_error(None) 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_status(None) s.set_ping(None) + return log() def start_async_loop(): @@ -44,14 +46,25 @@ def start_async_loop(): async def update_services(loop: asyncio.AbstractEventLoop): print("Starting service updates...") + with app.app_context(): + WorkerSession = sessionmaker(bind=db.engine) async with ( httpx.AsyncClient() as public_client, httpx.AsyncClient(verify=False) as local_client, ): while True: + session = WorkerSession() tasks = [ check_service(public_client if s.public else local_client, s) 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)