roundabout,
created on Thursday, 25 April 2024, 14:21:33 (1714054893),
received on Wednesday, 31 July 2024, 06:54:46 (1722408886)
Author identity: vlad <vlad.muntoiu@gmail.com>
dd0622d0cbd7e65bed5395d2ded443df4b1da598
app.py
@@ -168,33 +168,49 @@ def help_redirect():
return flask.redirect(config.help_url, code=302)
@app.route("/settings/", methods=["GET", "POST"])
@app.route("/settings/")
def settings():
if not flask.session.get("username"):
flask.abort(401)
if flask.request.method == "GET":
user = User.query.filter_by(username=flask.session.get("username")).first()
user = User.query.filter_by(username=flask.session.get("username")).first()
return flask.render_template("user-settings.html", user=user)
else:
user = User.query.filter_by(username=flask.session.get("username")).first()
return flask.render_template("user-settings.html", user=user)
user.display_name = flask.request.form["displayname"]
user.URL = flask.request.form["url"]
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
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")
db.session.commit()
@app.route("/settings/profile", methods=["POST"])
def settings_profile():
user = User.query.filter_by(username=flask.session.get("username")).first()
user.display_name = flask.request.form["displayname"]
user.URL = flask.request.form["url"]
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
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")
db.session.commit()
flask.flash(
Markup("<iconify-icon icon='mdi:check'></iconify-icon>" + _("Settings saved")),
category="success")
return flask.redirect(f"/{flask.session.get('username')}", code=303)
flask.flash(
Markup("<iconify-icon icon='mdi:check'></iconify-icon>" + _("Settings saved")),
category="success")
return flask.redirect(f"/{flask.session.get('username')}", code=303)
@app.route("/settings/preferences", methods=["POST"])
def settings_prefs():
user = User.query.filter_by(username=flask.session.get("username")).first()
user.default_page_length = int(flask.request.form["page_length"])
db.session.commit()
flask.flash(
Markup("<iconify-icon icon='mdi:check'></iconify-icon>" + _("Settings saved")),
category="success")
return flask.redirect(f"/{flask.session.get('username')}", code=303)
@app.route("/favourites/", methods=["GET", "POST"])
@@ -1209,7 +1225,11 @@ def repository_log(username, repository, branch):
commits = Commit.query.filter(Commit.identifier.in_(commit_list)).order_by(Commit.author_date.desc())
page_number = flask.request.args.get("page", 1, type=int)
page_length = flask.request.args.get("per_page", 2, type=int)
if flask.session.get("username"):
default_page_length = db.session.get(User, flask.session.get("username")).default_page_length
else:
default_page_length = 16
page_length = flask.request.args.get("per_page", default_page_length, type=int)
page_listing = db.paginate(commits, page=page_number, per_page=page_length)
if page_listing.has_next:
models.py
@@ -93,6 +93,7 @@ with (app.app_context()):
show_mail = db.Column(db.Boolean, default=False, nullable=False)
location = db.Column(db.Unicode(64), nullable=True)
creation_date = db.Column(db.DateTime, default=datetime.utcnow)
default_page_length = db.Column(db.SmallInteger, nullable=False, default=32, server_default="32")
repositories = db.relationship("Repo", back_populates="owner")
followers = db.relationship("UserFollow", back_populates="followed", foreign_keys="[UserFollow.followed_username]")
templates/pagination.html
@@ -1,19 +1,19 @@
<x-hbox id="pagination-options">
<x-hbox id="pagination">
{% if prev_page %}
<a href="?page=1">
<a href="?per_page={{ page_length }}&page=1">
«
</a>
<a href="?page={{ prev_page }}">
<a href="?per_page={{ page_length }}&page={{ prev_page }}">
‹
</a>
{% endif %}
<span>{{ page_number }}/{{ num_pages }}</span>
{% if next_page %}
<a href="?page={{ next_page }}">
<a href="?per_page={{ page_length }}&page={{ next_page }}">
›
</a>
<a href="?page={{ last_page }}">
<a href="?per_page={{ page_length }}&page={{ last_page }}">
»
</a>
{% endif %}
templates/user-settings.html
@@ -7,81 +7,97 @@
{% endblock %}
{% block content %}
<x-frame style="--width: 768px;">
<h1>{% trans %}User settings{% endtrans %}</h1>
<article class="card">
<section class="card-main">
<h2>{% trans %}Basic information{% endtrans %}</h2>
<p>{% trans username=user.username %}Username: {{ username }}{% endtrans %}</p>
<x-buttonbox>
<a class="button" href="password">{% trans %}Change password{% endtrans %}</a>
</x-buttonbox>
</section>
</article>
<article class="card">
<section class="card-main">
<h2>{% trans %}Avatar{% endtrans %}</h2>
<x-vbox>
<label for="change-avatar" id="change-avatar-label" data-change-label="{% trans %}Change{% endtrans %}">
<img src="/info/{{ user.username }}/avatar" alt="{{ user.username }}" class="avatar" style="width: 100%;" id="avatarPreview">
</label>
<form method="post" enctype="multipart/form-data" action="/info/{{ user.username }}/avatar">
<input type="file" name="avatar" accept="image/*" style="display: none;" id="change-avatar" onchange="preview();">
<button type="submit">{% trans %}Update{% endtrans %}</button>
</form>
</x-vbox>
</section>
<script>
avatarPreview=document.getElementById("avatarPreview");
function preview() {
avatarPreview.src=URL.createObjectURL(event.target.files[0]);
}
</script>
</article>
<article class="card">
<section class="card-main">
<form method="post">
<h2>{% trans %}Profile{% endtrans %}</h2>
<x-vbox>
<h1>{% trans %}User settings{% endtrans %}</h1>
<article class="card">
<section class="card-main">
<h2>{% trans %}Basic information{% endtrans %}</h2>
<p>{% trans username=user.username %}Username: {{ username }}{% endtrans %}</p>
<x-buttonbox>
<a class="button" href="password">{% trans %}Change password{% endtrans %}</a>
</x-buttonbox>
</section>
</article>
<article class="card">
<section class="card-main">
<h2>{% trans %}Avatar{% endtrans %}</h2>
<x-vbox>
<x-vbox class="nopad">
<label for="email">{% trans %}Email address{% endtrans %}</label>
<input id="email" name="email" type="email" value="{% if user.email %}{{ user.email }}{% endif %}">
</x-vbox>
<x-vbox class="nopad">
<label><input name="showmail" value="showmail" {% if user.show_mail %}checked{% endif %} type="checkbox">{% trans %}Show email on my profile{% endtrans %}</label>
</x-vbox>
<x-vbox class="nopad">
<label for="displayname">{% trans %}Friendly name{% endtrans %}</label>
<input id="displayname" name="displayname" value="{% if user.display_name %}{{ user.display_name }}{% endif %}" placeholder="{{ user.username }}">
</x-vbox>
<x-vbox class="nopad">
<label for="url">{% trans %}Link to your website{% endtrans %}</label>
<input id="url" name="url" value="{% if user.url %}{{ user.url }}{% endif %}" type="url">
</x-vbox>
<x-vbox class="nopad">
<x-hbox style="width: 100%; align-items: space-between;">
<x-vbox style="flex-grow: 1;" class="nopad">
<label for="company">{% trans %}Company or school{% endtrans %}</label>
<input id="company" name="company" value="{% if user.company %}{{ user.company }}{% endif %}">
</x-vbox>
<x-vbox style="flex-grow: 1;" class="nopad">
<label for="companyurl">{% trans %}Link to the company's website{% endtrans %}</label>
<input id="companyurl" name="companyurl" value="{% if user.company_url %}{{ user.company_url }}{% endif %}" type="url">
</x-vbox>
</x-hbox>
</x-vbox>
<x-vbox class="nopad">
<label for="location">{% trans %}Location{% endtrans %}</label>
<input id="location" name="location" value="{% if user.location %}{{ user.location }}{% endif %}" type="text">
<label for="change-avatar" id="change-avatar-label" data-change-label="{% trans %}Change{% endtrans %}">
<img src="/info/{{ user.username }}/avatar" alt="{{ user.username }}" class="avatar" style="width: 100%;" id="avatarPreview">
</label>
<form method="post" enctype="multipart/form-data" action="/info/{{ user.username }}/avatar">
<input type="file" name="avatar" accept="image/*" style="display: none;" id="change-avatar" onchange="preview();">
<button type="submit">{% trans %}Update{% endtrans %}</button>
</form>
</x-vbox>
</section>
<script>
avatarPreview=document.getElementById("avatarPreview");
function preview() {
avatarPreview.src=URL.createObjectURL(event.target.files[0]);
}
</script>
</article>
<article class="card">
<section class="card-main">
<form method="post" action="profile">
<h2>{% trans %}Profile{% endtrans %}</h2>
<x-vbox>
<x-vbox class="nopad">
<label for="email">{% trans %}Email address{% endtrans %}</label>
<input id="email" name="email" type="email" value="{% if user.email %}{{ user.email }}{% endif %}">
</x-vbox>
<x-vbox class="nopad">
<label><input name="showmail" value="showmail" {% if user.show_mail %}checked{% endif %} type="checkbox">{% trans %}Show email on my profile{% endtrans %}</label>
</x-vbox>
<x-vbox class="nopad">
<label for="displayname">{% trans %}Friendly name{% endtrans %}</label>
<input id="displayname" name="displayname" value="{% if user.display_name %}{{ user.display_name }}{% endif %}" placeholder="{{ user.username }}">
</x-vbox>
<x-vbox class="nopad">
<label for="url">{% trans %}Link to your website{% endtrans %}</label>
<input id="url" name="url" value="{% if user.url %}{{ user.url }}{% endif %}" type="url">
</x-vbox>
<x-vbox class="nopad">
<x-hbox style="width: 100%; align-items: space-between;">
<x-vbox style="flex-grow: 1;" class="nopad">
<label for="company">{% trans %}Company or school{% endtrans %}</label>
<input id="company" name="company" value="{% if user.company %}{{ user.company }}{% endif %}">
</x-vbox>
<x-vbox style="flex-grow: 1;" class="nopad">
<label for="companyurl">{% trans %}Link to the company's website{% endtrans %}</label>
<input id="companyurl" name="companyurl" value="{% if user.company_url %}{{ user.company_url }}{% endif %}" type="url">
</x-vbox>
</x-hbox>
</x-vbox>
<x-vbox class="nopad">
<label for="location">{% trans %}Location{% endtrans %}</label>
<input id="location" name="location" value="{% if user.location %}{{ user.location }}{% endif %}" type="text">
</x-vbox>
<x-vbox class="nopad">
<label for="bio">{% trans %}Bio{% endtrans %}</label>
<textarea id="bio" name="bio" rows="4">{% if user.bio %}{{ user.bio }}{% endif %}</textarea>
</x-vbox>
<button type="submit">{% trans %}Update profile{% endtrans %}</button>
</x-vbox>
<x-vbox class="nopad">
<label for="bio">{% trans %}Bio{% endtrans %}</label>
<textarea id="bio" name="bio" rows="4">{% if user.bio %}{{ user.bio }}{% endif %}</textarea>
</form>
</section>
</article>
<article class="card">
<section class="card-main">
<form method="post" action="preferences">
<h2>{% trans %}Preferences{% endtrans %}</h2>
{% trans username=user.username %}You can change themes by going to <a href="/{{ username }}/.config">your configuration repository</a> and pushing a CSS file called <code>theme.css</code>.{% endtrans %}
<x-vbox>
<x-vbox class="nopad">
<label for="page_length">{% trans %}Default number of items to show in paginated lists{% endtrans %}</label>
<input id="page_length" name="page_length" type="number" value="{{ user.default_page_length }}" min="1" max="256">
</x-vbox>
<button type="submit">{% trans %}Update preferences{% endtrans %}</button>
</x-vbox>
<button type="submit">{% trans %}Update profile{% endtrans %}</button>
</x-vbox>
</form>
</section>
</article>
</form>
</section>
</article>
</x-frame>
{% endblock %}