roundabout,
created on Saturday, 6 April 2024, 13:47:12 (1712411232),
received on Sunday, 7 April 2024, 12:44:08 (1712493848)
Author identity: vlad <vlad.muntoiu@gmail.com>
f93511b3d0df725ecc630ffdf11cb6e56889d64c
.idea/workspace.xml
@@ -4,17 +4,11 @@
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="411335b4-e813-41ad-9046-18b77b97ee46" name="Changes" comment="Initial commit">
<change afterPath="$PROJECT_DIR$/templates/app-editor.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/templates/app.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/templates/new-app.html" afterDir="false" />
<list default="true" id="411335b4-e813-41ad-9046-18b77b97ee46" name="Changes" comment="More">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app.py" beforeDir="false" afterPath="$PROJECT_DIR$/app.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/static/style.css" beforeDir="false" afterPath="$PROJECT_DIR$/static/style.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/dashboard.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/dashboard.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/default.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/default.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/login.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/login.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/signup.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/signup.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/app-editor.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/app-editor.html" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -80,7 +74,15 @@
<option name="project" value="LOCAL" />
<updated>1712333020964</updated>
</task>
<option name="localTasksCounter" value="2" />
<task id="LOCAL-00002" summary="More">
<option name="closed" value="true" />
<created>1712409360299</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1712409360299</updated>
</task>
<option name="localTasksCounter" value="3" />
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
@@ -96,6 +98,7 @@
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="Initial commit" />
<option name="LAST_COMMIT_MESSAGE" value="Initial commit" />
<MESSAGE value="More" />
<option name="LAST_COMMIT_MESSAGE" value="More" />
</component>
</project>
app.py
@@ -32,7 +32,7 @@ with app.app_context():
self.admin = admin
class Application(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True, default=0)
id = db.Column(db.Integer, primary_key=True, autoincrement=True, unique=True, default=0)
name = db.Column(db.String(64), unique=True, nullable=False)
owner_name = db.Column(db.String(64), db.ForeignKey("user.username"), nullable=False)
@@ -46,15 +46,18 @@ with app.app_context():
class Endpoint(db.Model):
id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True, autoincrement=True)
application_name = db.Column(db.String(64), db.ForeignKey("application.name"), nullable=False)
application_id = db.Column(db.Integer, db.ForeignKey("application.id"), nullable=False)
address = db.Column(db.String(2048), nullable=False)
name = db.Column(db.String(64), nullable=False)
comment = db.Column(db.String(2048), nullable=True)
application = db.relationship("Application", back_populates="endpoints")
def __init__(self, application_name):
self.application_name = application_name
def __init__(self, application, name, address, comment=""):
self.application_id = application.id
self.name = name
self.address = address
self.comment = comment
Base = declarative_base()
@@ -182,15 +185,45 @@ def info(endpoint_id):
return flask.render_template("timeline.html", endpoint=endpoint_id)
@app.route("/app/<int:app_id>")
@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_)
@app.route("/app/<int:app_id>/edit")
@app.route("/app/<int:app_id>/edit/")
def app_editor(app_id):
if flask.session.get("username") != db.session.get(Application, app_id).owner_name:
flask.abort(403)
app_ = db.session.get(Application, app_id)
return flask.render_template("app-editor.html", app=app_)
@app.route("/app/<int:app_id>/edit/<int:endpoint_id>", methods=["POST"])
def endpoint_edit(app_id, endpoint_id):
if flask.session.get("username") != db.session.get(Application, app_id).owner_name:
flask.abort(403)
endpoint = db.session.get(Endpoint, endpoint_id)
if flask.request.form.get("delete") == "delete":
db.session.delete(endpoint)
db.session.commit()
else:
endpoint.name = flask.request.form["name"]
endpoint.address = flask.request.form["url"]
endpoint.comment = flask.request.form["comment"]
db.session.commit()
return flask.redirect(f"/app/{app_id}/edit", code=303)
@app.route("/app/<int:app_id>/add-endpoint", methods=["POST"])
def app_add_endpoint(app_id):
if flask.session.get("username") != db.session.get(Application, app_id).owner_name:
flask.abort(403)
app_ = db.session.get(Application, app_id)
endpoint = Endpoint(app_,
flask.request.form["name"],
flask.request.form["url"],
flask.request.form["comment"])
db.session.add(endpoint)
db.session.commit()
return flask.redirect(f"/app/{app_id}/edit", code=303)
static/style.css
@@ -74,7 +74,7 @@ nav a:hover {
main {
padding: 16px;
width: min(800px, 100vw);
width: min(800px, 100%);
}
#navi-spacer {
@@ -262,4 +262,32 @@ iconify-icon {
textarea {
resize: vertical;
appearance: none;
}
}
#endpoint-editor {
display: flex;
gap: 2rem;
width: 100%;
align-items: stretch;
flex-direction: column;
}
.side-by-side {
display: flex;
gap: 1rem;
align-items: stretch;
justify-content: space-around;
}
.side-by-side > button {
flex: 1 1 25%;
}
.danger-button {
background: #F44336;
border-color: #F44336;
}
.danger-button:hover {
background: #D32F2F;
}
templates/app-editor.html
@@ -3,17 +3,23 @@
{% block content %}
<main>
<h1>Editing {{ app.name }}</h1>
{% for endpoint in app.endpoints %}
<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="text" name="url" placeholder="URL" value="{{ endpoint.url }}">
<button type="submit">Save</button>
<a class="button" href="/app/{{ app.id }}/delete/{{ endpoint.id }}">Delete</a>
</form>
{% endfor %}
<form class="stacked-form" method="post" action="/app/{{ app.id }}/edit">
<div id="endpoint-editor">
{% for endpoint in app.endpoints %}
<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 }}">
<textarea name="comment" placeholder="Comment" rows="4">{{ endpoint.comment }}</textarea>
<div class="side-by-side">
<button type="submit">Apply changes</button>
<button type="submit" name="delete" value="delete" class="danger-button">Delete</button>
</div>
</form>
{% endfor %}
</div>
<h2>Add an endpoint</h2>
<form class="stacked-form" method="post" action="/app/{{ app.id }}/add-endpoint">
<input type="text" name="name" placeholder="Name">
<input type="text" name="url" placeholder="URL">
<input type="url" name="url" placeholder="Ping address">
<textarea name="comment" placeholder="Comment" rows="4"></textarea>
<button type="submit">Add</button>
</form>