mirror of
https://github.com/minetest/contentdb.git
synced 2024-11-09 17:13:45 +01:00
parent
0614e6b28b
commit
347f8e5a22
@ -545,3 +545,42 @@ def audit(package):
|
||||
|
||||
pagination = query.paginate(page, num, True)
|
||||
return render_template("admin/audit.html", log=pagination.items, pagination=pagination)
|
||||
|
||||
|
||||
class PackageAliasForm(FlaskForm):
|
||||
author = StringField("Author Name", [InputRequired(), Length(1, 50)])
|
||||
name = StringField("Name (Technical)", [InputRequired(), Length(1, 100), Regexp("^[a-z0-9_]+$", 0, "Lower case letters (a-z), digits (0-9), and underscores (_) only")])
|
||||
submit = SubmitField("Save")
|
||||
|
||||
|
||||
@bp.route("/packages/<author>/<name>/aliases/")
|
||||
@rank_required(UserRank.EDITOR)
|
||||
@is_package_page
|
||||
def alias_list(package: Package):
|
||||
return render_template("packages/alias_list.html", package=package)
|
||||
|
||||
|
||||
@bp.route("/packages/<author>/<name>/aliases/new/", methods=["GET", "POST"])
|
||||
@bp.route("/packages/<author>/<name>/aliases/<int:alias_id>/", methods=["GET", "POST"])
|
||||
@rank_required(UserRank.EDITOR)
|
||||
@is_package_page
|
||||
def alias_create_edit(package: Package, alias_id: int = None):
|
||||
alias = None
|
||||
if alias_id:
|
||||
alias = PackageAlias.query.get(alias_id)
|
||||
if alias is None or alias.package != package:
|
||||
abort(404)
|
||||
|
||||
form = PackageAliasForm(request.form, obj=alias)
|
||||
if form.validate_on_submit():
|
||||
if alias is None:
|
||||
alias = PackageAlias()
|
||||
alias.package = package
|
||||
db.session.add(alias)
|
||||
|
||||
form.populate_obj(alias)
|
||||
db.session.commit()
|
||||
|
||||
return redirect(package.getAliasListURL())
|
||||
|
||||
return render_template("packages/alias_create_edit.html", package=package, form=form)
|
||||
|
@ -127,6 +127,12 @@ def handle_register(form):
|
||||
flash("That username/display name is already in use, please choose another.", "danger")
|
||||
return
|
||||
|
||||
alias_by_name = PackageAlias.query.filter(or_(
|
||||
PackageAlias.author==form.username.data,
|
||||
PackageAlias.author==form.display_name.data)).first()
|
||||
if alias_by_name:
|
||||
flash("That username/display name is already in use, please choose another.", "danger")
|
||||
return
|
||||
|
||||
user_by_email = User.query.filter_by(email=form.email.data).first()
|
||||
if user_by_email:
|
||||
|
@ -56,6 +56,12 @@ def handle_profile_edit(form, user, username):
|
||||
flash("A user already has that name", "danger")
|
||||
return None
|
||||
|
||||
alias_by_name = PackageAlias.query.filter(or_(
|
||||
PackageAlias.author == form.display_name.data)).first()
|
||||
if alias_by_name:
|
||||
flash("A user already has that name", "danger")
|
||||
return
|
||||
|
||||
user.display_name = form.display_name.data
|
||||
|
||||
severity = AuditSeverity.USER if current_user == user else AuditSeverity.MODERATION
|
||||
@ -190,6 +196,7 @@ def email_notifications(username=None):
|
||||
|
||||
|
||||
class UserAccountForm(FlaskForm):
|
||||
username = StringField("Username", [Optional(), Length(1, 50)])
|
||||
display_name = StringField("Display name", [Optional(), Length(2, 100)])
|
||||
forums_username = StringField("Forums Username", [Optional(), Length(2, 50)])
|
||||
github_username = StringField("GitHub Username", [Optional(), Length(2, 50)])
|
||||
@ -219,6 +226,14 @@ def account(username):
|
||||
|
||||
# Copy form fields to user_profile fields
|
||||
if user.checkPerm(current_user, Permission.CHANGE_USERNAMES):
|
||||
if user.username != form.username.data:
|
||||
for package in user.packages:
|
||||
alias = PackageAlias(user.username, package.name)
|
||||
package.aliases.append(alias)
|
||||
db.session.add(alias)
|
||||
|
||||
user.username = form.username.data
|
||||
|
||||
user.display_name = form.display_name.data
|
||||
user.forums_username = nonEmptyOrNone(form.forums_username.data)
|
||||
user.github_username = nonEmptyOrNone(form.github_username.data)
|
||||
|
@ -337,6 +337,9 @@ class Package(db.Model):
|
||||
update_config = db.relationship("PackageUpdateConfig", uselist=False, back_populates="package",
|
||||
cascade="all, delete, delete-orphan")
|
||||
|
||||
aliases = db.relationship("PackageAlias", foreign_keys="PackageAlias.package_id",
|
||||
back_populates="package", cascade="all, delete, delete-orphan")
|
||||
|
||||
def __init__(self, package=None):
|
||||
if package is None:
|
||||
return
|
||||
@ -385,16 +388,22 @@ class Package(db.Model):
|
||||
release = self.getDownloadRelease(version=version)
|
||||
release_id = release and release.id
|
||||
|
||||
return {
|
||||
ret = {
|
||||
"name": self.name,
|
||||
"title": self.title,
|
||||
"author": self.author.username,
|
||||
"short_description": self.short_desc,
|
||||
"type": self.type.toName(),
|
||||
"release": release_id,
|
||||
"thumbnail": (base_url + tnurl) if tnurl is not None else None
|
||||
"thumbnail": (base_url + tnurl) if tnurl is not None else None,
|
||||
"aliases": [ alias.getAsDictionary() for alias in self.aliases ],
|
||||
}
|
||||
|
||||
if not ret["aliases"]:
|
||||
del ret["aliases"]
|
||||
|
||||
return ret
|
||||
|
||||
def getAsDictionary(self, base_url, version=None):
|
||||
tnurl = self.getThumbnailURL(1)
|
||||
release = self.getDownloadRelease(version=version)
|
||||
@ -543,6 +552,14 @@ class Package(db.Model):
|
||||
|
||||
return None
|
||||
|
||||
def getAliasListURL(self):
|
||||
return url_for("packages.alias_list",
|
||||
author=self.author.username, name=self.name)
|
||||
|
||||
def getAliasCreateURL(self):
|
||||
return url_for("packages.alias_create_edit",
|
||||
author=self.author.username, name=self.name)
|
||||
|
||||
def checkPerm(self, user, perm):
|
||||
if not user.is_authenticated:
|
||||
return False
|
||||
@ -1033,3 +1050,24 @@ class PackageUpdateConfig(db.Model):
|
||||
|
||||
def get_create_release_url(self):
|
||||
return self.package.getCreateReleaseURL(title=self.get_title(), ref=self.get_ref())
|
||||
|
||||
|
||||
class PackageAlias(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
package_id = db.Column(db.Integer, db.ForeignKey("package.id"), nullable=False)
|
||||
package = db.relationship("Package", back_populates="aliases", foreign_keys=[package_id])
|
||||
|
||||
author = db.Column(db.String(50), nullable=False)
|
||||
name = db.Column(db.String(100), nullable=False)
|
||||
|
||||
def __init__(self, author="", name=""):
|
||||
self.author = author
|
||||
self.name = name
|
||||
|
||||
def getEditURL(self):
|
||||
return url_for("packages.alias_create_edit", author=self.package.author.username,
|
||||
name=self.package.name, alias_id=self.id)
|
||||
|
||||
def getAsDictionary(self):
|
||||
return f"{self.author}/{self.name}"
|
||||
|
@ -101,7 +101,7 @@ class QueryBuilder:
|
||||
else:
|
||||
query = Package.query.filter_by(state=PackageState.APPROVED)
|
||||
|
||||
query = query.options(subqueryload(Package.main_screenshot))
|
||||
query = query.options(subqueryload(Package.main_screenshot), subqueryload(Package.aliases))
|
||||
|
||||
query = self.orderPackageQuery(self.filterPackageQuery(query))
|
||||
|
||||
|
23
app/templates/packages/alias_create_edit.html
Normal file
23
app/templates/packages/alias_create_edit.html
Normal file
@ -0,0 +1,23 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
{{ _("Alias") }}
|
||||
{% endblock %}
|
||||
|
||||
{% block link %}
|
||||
<a href="{{ package.getDetailsURL() }}">{{ package.title }}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<a class="btn btn-secondary" href="{{ package.getAliasListURL() }}">Back to Aliases</a>
|
||||
|
||||
{% from "macros/forms.html" import render_field, render_submit_field, render_toggle_field %}
|
||||
<form method="POST" action="" enctype="multipart/form-data" class="mt-4">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
{{ render_field(form.author) }}
|
||||
{{ render_field(form.name) }}
|
||||
{{ render_submit_field(form.submit) }}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
27
app/templates/packages/alias_list.html
Normal file
27
app/templates/packages/alias_list.html
Normal file
@ -0,0 +1,27 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
{{ _("Aliases") }}
|
||||
{% endblock %}
|
||||
|
||||
{% block link %}
|
||||
<a href="{{ package.getDetailsURL() }}">{{ package.title }}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<a class="btn btn-primary float-right" href="{{ package.getAliasCreateURL() }}">Create</a>
|
||||
<h1>{{ _("Aliases for %(title)s by %(author)s", title=self.link(), author=package.author.display_name) }}</h1>
|
||||
|
||||
<div class="list-group">
|
||||
{% for alias in package.aliases %}
|
||||
<a class="list-group-item list-group-item-action" href="{{ alias.getEditURL() }}">
|
||||
{{ alias.author }} / {{ alias.name }}
|
||||
</a>
|
||||
{% else %}
|
||||
<div class="list-group-item">
|
||||
No aliases
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -18,6 +18,7 @@
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
{% if user.checkPerm(current_user, "CHANGE_USERNAMES") %}
|
||||
{{ render_field(form.username, tabindex=230) }}
|
||||
{{ render_field(form.display_name, tabindex=230) }}
|
||||
{{ render_field(form.forums_username, tabindex=230) }}
|
||||
{{ render_field_prefix(form.github_username, tabindex=230) }}
|
||||
|
@ -18,7 +18,7 @@
|
||||
from functools import wraps
|
||||
from flask import abort, redirect, url_for, request
|
||||
from flask_login import current_user
|
||||
from app.models import User, NotificationType, Package, UserRank, Notification, db, AuditSeverity, AuditLogEntry, ThreadReply, Thread, PackageState, PackageType
|
||||
from app.models import User, NotificationType, Package, UserRank, Notification, db, AuditSeverity, AuditLogEntry, ThreadReply, Thread, PackageState, PackageType, PackageAlias
|
||||
|
||||
|
||||
def getPackageByInfo(author, name):
|
||||
@ -45,16 +45,22 @@ def is_package_page(f):
|
||||
package = getPackageByInfo(author, name)
|
||||
if package is None:
|
||||
package = getPackageByInfo(author, name + "_game")
|
||||
if package is None or package.type != PackageType.GAME:
|
||||
abort(404)
|
||||
if package and package.type == PackageType.GAME:
|
||||
args = dict(kwargs)
|
||||
args["name"] = name + "_game"
|
||||
return redirect(url_for(request.endpoint, **args))
|
||||
|
||||
args = dict(kwargs)
|
||||
args["name"] = name + "_game"
|
||||
return redirect(url_for(request.endpoint, **args))
|
||||
alias = PackageAlias.query.filter_by(author=author, name=name).first()
|
||||
if alias is not None:
|
||||
args = dict(kwargs)
|
||||
args["author"] = alias.package.author.username
|
||||
args["name"] = alias.package.name
|
||||
return redirect(url_for(request.endpoint, **args))
|
||||
|
||||
abort(404)
|
||||
|
||||
del kwargs["author"]
|
||||
del kwargs["name"]
|
||||
|
||||
return f(package=package, *args, **kwargs)
|
||||
|
||||
return decorated_function
|
||||
|
Loading…
Reference in New Issue
Block a user