roundabout,
created on Wednesday, 17 April 2024, 13:14:20 (1713359660),
received on Wednesday, 31 July 2024, 06:54:45 (1722408885)
Author identity: vlad <vlad.muntoiu@gmail.com>
58e270e0b833e0365d0b24a345ffdf3a66c748fa
app.py
@@ -97,7 +97,7 @@ def default():
"user_object": user_object,
"Notification": Notification,
"unread": UserNotification.query.filter_by(user_username=username).filter(
UserNotification.attention_level > 0).count(),
UserNotification.attention_level > 0).count(),
"config": config,
"Markup": Markup,
"locale_names": locale_names,
@@ -114,8 +114,12 @@ def main():
@app.route("/userstyle")
def userstyle():
if flask.session.get("username") and os.path.exists(os.path.join(config.REPOS_PATH, flask.session.get("username"), ".config", "theme.css")):
return flask.send_from_directory(os.path.join(config.REPOS_PATH, flask.session.get("username"), ".config"), "theme.css")
if flask.session.get("username") and os.path.exists(
os.path.join(config.REPOS_PATH, flask.session.get("username"), ".config",
"theme.css")):
return flask.send_from_directory(
os.path.join(config.REPOS_PATH, flask.session.get("username"), ".config"),
"theme.css")
else:
return flask.Response("", mimetype="text/css")
@@ -166,7 +170,7 @@ def settings():
user.company = flask.request.form["company"]
user.company_URL = flask.request.form["companyurl"]
user.email = flask.request.form.get("email") if flask.request.form.get(
"email") else None
"email") else None
user.location = flask.request.form["location"]
user.show_mail = True if flask.request.form.get("showmail") else False
user.bio = flask.request.form.get("bio")
@@ -174,8 +178,8 @@ def settings():
db.session.commit()
flask.flash(
Markup("<iconify-icon icon='mdi:check'></iconify-icon>" + _("Settings saved")),
category="success")
Markup("<iconify-icon icon='mdi:check'></iconify-icon>" + _("Settings saved")),
category="success")
return flask.redirect(f"/{flask.session.get('username')}", code=303)
@@ -185,7 +189,7 @@ def favourites():
flask.abort(401)
if flask.request.method == "GET":
relationships = RepoFavourite.query.filter_by(
user_username=flask.session.get("username"))
user_username=flask.session.get("username"))
return flask.render_template("favourites.html", favourites=relationships)
@@ -203,10 +207,11 @@ def favourite_edit(id):
favourite.notify_forum = js_to_bool(data.get("forum"))
favourite.notify_pr = js_to_bool(data.get("pull_request"))
favourite.notify_admin = js_to_bool(data.get("administrative"))
print(favourite.notify_commit, favourite.notify_forum, favourite.notify_pr, favourite.notify_admin)
print(favourite.notify_commit, favourite.notify_forum, favourite.notify_pr,
favourite.notify_admin)
db.session.commit()
return flask.render_template_string(
"""
"""
<tr hx-post="/favourites/{{ favourite.id }}" hx-trigger="change" hx-include="#commit-{{ favourite.id }}, #forum-{{ favourite.id }}, #pull_request-{{ favourite.id }}, #administrative-{{ favourite.id }}" hx-headers='{"Content-Type": "application/json"}' hx-swap="outerHTML">
<td><a href="{{ favourite.repo.route }}">{{ favourite.repo.owner.username }}/{{ favourite.repo.name }}</a></td>
<td style="text-align: center;"><input type="checkbox" name="commit" id="commit-{{ favourite.id }}" value="true" {% if favourite.notify_commit %}checked{% endif %}></td>
@@ -215,7 +220,7 @@ def favourite_edit(id):
<td style="text-align: center;"><input type="checkbox" name="administrative" id="administrative-{{ favourite.id }}" value="true" {% if favourite.notify_admin %}checked{% endif %}></td>
</tr>
""",
favourite=favourite
favourite=favourite
)
@@ -226,7 +231,9 @@ def notifications():
if flask.request.method == "GET":
return flask.render_template("notifications.html",
notifications=UserNotification.query.filter_by(
user_username=flask.session.get("username")))
user_username=flask.session.get("username")
).order_by(UserNotification.id.desc())
)
@app.route("/notifications/<int:notification_id>/read", methods=["POST"])
@@ -238,7 +245,9 @@ def mark_read(notification_id):
flask.abort(403)
notification.mark_read()
db.session.commit()
return flask.render_template_string("<button hx-post='/notifications/{{ notification.id }}/unread' hx-swap='outerHTML'>Mark as unread</button>", notification=notification), 200
return flask.render_template_string(
"<button hx-post='/notifications/{{ notification.id }}/unread' hx-swap='outerHTML'>Mark as unread</button>",
notification=notification), 200
@app.route("/notifications/<int:notification_id>/unread", methods=["POST"])
@@ -250,7 +259,9 @@ def mark_unread(notification_id):
flask.abort(403)
notification.mark_unread()
db.session.commit()
return flask.render_template_string("<button hx-post='/notifications/{{ notification.id }}/read' hx-swap='outerHTML'>Mark as read</button>", notification=notification), 200
return flask.render_template_string(
"<button hx-post='/notifications/{{ notification.id }}/read' hx-swap='outerHTML'>Mark as read</button>",
notification=notification), 200
@app.route("/notifications/mark-all-read", methods=["POST"])
@@ -259,7 +270,7 @@ def mark_all_read():
flask.abort(401)
notifications = UserNotification.query.filter_by(
user_username=flask.session.get("username"))
user_username=flask.session.get("username"))
for notification in notifications:
notification.mark_read()
db.session.commit()
@@ -281,20 +292,21 @@ def login():
flask.session["username"] = user.username
flask.flash(
Markup("<iconify-icon icon='mdi:account'></iconify-icon>" + _(
"Successfully logged in as {username}").format(username=username)),
"Successfully logged in as {username}").format(
username=username)),
category="success")
return flask.redirect("/", code=303)
elif not user:
flask.flash(Markup(
"<iconify-icon icon='mdi:account-question'></iconify-icon>" + _(
"User not found")),
category="alert")
"<iconify-icon icon='mdi:account-question'></iconify-icon>" + _(
"User not found")),
category="alert")
return flask.render_template("login.html")
else:
flask.flash(Markup(
"<iconify-icon icon='mdi:account-question'></iconify-icon>" + _(
"Invalid password")),
category="error")
"<iconify-icon icon='mdi:account-question'></iconify-icon>" + _(
"Invalid password")),
category="error")
return flask.render_template("login.html")
if "signup" in flask.request.form:
username = flask.request.form["username"]
@@ -315,24 +327,24 @@ def login():
flask.flash(
Markup(
"<iconify-icon icon='mdi:account-error'></iconify-icon>" + _(
"Sorry, {username} is a system path").format(
username=username)),
"Sorry, {username} is a system path").format(
username=username)),
category="error")
return flask.render_template("login.html")
user_check = User.query.filter_by(username=username).first()
if user_check or email2: # make the honeypot look like a normal error
if user_check or email2: # make the honeypot look like a normal error
flask.flash(
Markup(
"<iconify-icon icon='mdi:account-error'></iconify-icon>" + _(
"The username {username} is taken").format(
username=username)),
"The username {username} is taken").format(
username=username)),
category="error")
return flask.render_template("login.html")
if password2 != password:
flask.flash(Markup("<iconify-icon icon='mdi:key-alert'></iconify-icon>" + _(
"Make sure the passwords match")),
"Make sure the passwords match")),
category="error")
return flask.render_template("login.html")
@@ -342,8 +354,8 @@ def login():
flask.session["username"] = user.username
flask.flash(Markup(
"<iconify-icon icon='mdi:account'></iconify-icon>" + _(
"Successfully created and logged in as {username}").format(
username=username)),
"Successfully created and logged in as {username}").format(
username=username)),
category="success")
notification = Notification({"type": "welcome"})
@@ -369,7 +381,7 @@ def new_repo():
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"):
flask.flash(Markup(
"<iconify-icon icon='mdi:error'></iconify-icon>" + _(
"Repository names may only contain Latin alphabet, numbers, '-' and '_'")),
"Repository names may only contain Latin alphabet, numbers, '-' and '_'")),
category="error")
return flask.render_template("new-repo.html")
@@ -388,16 +400,16 @@ def new_repo():
def logout():
flask.session.clear()
flask.flash(Markup(
"<iconify-icon icon='mdi:account'></iconify-icon>" + _("Successfully logged out")),
category="info")
"<iconify-icon icon='mdi:account'></iconify-icon>" + _("Successfully logged out")),
category="info")
return flask.redirect("/", code=303)
@app.route("/<username>/", methods=["GET", "POST"])
def user_profile(username):
old_relationship = UserFollow.query.filter_by(
follower_username=flask.session.get("username"),
followed_username=username).first()
follower_username=flask.session.get("username"),
followed_username=username).first()
if flask.request.method == "GET":
user = User.query.filter_by(username=username).first()
match flask.request.args.get("action"):
@@ -848,7 +860,8 @@ def repository_forum_thread(username, repository, post_id):
)
@repositories.route("/<username>/<repository>/forum/<int:post_id>/change-state", methods=["POST"])
@repositories.route("/<username>/<repository>/forum/<int:post_id>/change-state",
methods=["POST"])
def repository_forum_change_state(username, repository, post_id):
server_repo_location = os.path.join(config.REPOS_PATH, username, repository)
if not os.path.exists(server_repo_location):
@@ -973,7 +986,7 @@ def repository_forum_vote(username, repository, post_id, score):
user_vote = PostVote.query.filter_by(user_username=user.username,
post_identifier=post.identifier).first()
response = flask.make_response(
str(post.vote_sum) + " " + str(user_vote.vote_score if user_vote else 0))
str(post.vote_sum) + " " + str(user_vote.vote_score if user_vote else 0))
response.content_type = "text/plain"
return response
@@ -1059,14 +1072,14 @@ def repository_users(username, repository):
if flask.request.form.get("new-username"):
# Create new relationship
new_user = User.query.filter_by(
username=flask.request.form.get("new-username")).first()
username=flask.request.form.get("new-username")).first()
relationship = RepoAccess(new_user, repo_data, flask.request.form.get("new-level"))
db.session.add(relationship)
db.session.commit()
if flask.request.form.get("update-username"):
# Create new relationship
updated_user = User.query.filter_by(
username=flask.request.form.get("update-username")).first()
username=flask.request.form.get("update-username")).first()
relationship = RepoAccess.query.filter_by(repo=repo_data, user=updated_user).first()
if flask.request.form.get("update-level") == -1:
relationship.delete()
@@ -1075,7 +1088,7 @@ def repository_users(username, repository):
db.session.commit()
return flask.redirect(
app.url_for(".repository_users", username=username, repository=repository))
app.url_for(".repository_users", username=username, repository=repository))
@repositories.route("/<username>/<repository>/branches/")
@@ -1239,7 +1252,7 @@ def repository_prs(username, repository):
if not head_data.visibility:
flask.flash(Markup(
"<iconify-icon icon='mdi:error'></iconify-icon>" + _(
"Head can't be restricted")),
"Head can't be restricted")),
category="error")
return flask.redirect(".", 303)
@@ -1398,4 +1411,4 @@ def e405(error):
if __name__ == "__main__":
app.run(debug=True, port=8080, host="0.0.0.0")
app.register_blueprint(repositories)
app.register_blueprint(repositories)
jinja_utils.py
@@ -47,4 +47,14 @@ def parse_inline_markdown(value: str):
@app.template_filter("parse_diff_location")
def parse_diff_location(value: str):
header = value.split("@@")[1].strip()
return [tuple(int(j) for j in i.lstrip("-+").split(",")) for i in header.split(" ")]
return [tuple(int(j) for j in i.lstrip("-+").split(",")) for i in header.split(" ")]
@app.template_filter("reverse")
def reverse(value):
return reversed(value)
@app.template_filter("sort")
def sort(value):
return sorted(value)