roundabout,
created on Wednesday, 17 July 2024, 11:44:49 (1721216689),
received on Wednesday, 31 July 2024, 06:54:51 (1722408891)
Author identity: vlad <vlad.muntoiu@gmail.com>
7f735e56899d3c2dcc1bfd1adf95a962879f30db
app.py
@@ -125,6 +125,8 @@ def default():
"locale_names": locale_names,
"set": set, # since using {} is impossible in Jinja
"request": flask.request,
"get_visibility": get_visibility,
"get_permission_level": get_permission_level,
}
@@ -1487,7 +1489,7 @@ def repository_prs(username, repository):
branches=repo.branches
)
else:
elif "id" not in flask.request.form:
repo_data = Repo.query.filter_by(route=f"/{username}/{repository}").first()
head = flask.request.form.get("head")
head_route = flask.request.form.get("headroute")
@@ -1533,6 +1535,28 @@ def repository_prs(username, repository):
celery_tasks.send_notification.apply_async(args=[user_notification.id])
return flask.redirect(".", 303)
else:
id = flask.request.form.get("id")
pull_request = db.session.get(PullRequest, id)
if not pull_request:
flask.abort(404)
if not (get_visibility(username, repository) or get_permission_level(
flask.session.get("username"), username,
repository) >= 1 or pull_request.owner.username == flask.session.get("username")):
flask.abort(403)
if not get_permission_level(flask.session.get("username"), username, repository):
flask.abort(401)
repo_data = Repo.query.filter_by(route=f"/{username}/{repository}").first()
if pull_request:
pull_request.resolves_list = flask.request.form.get("resolves")
db.session.commit()
return flask.redirect(".", 303)
@repositories.route("/<username>/<repository>/prs/merge", methods=["POST"])
models.py
@@ -12,6 +12,7 @@ __all__ = [
"PullRequest",
"EmailChangeRequest",
"Comment",
"PullRequestResolvesThread",
]
import secrets
@@ -271,6 +272,7 @@ with (app.app_context()):
remote_side="Post.parent_id",
primaryjoin="Post.identifier==Post.parent_id",
foreign_keys="[Post.parent_id]")
resolved_by = db.relationship("PullRequestResolvesThread", back_populates="post")
def __init__(self, owner, repo, parent, subject, message):
self.identifier = f"{repo.route}/{repo.last_post_id}"
@@ -410,6 +412,19 @@ with (app.app_context()):
self.data = json
class PullRequestResolvesThread(db.Model):
id = db.Column(db.Integer, primary_key=True)
pr_id = db.Column(db.BigInteger, db.ForeignKey("pull_request.id"), nullable=False)
post_id = db.Column(db.String(109), db.ForeignKey("post.identifier"), nullable=False)
pr = db.relationship("PullRequest", back_populates="resolves")
post = db.relationship("Post", back_populates="resolved_by")
def __init__(self, pr, post):
self.pr = pr
self.post = post
class PullRequest(db.Model):
id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
head_route = db.Column(db.String(98), db.ForeignKey("repo.route", ondelete="CASCADE"), nullable=False)
@@ -424,6 +439,7 @@ with (app.app_context()):
base_branch = db.Column(db.String(64), nullable=False)
owner = db.relationship("User", back_populates="prs")
resolves = db.relationship("PullRequestResolvesThread", back_populates="pr")
timestamp = db.Column(db.DateTime, nullable=False, default=datetime.now)
def __init__(self, head, head_branch, base, base_branch, owner):
@@ -433,6 +449,24 @@ with (app.app_context()):
self.base_branch = base_branch
self.owner = owner
@property
def resolves_list(self):
return " ".join([str(post.post.number) for post in self.resolves])
@resolves_list.setter
def resolves_list(self, value):
link_to = [Post.query.filter_by(number=int(number), repo=self.base).first() for number in value.split()]
resolved_posts = [post.post for post in self.resolves]
no_longer_resolves = list(set(resolved_posts) - set(link_to))
for post in no_longer_resolves:
db.session.delete(PullRequestResolvesThread.query.filter_by(pr=self, post=post).first())
for post in link_to:
if post not in resolved_posts and post is not None:
db.session.add(PullRequestResolvesThread(self, post))
db.session.commit()
class EmailChangeRequest(db.Model):
id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
static/style.css
@@ -673,4 +673,10 @@ small {
#repo-tabs > li > a:hover {
background-color: var(--color-flat-button-hover);
transition: box-shadow 375ms cubic-bezier(0.5, 1, 0.89, 1), background 375ms cubic-bezier(0.5, 1, 0.89, 1), color 375ms cubic-bezier(0.5, 1, 0.89, 1);
}
}
.post-number {
font: var(--mono-font);
font-size: inherit;
font-weight: 150;
}
templates/post.html
@@ -4,9 +4,9 @@
<section class="card-main">
<p class="post-details"><a href="/{{ post.owner.username }}" class="post-author">{{ post.owner.username }}</a> • {{ post.date | strftime("%A, %e %B %Y, %H:%M:%S") }}</p>
{% if level %}
<h2><a href="{{ post.number }}">{{ post.subject }}</a></h2>
<h2><a href="{{ post.number }}">{{ post.subject }}</a> <span class="post-number">#{{ post.number }}</span></h2>
{% else %}
<h2>{{ post.subject }}</h2>
<h2>{{ post.subject }} <span class="post-number">#{{ post.number }}</span></h2>
{% endif %}
<p>
{{ post.html | safe }}
templates/repository/repo-forum.html
@@ -36,7 +36,7 @@
</div>
{% endif %}
<section class="card-main">
<h3><a href="{{ post.number }}">{{ post.subject }}</a> ({{ post.children | length }})</h3>
<h3><a href="{{ post.number }}">{{ post.subject }}</a> <span class="post-number">#{{ post.number }}</span> ({{ post.children | length }})</h3>
<p><a href="/{{ post.owner.username }}">{{ post.owner.username }}</a></p>
</section>
</article>
templates/repository/repo-prs.html
@@ -46,6 +46,19 @@
<section class="card-main flexible-space">
<h3>{{ pr.head_route }} ({{ pr.head_branch }})<br>{{ pr.base_route }} ({{ pr.base_branch }})</h3>
<p>{% trans %}Requested by{% endtrans %} <a href="/{{ pr.owner.username }}">{{ pr.owner.username }}</a> • {{ pr.timestamp | strftime("%A, %e %B %Y, %H:%M:%S") }}</p>
{% if logged_in_user == pr.owner.username or get_permission_level(logged_in_user, username, repository) >= 1 %}
<form class="vbox" method="post">
<input type="hidden" name="id" value="{{ pr.id }}">
<label>
{% trans %}Resolves:{% endtrans %}
<input type="text" name="resolves" value="{{ pr.resolves_list }}">
</label>
{% trans %}To change: space-separated list of root post numbers{% endtrans %}
<button type="submit">{% trans %}Save{% endtrans %}</button>
</form>
{% else %}
{% trans %}Resolves:{% endtrans %} {{ pr.resolves_list }}
{% endif %}
</section>
<section>
<x-hbox>