WWW service status tracker

Save ping results

by roundabout, Saturday, 6 April 2024, 16:26:27 (1712420787), pushed by roundabout, Sunday, 7 April 2024, 12:44:08 (1712493848)

Author identity: vlad <vlad.muntoiu@gmail.com>

da0632aae170ad798b2c4128c686c4eddfdded4c

.idea/workspace.xml

@@ -4,11 +4,12 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <option name="autoReloadType" value="SELECTIVE" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              </component>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              <component name="ChangeListManager">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <list default="true" id="411335b4-e813-41ad-9046-18b77b97ee46" name="Changes" comment="More">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <list default="true" id="411335b4-e813-41ad-9046-18b77b97ee46" name="Changes" comment="Endpoint management">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <change beforePath="$PROJECT_DIR$/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/app.py" afterDir="false" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <change beforePath="$PROJECT_DIR$/static/style.css" beforeDir="false" afterPath="$PROJECT_DIR$/static/style.css" afterDir="false" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <change beforePath="$PROJECT_DIR$/templates/app-editor.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/app-editor.html" afterDir="false" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <change beforePath="$PROJECT_DIR$/templates/app.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/app.html" afterDir="false" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                </list>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <option name="SHOW_DIALOG" value="false" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <option name="HIGHLIGHT_CONFLICTS" value="true" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -82,7 +83,15 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <option name="project" value="LOCAL" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <updated>1712409360299</updated>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                </task>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <option name="localTasksCounter" value="3" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <task id="LOCAL-00003" summary="Endpoint management">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="closed" value="true" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <created>1712411232132</created>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="number" value="00003" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="presentableId" value="LOCAL-00003" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="project" value="LOCAL" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <updated>1712411232132</updated>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            </task>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <option name="localTasksCounter" value="4" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <servers />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              </component>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              <component name="Vcs.Log.Tabs.Properties">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -99,6 +108,7 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              <component name="VcsManagerConfiguration">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <MESSAGE value="Initial commit" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <MESSAGE value="More" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <option name="LAST_COMMIT_MESSAGE" value="More" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <MESSAGE value="Endpoint management" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <option name="LAST_COMMIT_MESSAGE" value="Endpoint management" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              </component>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            </project>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

app.py

@@ -1,15 +1,40 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            import datetime
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        import celery
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            import flask
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            from flask_sqlalchemy import SQLAlchemy
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            from flask_bcrypt import Bcrypt
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            from flask_migrate import Migrate
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            from sqlalchemy.orm import declarative_base
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from celery import shared_task
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            import httpx
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            app = flask.Flask(__name__)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        from celery import Celery, Task
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        def celery_init_app(app_) -> Celery:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            class FlaskTask(Task):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                def __call__(self, *args: object, **kwargs: object) -> object:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    with app_.app_context():
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        return self.run(*args, **kwargs)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            celery_app = Celery(app_.name, task_cls=FlaskTask)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            celery_app.config_from_object(app_.config["CELERY"])
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            celery_app.set_default()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            app_.extensions["celery"] = celery_app
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            return celery_app
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        app.config.from_mapping(
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            CELERY=dict(
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                broker_url="redis://localhost:6379",
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                result_backend="redis://localhost:6379"
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            ),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        )
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        celery_app = celery_init_app(app)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            app.config["SQLALCHEMY_DATABASE_URI"] = \
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                "postgresql://echo:1234@localhost:5432/echo"
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            db = SQLAlchemy(app)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -50,43 +75,56 @@ with app.app_context():

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    address = db.Column(db.String(2048), nullable=False)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    name = db.Column(db.String(64), nullable=False)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    comment = db.Column(db.String(2048), nullable=True)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                ping_interval = db.Column(db.Integer, default=300, nullable=False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    application = db.relationship("Application", back_populates="endpoints")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                def __init__(self, application, name, address, comment=""):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                def __init__(self, application, name, address, ping_interval, comment=""):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        self.application_id = application.id
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        self.name = name
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        self.address = address
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        self.comment = comment
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    self.ping_interval = ping_interval
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            Base = declarative_base()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            class Status(Base):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                __table_args = (
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        "timescaledb_hypertable": {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            "time_column_name": "time",
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        },
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                )
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                __tablename__ = "status"
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                id = db.Column(db.Integer, unique=True, nullable=False, autoincrement=True)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            class Status(db.Model):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                id = db.Column(db.Integer, unique=True, nullable=False, autoincrement=True, primary_key=True, default=0)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    endpoint_id = db.Column(db.Integer, nullable=False)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                time = db.Column(db.DateTime, index=True, default=datetime.datetime.utcnow, primary_key=True)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                time = db.Column(db.DateTime, default=datetime.datetime.utcnow)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    status = db.Column(db.SmallInteger, nullable=False)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                endpoint = db.relationship("Endpoint", back_populates="statuses")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                def __init__(self, endpoint, status):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    self.endpoint_id = endpoint.id
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                def __init__(self, endpoint_id, status):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    self.endpoint_id = endpoint_id
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        self.status = status
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        def ping(endpoint):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            url = endpoint.address
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            response = httpx.get(url)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            return response.status_code
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            @celery.shared_task(name="ping")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def ping(id, address, next_ping):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                url = address
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                print(f"Pinging {url}")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                response = httpx.get(url, verify=False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                reading = Status(id, response.status_code)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                db.session.add(reading)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                db.session.commit()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                # Schedule the next ping
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                ping.apply_async(args=(id, address, next_ping), countdown=next_ping)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            @celery.shared_task(name="ping_all")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            def ping_all():
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                endpoints = Endpoint.query.all()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                for endpoint in endpoints:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    ping.delay(endpoint.id, endpoint.address, endpoint.ping_interval)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        task = ping_all.delay()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        print()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        print()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        print(task)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        print()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        print()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            @app.context_processor
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -180,11 +218,6 @@ def signup_post():

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                return flask.redirect("/", code=303)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        @app.route("/timeline/<endpoint_id>")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        def info(endpoint_id):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            return flask.render_template("timeline.html", endpoint=endpoint_id)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            @app.route("/app/<int:app_id>/")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            def app_info(app_id):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                app_ = db.session.get(Application, app_id)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -223,7 +256,9 @@ def app_add_endpoint(app_id):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                endpoint = Endpoint(app_,
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                    flask.request.form["name"],
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                    flask.request.form["url"],
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                300,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                    flask.request.form["comment"])
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                db.session.add(endpoint)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                db.session.commit()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                return flask.redirect(f"/app/{app_id}/edit", code=303)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

static/style.css

@@ -176,14 +176,14 @@ input[type="password"]:not(:placeholder-shown) {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                font-family: "Lexend Exa", "Lexend", sans-serif;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .app-card {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .app-card, .endpoint-card {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                width: 100%;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                border: 2px solid #000000aa;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                padding: 0.75rem;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                border-radius: 24px;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .app-card h2 {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        :is(.app-card, .endpoint-card) h2 {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                margin-top: 0;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                font-size: 1.45rem;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                font-weight: 750;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -249,7 +249,7 @@ iconify-icon {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                display: inline-block;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .quiet-link:has(.app-card) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .quiet-link:has(:is(.app-card, .endpoint-card)) {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                display: block;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                border-radius: 24px;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -264,7 +264,7 @@ textarea {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                appearance: none;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        #endpoint-editor {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        #endpoint-editor, #endpoint-list {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                display: flex;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                gap: 2rem;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                width: 100%;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -279,8 +279,8 @@ textarea {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                justify-content: space-around;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .side-by-side > button {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            flex: 1 1 25%;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .side-by-side > button.extend {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            flex: 1 1 100%;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            .danger-button {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -291,3 +291,8 @@ textarea {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            .danger-button:hover {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                background: #D32F2F;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        nav a:focus {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            box-shadow: none;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            text-decoration: underline;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

templates/app-editor.html

@@ -10,8 +10,10 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <input type="url" name="url" placeholder="Ping address" value="{{ endpoint.address }}">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <textarea name="comment" placeholder="Comment" rows="4">{{ endpoint.comment }}</textarea>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <div class="side-by-side">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                <button type="submit">Apply changes</button>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                <button type="submit" name="delete" value="delete" class="danger-button">Delete</button>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                <button type="submit" class="extend">Apply changes</button>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                <button type="submit" name="delete" value="delete" class="danger-button">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    <iconify-icon icon="mdi:trash-can">Delete</iconify-icon>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                </button>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                </div>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            </form>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        {% endfor %}
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

templates/app.html

@@ -9,5 +9,14 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            Manage endpoints
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        </a>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    {% endif %}
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                <div id="endpoint-list">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    {% for endpoint in app.endpoints %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        <div class="endpoint-card">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            <h2>{{ endpoint.name }}</h2>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            <p>{{ endpoint.comment }}</p>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        </div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    {% endfor %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                </div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                </main>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            {% endblock %}