WWW service status tracker

By using this site, you agree to have cookies stored on your device, strictly for functional purposes, such as storing your session and preferences.

Dismiss

Do it

roundabout,
created on Sunday, 7 April 2024, 04:40:24 (1712464824), received on Sunday, 7 April 2024, 12:44:08 (1712493848)
Author identity: vlad <vlad.muntoiu@gmail.com>

96c9bc1fc10c421a0983dff39a702d0fc3b42ba4

.idea/workspace.xml

@@ -4,7 +4,7 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <option name="autoReloadType" value="SELECTIVE" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              </component>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              <component name="ChangeListManager">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <list default="true" id="411335b4-e813-41ad-9046-18b77b97ee46" name="Changes" comment="Endpoint management">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <list default="true" id="411335b4-e813-41ad-9046-18b77b97ee46" name="Changes" comment="Save ping results">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <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" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -91,7 +91,15 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <option name="project" value="LOCAL" />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                  <updated>1712411232132</updated>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                </task>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <option name="localTasksCounter" value="4" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <task id="LOCAL-00004" summary="Save ping results">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="closed" value="true" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <created>1712420788013</created>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="number" value="00004" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="presentableId" value="LOCAL-00004" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <option name="project" value="LOCAL" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                              <updated>1712420788013</updated>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            </task>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            <option name="localTasksCounter" value="5" />
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                <servers />
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              </component>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                              <component name="Vcs.Log.Tabs.Properties">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -109,6 +117,7 @@

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

app.py

@@ -2,6 +2,7 @@ import datetime

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            import celery
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            import flask
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        import sqlalchemy
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            from flask_sqlalchemy import SQLAlchemy
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            from flask_bcrypt import Bcrypt
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            from flask_migrate import Migrate
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -37,6 +38,11 @@ celery_app = celery_init_app(app)

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            app.config["SQLALCHEMY_DATABASE_URI"] = \
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                "postgresql://echo:1234@localhost:5432/echo"
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        app.config["SQLALCHEMY_ENGINE_OPTIONS"] = {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            "connect_args": {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                "options": "-c timezone=utc"
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            db = SQLAlchemy(app)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            bcrypt = Bcrypt(app)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            migrate = Migrate(app, db)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -76,8 +82,10 @@ with app.app_context():

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    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)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                buggy = db.Column(db.Boolean, default=False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    application = db.relationship("Application", back_populates="endpoints")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                statuses = db.relationship("Status", back_populates="endpoint", lazy="dynamic")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    def __init__(self, application, name, address, ping_interval, comment=""):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        self.application_id = application.id
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -88,11 +96,13 @@ with app.app_context():

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                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)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                id = db.Column(db.Integer, nullable=False, autoincrement=True, primary_key=True)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                endpoint_id = db.Column(db.Integer, db.ForeignKey("endpoint.id"), nullable=False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    time = db.Column(db.DateTime, default=datetime.datetime.utcnow)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    status = db.Column(db.SmallInteger, nullable=False)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                buggy = db.Column(db.Boolean, default=False)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                endpoint = db.relationship("Endpoint", back_populates="statuses")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    def __init__(self, endpoint_id, status):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        self.endpoint_id = endpoint_id
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -218,10 +228,37 @@ def signup_post():

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                return flask.redirect("/", code=303)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        # UTC filter
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        @app.template_filter("utc")
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        def utc_filter(timestamp):
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            return datetime.datetime.utcfromtimestamp(timestamp)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            @app.route("/app/<int:app_id>/")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            def app_info(app_id):
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                app_ = db.session.get(Application, app_id)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            return flask.render_template("app.html", app=app_)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            time_slices = [(datetime.datetime.utcnow() - datetime.timedelta(seconds=int(flask.request.args.get("bar_duration", 30)) * 60 * (i+1)),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            datetime.datetime.utcnow() - datetime.timedelta(seconds=int(flask.request.args.get("bar_duration", 30)) * i))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                           for i in range(int(flask.request.args.get("time_period", 30)) // int(flask.request.args.get("bar_duration", 1)))]
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            slice_results = []
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            for slice_ in time_slices:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                slice_results.append(db.session.query(Status).filter(
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    sqlalchemy.and_(Status.endpoint.has(application_id=app_id),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    Status.time >= slice_[0],
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    Status.time < slice_[1])).all())
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            return flask.render_template("app.html", app=app_, sorted=sorted, list=list,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                         sorting=lambda x: x.time, reverse=True,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                         is_ok=lambda x: all(status.status in (200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 302, 304, 307)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                                             for status in x), and_=sqlalchemy.and_,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                         bar_duration=int(flask.request.args.get("bar_duration", 30)), int=int, Status=Status,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                         time_period=int(flask.request.args.get("time_period", 1440)),
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                         now=round(datetime.datetime.utcnow().timestamp()), func=sqlalchemy.func,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                         reversed=reversed, fromtimestamp=datetime.datetime.utcfromtimestamp,
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                         slices=slice_results)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            @app.route("/app/<int:app_id>/edit/")
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -238,11 +275,15 @@ def endpoint_edit(app_id, endpoint_id):

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    flask.abort(403)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                endpoint = db.session.get(Endpoint, endpoint_id)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                if flask.request.form.get("delete") == "delete":
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                statuses = db.session.query(Status).filter_by(endpoint_id=endpoint_id).all()
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                for status in statuses:
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    db.session.delete(status)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    db.session.delete(endpoint)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    db.session.commit()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                else:
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    endpoint.name = flask.request.form["name"]
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    endpoint.address = flask.request.form["url"]
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                endpoint.ping_interval = max(15, int(flask.request.form["ping_interval"]))
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    endpoint.comment = flask.request.form["comment"]
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    db.session.commit()
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                return flask.redirect(f"/app/{app_id}/edit", code=303)
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -256,9 +297,12 @@ def app_add_endpoint(app_id):

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

static/style.css

@@ -191,6 +191,7 @@ input[type="password"]:not(:placeholder-shown) {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            .app-uptime {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                display: flex;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            flex-flow: row-reverse nowrap;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                overflow: hidden;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                border-radius: calc(24px - 0.75rem);
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -216,6 +217,7 @@ input[type="password"]:not(:placeholder-shown) {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                background: #546E7A;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                height: 2rem;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                flex: 1 0 auto;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            outline: 1px solid #ffffff;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            .uptime-bar-ok {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -275,11 +277,11 @@ textarea {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            .side-by-side {
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                display: flex;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                gap: 1rem;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            align-items: stretch;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            align-items: center;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                justify-content: space-around;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .side-by-side > button.extend {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .extend {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                flex: 1 1 100%;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -296,3 +298,18 @@ nav a:focus {

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                box-shadow: none;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                text-decoration: underline;
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                            }
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        .horizontal-form {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            display: flex;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            align-items: center;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            gap: 1rem;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        label {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            color: #00796B;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            display: block;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        label > input {
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            width: 100%;
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        }
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

templates/app-editor.html

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

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            <form class="stacked-form" method="post" action="/app/{{ app.id }}/edit/{{ endpoint.id }}">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <input type="text" name="name" placeholder="Name" value="{{ endpoint.name }}">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <input type="url" name="url" placeholder="Ping address" value="{{ endpoint.address }}">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            <div class="side-by-side">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                <input class="extend" type="number" name="ping_interval" placeholder="Interval (seconds)" value="{{ endpoint.ping_interval }}" step="1" min="15">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                seconds
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            </div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <textarea name="comment" placeholder="Comment" rows="4">{{ endpoint.comment }}</textarea>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <div class="side-by-side">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                    <button type="submit" class="extend">Apply changes</button>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        

@@ -22,6 +26,10 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    <form class="stacked-form" method="post" action="/app/{{ app.id }}/add-endpoint">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        <input type="text" name="name" placeholder="Name">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        <input type="url" name="url" placeholder="Ping address">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    <div class="side-by-side">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        <input class="extend" type="number" name="ping_interval" placeholder="Interval (seconds)" value="300" step="1" min="15">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        seconds
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    </div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        <textarea name="comment" placeholder="Comment" rows="4"></textarea>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        <button type="submit">Add</button>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    </form>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                            
                                

templates/app.html

@@ -9,12 +9,47 @@

                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            Manage endpoints
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        </a>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    {% endif %}
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                <form style="margin-bottom: 1em;" class="horizontal-form">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    <label class="extend">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        Interval duration (minutes)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        <input type="number" name="bar_duration" step="1" value="{{ bar_duration }}">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    </label>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    <label class="extend">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        Time period (minutes)
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                        <input type="number" name="time_period" step="1" value="{{ time_period }}">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    </label>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                    <button type="submit">Change</button>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                </form>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    <div id="endpoint-list">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        {% for endpoint in app.endpoints %}
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            <div class="endpoint-card">
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <h2>{{ endpoint.name }}</h2>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                                <p>{{ endpoint.comment }}</p>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            <div class="app-uptime">
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                        {% set slice_size = bar_duration * 60 %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                        {% set shown_seconds = 3600 %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                        {% set num_slices = int(shown_seconds // slice_size) %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                        {% for i in range(num_slices) %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                            {% set slice_statuses = endpoint.statuses.filter(Status.time.between(fromtimestamp(now - i*slice_size), fromtimestamp(now - i*slice_size + slice_size))) %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                            {% if not slice_statuses.count() %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                                <div class="uptime-bar"></div>-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                            {% elif is_ok(slice_statuses) %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                                <div class="uptime-bar uptime-bar-ok"></div>-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                            {% else %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                                <div class="uptime-bar uptime-bar-down"></div>-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                            {% endif %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                            {{ slice_statuses.all() }}<br>-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                        <!--                        {% endfor %}-->
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                {% for slice in slices %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    {% if not slice %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                        <div class="uptime-bar"></div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    {% elif is_ok(slice) %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                        <div class="uptime-bar uptime-bar-ok"></div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    {% else %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                        <div class="uptime-bar uptime-bar-down"></div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                    {% endif %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                                {% endfor %}
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                                            </div>
                                        
                                        
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                            </div>
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                        {% endfor %}
                                        
                                        
                                            
                                            
                                            
                                            
                                        
                                    
                                
                                
                                
                            
                                
                                    
                                        
                                            
                                                    </div>