mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 14:02:24 +01:00
Use consistent naming scheme for methods/functions
This commit is contained in:
parent
e0b25054dc
commit
8585357942
@ -106,10 +106,10 @@ def restore():
|
|||||||
package.state = target
|
package.state = target
|
||||||
|
|
||||||
addAuditLog(AuditSeverity.EDITOR, current_user, f"Restored package to state {target.value}",
|
addAuditLog(AuditSeverity.EDITOR, current_user, f"Restored package to state {target.value}",
|
||||||
package.getURL("packages.view"), package)
|
package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
deleted_packages = Package.query \
|
deleted_packages = Package.query \
|
||||||
.filter(Package.state == PackageState.DELETED) \
|
.filter(Package.state == PackageState.DELETED) \
|
||||||
|
@ -45,7 +45,7 @@ def audit():
|
|||||||
@login_required
|
@login_required
|
||||||
def audit_view(id_):
|
def audit_view(id_):
|
||||||
entry: AuditLogEntry = AuditLogEntry.query.get_or_404(id_)
|
entry: AuditLogEntry = AuditLogEntry.query.get_or_404(id_)
|
||||||
if not entry.checkPerm(current_user, Permission.VIEW_AUDIT_DESCRIPTION):
|
if not entry.check_perm(current_user, Permission.VIEW_AUDIT_DESCRIPTION):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
return render_template("admin/audit_view.html", entry=entry)
|
return render_template("admin/audit_view.html", entry=entry)
|
||||||
|
@ -60,7 +60,7 @@ def create_edit_tag(name=None):
|
|||||||
if tag is None:
|
if tag is None:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not Permission.checkPerm(current_user, Permission.EDIT_TAGS if tag else Permission.CREATE_TAG):
|
if not Permission.check_perm(current_user, Permission.EDIT_TAGS if tag else Permission.CREATE_TAG):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
form = TagForm( obj=tag)
|
form = TagForm( obj=tag)
|
||||||
|
@ -69,7 +69,7 @@ def packages():
|
|||||||
query = qb.buildPackageQuery()
|
query = qb.buildPackageQuery()
|
||||||
|
|
||||||
if request.args.get("fmt") == "keys":
|
if request.args.get("fmt") == "keys":
|
||||||
return jsonify([package.getAsDictionaryKey() for package in query.all()])
|
return jsonify([package.as_key_dict() for package in query.all()])
|
||||||
|
|
||||||
pkgs = qb.convertToDictionary(query.all())
|
pkgs = qb.convertToDictionary(query.all())
|
||||||
if "engine_version" in request.args or "protocol_version" in request.args:
|
if "engine_version" in request.args or "protocol_version" in request.args:
|
||||||
@ -93,7 +93,7 @@ def packages():
|
|||||||
@is_package_page
|
@is_package_page
|
||||||
@cors_allowed
|
@cors_allowed
|
||||||
def package(package):
|
def package(package):
|
||||||
return jsonify(package.getAsDictionary(current_app.config["BASE_URL"]))
|
return jsonify(package.as_dict(current_app.config["BASE_URL"]))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/packages/<author>/<name>/hypertext/")
|
@bp.route("/api/packages/<author>/<name>/hypertext/")
|
||||||
@ -119,7 +119,7 @@ def edit_package(token, package):
|
|||||||
|
|
||||||
|
|
||||||
def resolve_package_deps(out, package, only_hard, depth=1):
|
def resolve_package_deps(out, package, only_hard, depth=1):
|
||||||
id = package.getId()
|
id = package.get_id()
|
||||||
if id in out:
|
if id in out:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -135,12 +135,12 @@ def resolve_package_deps(out, package, only_hard, depth=1):
|
|||||||
|
|
||||||
if dep.package:
|
if dep.package:
|
||||||
name = dep.package.name
|
name = dep.package.name
|
||||||
fulfilled_by = [ dep.package.getId() ]
|
fulfilled_by = [ dep.package.get_id() ]
|
||||||
resolve_package_deps(out, dep.package, only_hard, depth)
|
resolve_package_deps(out, dep.package, only_hard, depth)
|
||||||
|
|
||||||
elif dep.meta_package:
|
elif dep.meta_package:
|
||||||
name = dep.meta_package.name
|
name = dep.meta_package.name
|
||||||
fulfilled_by = [ pkg.getId() for pkg in dep.meta_package.packages if pkg.state == PackageState.APPROVED]
|
fulfilled_by = [ pkg.get_id() for pkg in dep.meta_package.packages if pkg.state == PackageState.APPROVED]
|
||||||
|
|
||||||
if depth == 1 and not dep.optional:
|
if depth == 1 and not dep.optional:
|
||||||
most_likely = next((pkg for pkg in dep.meta_package.packages \
|
most_likely = next((pkg for pkg in dep.meta_package.packages \
|
||||||
@ -175,7 +175,7 @@ def package_dependencies(package):
|
|||||||
def topics():
|
def topics():
|
||||||
qb = QueryBuilder(request.args)
|
qb = QueryBuilder(request.args)
|
||||||
query = qb.buildTopicQuery(show_added=True)
|
query = qb.buildTopicQuery(show_added=True)
|
||||||
return jsonify([t.getAsDictionary() for t in query.all()])
|
return jsonify([t.as_dict() for t in query.all()])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/topic_discard/", methods=["POST"])
|
@bp.route("/api/topic_discard/", methods=["POST"])
|
||||||
@ -187,13 +187,13 @@ def topic_set_discard():
|
|||||||
error(400, "Missing topic ID or discard bool")
|
error(400, "Missing topic ID or discard bool")
|
||||||
|
|
||||||
topic = ForumTopic.query.get(tid)
|
topic = ForumTopic.query.get(tid)
|
||||||
if not topic.checkPerm(current_user, Permission.TOPIC_DISCARD):
|
if not topic.check_perm(current_user, Permission.TOPIC_DISCARD):
|
||||||
error(403, "Permission denied, need: TOPIC_DISCARD")
|
error(403, "Permission denied, need: TOPIC_DISCARD")
|
||||||
|
|
||||||
topic.discarded = discard == "true"
|
topic.discarded = discard == "true"
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify(topic.getAsDictionary())
|
return jsonify(topic.as_dict())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/whoami/")
|
@bp.route("/api/whoami/")
|
||||||
@ -232,14 +232,14 @@ def list_all_releases():
|
|||||||
query = query.join(Package)
|
query = query.join(Package)
|
||||||
query = query.filter(Package.maintainers.contains(maintainer))
|
query = query.filter(Package.maintainers.contains(maintainer))
|
||||||
|
|
||||||
return jsonify([ rel.getLongAsDictionary() for rel in query.limit(30).all() ])
|
return jsonify([ rel.as_long_dict() for rel in query.limit(30).all() ])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/packages/<author>/<name>/releases/")
|
@bp.route("/api/packages/<author>/<name>/releases/")
|
||||||
@is_package_page
|
@is_package_page
|
||||||
@cors_allowed
|
@cors_allowed
|
||||||
def list_releases(package):
|
def list_releases(package):
|
||||||
return jsonify([ rel.getAsDictionary() for rel in package.releases.all() ])
|
return jsonify([ rel.as_dict() for rel in package.releases.all() ])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/packages/<author>/<name>/releases/new/", methods=["POST"])
|
@bp.route("/api/packages/<author>/<name>/releases/new/", methods=["POST"])
|
||||||
@ -251,7 +251,7 @@ def create_release(token, package):
|
|||||||
if not token:
|
if not token:
|
||||||
error(401, "Authentication needed")
|
error(401, "Authentication needed")
|
||||||
|
|
||||||
if not package.checkPerm(token.owner, Permission.APPROVE_RELEASE):
|
if not package.check_perm(token.owner, Permission.APPROVE_RELEASE):
|
||||||
error(403, "You do not have the permission to approve releases")
|
error(403, "You do not have the permission to approve releases")
|
||||||
|
|
||||||
if request.headers.get("Content-Type") == "application/json":
|
if request.headers.get("Content-Type") == "application/json":
|
||||||
@ -290,7 +290,7 @@ def release(package: Package, id: int):
|
|||||||
if release is None or release.package != package:
|
if release is None or release.package != package:
|
||||||
error(404, "Release not found")
|
error(404, "Release not found")
|
||||||
|
|
||||||
return jsonify(release.getAsDictionary())
|
return jsonify(release.as_dict())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/packages/<author>/<name>/releases/<int:id>/", methods=["DELETE"])
|
@bp.route("/api/packages/<author>/<name>/releases/<int:id>/", methods=["DELETE"])
|
||||||
@ -309,7 +309,7 @@ def delete_release(token: APIToken, package: Package, id: int):
|
|||||||
if not token.canOperateOnPackage(package):
|
if not token.canOperateOnPackage(package):
|
||||||
error(403, "API token does not have access to the package")
|
error(403, "API token does not have access to the package")
|
||||||
|
|
||||||
if not release.checkPerm(token.owner, Permission.DELETE_RELEASE):
|
if not release.check_perm(token.owner, Permission.DELETE_RELEASE):
|
||||||
error(403, "Unable to delete the release, make sure there's a newer release available")
|
error(403, "Unable to delete the release, make sure there's a newer release available")
|
||||||
|
|
||||||
db.session.delete(release)
|
db.session.delete(release)
|
||||||
@ -323,7 +323,7 @@ def delete_release(token: APIToken, package: Package, id: int):
|
|||||||
@cors_allowed
|
@cors_allowed
|
||||||
def list_screenshots(package):
|
def list_screenshots(package):
|
||||||
screenshots = package.screenshots.all()
|
screenshots = package.screenshots.all()
|
||||||
return jsonify([ss.getAsDictionary(current_app.config["BASE_URL"]) for ss in screenshots])
|
return jsonify([ss.as_dict(current_app.config["BASE_URL"]) for ss in screenshots])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/packages/<author>/<name>/screenshots/new/", methods=["POST"])
|
@bp.route("/api/packages/<author>/<name>/screenshots/new/", methods=["POST"])
|
||||||
@ -335,7 +335,7 @@ def create_screenshot(token: APIToken, package: Package):
|
|||||||
if not token:
|
if not token:
|
||||||
error(401, "Authentication needed")
|
error(401, "Authentication needed")
|
||||||
|
|
||||||
if not package.checkPerm(token.owner, Permission.ADD_SCREENSHOTS):
|
if not package.check_perm(token.owner, Permission.ADD_SCREENSHOTS):
|
||||||
error(403, "You do not have the permission to create screenshots")
|
error(403, "You do not have the permission to create screenshots")
|
||||||
|
|
||||||
data = request.form
|
data = request.form
|
||||||
@ -357,7 +357,7 @@ def screenshot(package, id):
|
|||||||
if ss is None or ss.package != package:
|
if ss is None or ss.package != package:
|
||||||
error(404, "Screenshot not found")
|
error(404, "Screenshot not found")
|
||||||
|
|
||||||
return jsonify(ss.getAsDictionary(current_app.config["BASE_URL"]))
|
return jsonify(ss.as_dict(current_app.config["BASE_URL"]))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/packages/<author>/<name>/screenshots/<int:id>/", methods=["DELETE"])
|
@bp.route("/api/packages/<author>/<name>/screenshots/<int:id>/", methods=["DELETE"])
|
||||||
@ -373,7 +373,7 @@ def delete_screenshot(token: APIToken, package: Package, id: int):
|
|||||||
if not token:
|
if not token:
|
||||||
error(401, "Authentication needed")
|
error(401, "Authentication needed")
|
||||||
|
|
||||||
if not package.checkPerm(token.owner, Permission.ADD_SCREENSHOTS):
|
if not package.check_perm(token.owner, Permission.ADD_SCREENSHOTS):
|
||||||
error(403, "You do not have the permission to delete screenshots")
|
error(403, "You do not have the permission to delete screenshots")
|
||||||
|
|
||||||
if not token.canOperateOnPackage(package):
|
if not token.canOperateOnPackage(package):
|
||||||
@ -398,7 +398,7 @@ def order_screenshots(token: APIToken, package: Package):
|
|||||||
if not token:
|
if not token:
|
||||||
error(401, "Authentication needed")
|
error(401, "Authentication needed")
|
||||||
|
|
||||||
if not package.checkPerm(token.owner, Permission.ADD_SCREENSHOTS):
|
if not package.check_perm(token.owner, Permission.ADD_SCREENSHOTS):
|
||||||
error(403, "You do not have the permission to change screenshots")
|
error(403, "You do not have the permission to change screenshots")
|
||||||
|
|
||||||
if not token.canOperateOnPackage(package):
|
if not token.canOperateOnPackage(package):
|
||||||
@ -420,7 +420,7 @@ def set_cover_image(token: APIToken, package: Package):
|
|||||||
if not token:
|
if not token:
|
||||||
error(401, "Authentication needed")
|
error(401, "Authentication needed")
|
||||||
|
|
||||||
if not package.checkPerm(token.owner, Permission.ADD_SCREENSHOTS):
|
if not package.check_perm(token.owner, Permission.ADD_SCREENSHOTS):
|
||||||
error(403, "You do not have the permission to change screenshots")
|
error(403, "You do not have the permission to change screenshots")
|
||||||
|
|
||||||
if not token.canOperateOnPackage(package):
|
if not token.canOperateOnPackage(package):
|
||||||
@ -438,7 +438,7 @@ def set_cover_image(token: APIToken, package: Package):
|
|||||||
@cors_allowed
|
@cors_allowed
|
||||||
def list_reviews(package):
|
def list_reviews(package):
|
||||||
reviews = package.reviews
|
reviews = package.reviews
|
||||||
return jsonify([review.getAsDictionary() for review in reviews])
|
return jsonify([review.as_dict() for review in reviews])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/reviews/")
|
@bp.route("/api/reviews/")
|
||||||
@ -473,7 +473,7 @@ def list_all_reviews():
|
|||||||
"previous": abs_url(url_set_query(page=page - 1)) if pagination.has_prev else None,
|
"previous": abs_url(url_set_query(page=page - 1)) if pagination.has_prev else None,
|
||||||
"next": abs_url(url_set_query(page=page + 1)) if pagination.has_next else None,
|
"next": abs_url(url_set_query(page=page + 1)) if pagination.has_next else None,
|
||||||
},
|
},
|
||||||
"items": [review.getAsDictionary(True) for review in pagination.items],
|
"items": [review.as_dict(True) for review in pagination.items],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -501,20 +501,20 @@ def package_scores():
|
|||||||
qb = QueryBuilder(request.args)
|
qb = QueryBuilder(request.args)
|
||||||
query = qb.buildPackageQuery()
|
query = qb.buildPackageQuery()
|
||||||
|
|
||||||
pkgs = [package.getScoreDict() for package in query.all()]
|
pkgs = [package.as_score_dict() for package in query.all()]
|
||||||
return jsonify(pkgs)
|
return jsonify(pkgs)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/tags/")
|
@bp.route("/api/tags/")
|
||||||
@cors_allowed
|
@cors_allowed
|
||||||
def tags():
|
def tags():
|
||||||
return jsonify([tag.getAsDictionary() for tag in Tag.query.all() ])
|
return jsonify([tag.as_dict() for tag in Tag.query.all() ])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/content_warnings/")
|
@bp.route("/api/content_warnings/")
|
||||||
@cors_allowed
|
@cors_allowed
|
||||||
def content_warnings():
|
def content_warnings():
|
||||||
return jsonify([warning.getAsDictionary() for warning in ContentWarning.query.all() ])
|
return jsonify([warning.as_dict() for warning in ContentWarning.query.all() ])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/licenses/")
|
@bp.route("/api/licenses/")
|
||||||
@ -549,7 +549,7 @@ def homepage():
|
|||||||
downloads = 0 if not downloads_result or not downloads_result[0] else downloads_result[0]
|
downloads = 0 if not downloads_result or not downloads_result[0] else downloads_result[0]
|
||||||
|
|
||||||
def mapPackages(packages: List[Package]):
|
def mapPackages(packages: List[Package]):
|
||||||
return [pkg.getAsDictionaryShort(current_app.config["BASE_URL"]) for pkg in packages]
|
return [pkg.as_short_dict(current_app.config["BASE_URL"]) for pkg in packages]
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"count": count,
|
"count": count,
|
||||||
@ -574,7 +574,7 @@ def welcome_v1():
|
|||||||
.limit(5).all()
|
.limit(5).all()
|
||||||
|
|
||||||
def map_packages(packages: List[Package]):
|
def map_packages(packages: List[Package]):
|
||||||
return [pkg.getAsDictionaryShort(current_app.config["BASE_URL"]) for pkg in packages]
|
return [pkg.as_short_dict(current_app.config["BASE_URL"]) for pkg in packages]
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"featured": map_packages(featured),
|
"featured": map_packages(featured),
|
||||||
@ -591,10 +591,10 @@ def versions():
|
|||||||
if rel is None:
|
if rel is None:
|
||||||
error(404, "No releases found")
|
error(404, "No releases found")
|
||||||
|
|
||||||
return jsonify(rel.getAsDictionary())
|
return jsonify(rel.as_dict())
|
||||||
|
|
||||||
return jsonify([rel.getAsDictionary() \
|
return jsonify([rel.as_dict() \
|
||||||
for rel in MinetestRelease.query.all() if rel.getActual() is not None])
|
for rel in MinetestRelease.query.all() if rel.get_actual() is not None])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/api/dependencies/")
|
@bp.route("/api/dependencies/")
|
||||||
@ -605,7 +605,7 @@ def all_deps():
|
|||||||
|
|
||||||
def format_pkg(pkg: Package):
|
def format_pkg(pkg: Package):
|
||||||
return {
|
return {
|
||||||
"type": pkg.type.toName(),
|
"type": pkg.type.to_name(),
|
||||||
"author": pkg.author.username,
|
"author": pkg.author.username,
|
||||||
"name": pkg.name,
|
"name": pkg.name,
|
||||||
"provides": [x.name for x in pkg.provides],
|
"provides": [x.name for x in pkg.provides],
|
||||||
|
@ -49,7 +49,7 @@ def api_create_vcs_release(token: APIToken, package: Package, title: str, ref: s
|
|||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"task": url_for("tasks.check", id=rel.task_id),
|
"task": url_for("tasks.check", id=rel.task_id),
|
||||||
"release": rel.getAsDictionary()
|
"release": rel.as_dict()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ def api_create_zip_release(token: APIToken, package: Package, title: str, file,
|
|||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"task": url_for("tasks.check", id=rel.task_id),
|
"task": url_for("tasks.check", id=rel.task_id),
|
||||||
"release": rel.getAsDictionary()
|
"release": rel.as_dict()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ def api_create_screenshot(token: APIToken, package: Package, title: str, file, i
|
|||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"screenshot": ss.getAsDictionary()
|
"screenshot": ss.as_dict()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -115,5 +115,5 @@ def api_edit_package(token: APIToken, package: Package, data: dict, reason: str
|
|||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
"package": package.getAsDictionary(current_app.config["BASE_URL"])
|
"package": package.as_dict(current_app.config["BASE_URL"])
|
||||||
})
|
})
|
||||||
|
@ -49,7 +49,7 @@ def list_tokens(username):
|
|||||||
if user is None:
|
if user is None:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
|
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
return render_template("api/list_tokens.html", user=user, tabs=get_setting_tabs(user), current_tab="api_tokens")
|
return render_template("api/list_tokens.html", user=user, tabs=get_setting_tabs(user), current_tab="api_tokens")
|
||||||
@ -63,7 +63,7 @@ def create_edit_token(username, id=None):
|
|||||||
if user is None:
|
if user is None:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
|
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
is_new = id is None
|
is_new = id is None
|
||||||
@ -108,7 +108,7 @@ def reset_token(username, id):
|
|||||||
if user is None:
|
if user is None:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
|
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
token = APIToken.query.get(id)
|
token = APIToken.query.get(id)
|
||||||
@ -134,7 +134,7 @@ def delete_token(username, id):
|
|||||||
if user is None:
|
if user is None:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
|
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
is_new = id is None
|
is_new = id is None
|
||||||
|
@ -123,7 +123,7 @@ def webhook():
|
|||||||
if actual_token is None:
|
if actual_token is None:
|
||||||
return error(403, "Invalid authentication, couldn't validate API token")
|
return error(403, "Invalid authentication, couldn't validate API token")
|
||||||
|
|
||||||
if not package.checkPerm(actual_token.owner, Permission.APPROVE_RELEASE):
|
if not package.check_perm(actual_token.owner, Permission.APPROVE_RELEASE):
|
||||||
return error(403, "You do not have the permission to approve releases")
|
return error(403, "You do not have the permission to approve releases")
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -43,7 +43,7 @@ def webhook_impl():
|
|||||||
if token is None:
|
if token is None:
|
||||||
return error(403, "Invalid authentication")
|
return error(403, "Invalid authentication")
|
||||||
|
|
||||||
if not package.checkPerm(token.owner, Permission.APPROVE_RELEASE):
|
if not package.check_perm(token.owner, Permission.APPROVE_RELEASE):
|
||||||
return error(403, "You do not have the permission to approve releases")
|
return error(403, "You do not have the permission to approve releases")
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -23,49 +23,49 @@ bp = Blueprint("packages", __name__)
|
|||||||
|
|
||||||
|
|
||||||
def get_package_tabs(user: User, package: Package):
|
def get_package_tabs(user: User, package: Package):
|
||||||
if package is None or not package.checkPerm(user, Permission.EDIT_PACKAGE):
|
if package is None or not package.check_perm(user, Permission.EDIT_PACKAGE):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
retval = [
|
retval = [
|
||||||
{
|
{
|
||||||
"id": "edit",
|
"id": "edit",
|
||||||
"title": gettext("Edit Details"),
|
"title": gettext("Edit Details"),
|
||||||
"url": package.getURL("packages.create_edit")
|
"url": package.get_url("packages.create_edit")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "releases",
|
"id": "releases",
|
||||||
"title": gettext("Releases"),
|
"title": gettext("Releases"),
|
||||||
"url": package.getURL("packages.list_releases")
|
"url": package.get_url("packages.list_releases")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "screenshots",
|
"id": "screenshots",
|
||||||
"title": gettext("Screenshots"),
|
"title": gettext("Screenshots"),
|
||||||
"url": package.getURL("packages.screenshots")
|
"url": package.get_url("packages.screenshots")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "maintainers",
|
"id": "maintainers",
|
||||||
"title": gettext("Maintainers"),
|
"title": gettext("Maintainers"),
|
||||||
"url": package.getURL("packages.edit_maintainers")
|
"url": package.get_url("packages.edit_maintainers")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "audit",
|
"id": "audit",
|
||||||
"title": gettext("Audit Log"),
|
"title": gettext("Audit Log"),
|
||||||
"url": package.getURL("packages.audit")
|
"url": package.get_url("packages.audit")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "stats",
|
"id": "stats",
|
||||||
"title": gettext("Statistics"),
|
"title": gettext("Statistics"),
|
||||||
"url": package.getURL("packages.statistics")
|
"url": package.get_url("packages.statistics")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "share",
|
"id": "share",
|
||||||
"title": gettext("Share and Badges"),
|
"title": gettext("Share and Badges"),
|
||||||
"url": package.getURL("packages.share")
|
"url": package.get_url("packages.share")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "remove",
|
"id": "remove",
|
||||||
"title": gettext("Remove"),
|
"title": gettext("Remove"),
|
||||||
"url": package.getURL("packages.remove")
|
"url": package.get_url("packages.remove")
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ def get_package_tabs(user: User, package: Package):
|
|||||||
retval.insert(1, {
|
retval.insert(1, {
|
||||||
"id": "game_support",
|
"id": "game_support",
|
||||||
"title": gettext("Supported Games"),
|
"title": gettext("Supported Games"),
|
||||||
"url": package.getURL("packages.game_support")
|
"url": package.get_url("packages.game_support")
|
||||||
})
|
})
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
@ -68,7 +68,7 @@ def list_all():
|
|||||||
if qb.lucky:
|
if qb.lucky:
|
||||||
package = query.first()
|
package = query.first()
|
||||||
if package:
|
if package:
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
topic = qb.buildTopicQuery().first()
|
topic = qb.buildTopicQuery().first()
|
||||||
if qb.search and topic:
|
if qb.search and topic:
|
||||||
@ -108,7 +108,7 @@ def list_all():
|
|||||||
|
|
||||||
|
|
||||||
def getReleases(package):
|
def getReleases(package):
|
||||||
if package.checkPerm(current_user, Permission.MAKE_RELEASE):
|
if package.check_perm(current_user, Permission.MAKE_RELEASE):
|
||||||
return package.releases.limit(5)
|
return package.releases.limit(5)
|
||||||
else:
|
else:
|
||||||
return package.releases.filter_by(approved=True).limit(5)
|
return package.releases.filter_by(approved=True).limit(5)
|
||||||
@ -117,12 +117,12 @@ def getReleases(package):
|
|||||||
@bp.route("/packages/<author>/<name>/")
|
@bp.route("/packages/<author>/<name>/")
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def view(package):
|
def view(package):
|
||||||
if package.state != PackageState.APPROVED and not package.checkPerm(current_user, Permission.EDIT_PACKAGE):
|
if package.state != PackageState.APPROVED and not package.check_perm(current_user, Permission.EDIT_PACKAGE):
|
||||||
return render_template("packages/gone.html", package=package), 403
|
return render_template("packages/gone.html", package=package), 403
|
||||||
|
|
||||||
show_similar = not package.approved and (
|
show_similar = not package.approved and (
|
||||||
current_user in package.maintainers or
|
current_user in package.maintainers or
|
||||||
package.checkPerm(current_user, Permission.APPROVE_NEW))
|
package.check_perm(current_user, Permission.APPROVE_NEW))
|
||||||
|
|
||||||
conflicting_modnames = None
|
conflicting_modnames = None
|
||||||
if show_similar and package.type != PackageType.TXP:
|
if show_similar and package.type != PackageType.TXP:
|
||||||
@ -153,7 +153,7 @@ def view(package):
|
|||||||
releases = getReleases(package)
|
releases = getReleases(package)
|
||||||
|
|
||||||
review_thread = package.review_thread
|
review_thread = package.review_thread
|
||||||
if review_thread is not None and not review_thread.checkPerm(current_user, Permission.SEE_THREAD):
|
if review_thread is not None and not review_thread.check_perm(current_user, Permission.SEE_THREAD):
|
||||||
review_thread = None
|
review_thread = None
|
||||||
|
|
||||||
topic_error = None
|
topic_error = None
|
||||||
@ -209,7 +209,7 @@ def shield(package, type):
|
|||||||
@bp.route("/packages/<author>/<name>/download/")
|
@bp.route("/packages/<author>/<name>/download/")
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def download(package):
|
def download(package):
|
||||||
release = package.getDownloadRelease()
|
release = package.get_download_release()
|
||||||
|
|
||||||
if release is None:
|
if release is None:
|
||||||
if "application/zip" in request.accept_mimetypes and \
|
if "application/zip" in request.accept_mimetypes and \
|
||||||
@ -217,9 +217,9 @@ def download(package):
|
|||||||
return "", 204
|
return "", 204
|
||||||
else:
|
else:
|
||||||
flash(gettext("No download available."), "danger")
|
flash(gettext("No download available."), "danger")
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
else:
|
else:
|
||||||
return redirect(release.getDownloadURL())
|
return redirect(release.get_download_url())
|
||||||
|
|
||||||
|
|
||||||
def makeLabel(obj):
|
def makeLabel(obj):
|
||||||
@ -269,7 +269,7 @@ def handle_create_edit(package: typing.Optional[Package], form: PackageForm, aut
|
|||||||
"danger")
|
"danger")
|
||||||
else:
|
else:
|
||||||
flash(markupsafe.Markup(
|
flash(markupsafe.Markup(
|
||||||
f"<a class='btn btn-sm btn-danger float-right' href='{package.getURL('packages.view')}'>View</a>" +
|
f"<a class='btn btn-sm btn-danger float-right' href='{package.get_url('packages.view')}'>View</a>" +
|
||||||
gettext("Package already exists")), "danger")
|
gettext("Package already exists")), "danger")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -301,16 +301,16 @@ def handle_create_edit(package: typing.Optional[Package], form: PackageForm, aut
|
|||||||
|
|
||||||
if wasNew:
|
if wasNew:
|
||||||
msg = f"Created package {author.username}/{form.name.data}"
|
msg = f"Created package {author.username}/{form.name.data}"
|
||||||
addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.getURL("packages.view"), package)
|
addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
if wasNew and package.repo is not None:
|
if wasNew and package.repo is not None:
|
||||||
importRepoScreenshot.delay(package.id)
|
importRepoScreenshot.delay(package.id)
|
||||||
|
|
||||||
next_url = package.getURL("packages.view")
|
next_url = package.get_url("packages.view")
|
||||||
if wasNew and ("WTFPL" in package.license.name or "WTFPL" in package.media_license.name):
|
if wasNew and ("WTFPL" in package.license.name or "WTFPL" in package.media_license.name):
|
||||||
next_url = url_for("flatpage", path="help/wtfpl", r=next_url)
|
next_url = url_for("flatpage", path="help/wtfpl", r=next_url)
|
||||||
elif wasNew:
|
elif wasNew:
|
||||||
next_url = package.getURL("packages.setup_releases")
|
next_url = package.get_url("packages.setup_releases")
|
||||||
|
|
||||||
return redirect(next_url)
|
return redirect(next_url)
|
||||||
except LogicError as e:
|
except LogicError as e:
|
||||||
@ -333,7 +333,7 @@ def create_edit(author=None, name=None):
|
|||||||
flash(gettext("Unable to find that user"), "danger")
|
flash(gettext("Unable to find that user"), "danger")
|
||||||
return redirect(url_for("packages.create_edit"))
|
return redirect(url_for("packages.create_edit"))
|
||||||
|
|
||||||
if not author.checkPerm(current_user, Permission.CHANGE_AUTHOR):
|
if not author.check_perm(current_user, Permission.CHANGE_AUTHOR):
|
||||||
flash(gettext("Permission denied"), "danger")
|
flash(gettext("Permission denied"), "danger")
|
||||||
return redirect(url_for("packages.create_edit"))
|
return redirect(url_for("packages.create_edit"))
|
||||||
|
|
||||||
@ -341,8 +341,8 @@ def create_edit(author=None, name=None):
|
|||||||
package = getPackageByInfo(author, name)
|
package = getPackageByInfo(author, name)
|
||||||
if package is None:
|
if package is None:
|
||||||
abort(404)
|
abort(404)
|
||||||
if not package.checkPerm(current_user, Permission.EDIT_PACKAGE):
|
if not package.check_perm(current_user, Permission.EDIT_PACKAGE):
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
author = package.author
|
author = package.author
|
||||||
|
|
||||||
@ -389,9 +389,9 @@ def move_to_state(package):
|
|||||||
if state is None:
|
if state is None:
|
||||||
abort(400)
|
abort(400)
|
||||||
|
|
||||||
if not package.canMoveToState(current_user, state):
|
if not package.can_move_to_state(current_user, state):
|
||||||
flash(gettext("You don't have permission to do that"), "danger")
|
flash(gettext("You don't have permission to do that"), "danger")
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
package.state = state
|
package.state = state
|
||||||
msg = "Marked {} as {}".format(package.title, state.value)
|
msg = "Marked {} as {}".format(package.title, state.value)
|
||||||
@ -399,8 +399,8 @@ def move_to_state(package):
|
|||||||
if state == PackageState.APPROVED:
|
if state == PackageState.APPROVED:
|
||||||
if not package.approved_at:
|
if not package.approved_at:
|
||||||
post_discord_webhook.delay(package.author.username,
|
post_discord_webhook.delay(package.author.username,
|
||||||
"New package {}".format(package.getURL("packages.view", absolute=True)), False,
|
"New package {}".format(package.get_url("packages.view", absolute=True)), False,
|
||||||
package.title, package.short_desc, package.getThumbnailURL(2, True))
|
package.title, package.short_desc, package.get_thumb_url(2, True))
|
||||||
package.approved_at = datetime.datetime.now()
|
package.approved_at = datetime.datetime.now()
|
||||||
|
|
||||||
screenshots = PackageScreenshot.query.filter_by(package=package, approved=False).all()
|
screenshots = PackageScreenshot.query.filter_by(package=package, approved=False).all()
|
||||||
@ -410,23 +410,23 @@ def move_to_state(package):
|
|||||||
msg = "Approved {}".format(package.title)
|
msg = "Approved {}".format(package.title)
|
||||||
elif state == PackageState.READY_FOR_REVIEW:
|
elif state == PackageState.READY_FOR_REVIEW:
|
||||||
post_discord_webhook.delay(package.author.username,
|
post_discord_webhook.delay(package.author.username,
|
||||||
"Ready for Review: {}".format(package.getURL("packages.view", absolute=True)), True,
|
"Ready for Review: {}".format(package.get_url("packages.view", absolute=True)), True,
|
||||||
package.title, package.short_desc, package.getThumbnailURL(2, True))
|
package.title, package.short_desc, package.get_thumb_url(2, True))
|
||||||
|
|
||||||
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_APPROVAL, msg, package.getURL("packages.view"), package)
|
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_APPROVAL, msg, package.get_url("packages.view"), package)
|
||||||
severity = AuditSeverity.NORMAL if current_user in package.maintainers else AuditSeverity.EDITOR
|
severity = AuditSeverity.NORMAL if current_user in package.maintainers else AuditSeverity.EDITOR
|
||||||
addAuditLog(severity, current_user, msg, package.getURL("packages.view"), package)
|
addAuditLog(severity, current_user, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
if package.state == PackageState.CHANGES_NEEDED:
|
if package.state == PackageState.CHANGES_NEEDED:
|
||||||
flash(gettext("Please comment what changes are needed in the approval thread"), "warning")
|
flash(gettext("Please comment what changes are needed in the approval thread"), "warning")
|
||||||
if package.review_thread:
|
if package.review_thread:
|
||||||
return redirect(package.review_thread.getViewURL())
|
return redirect(package.review_thread.get_view_url())
|
||||||
else:
|
else:
|
||||||
return redirect(url_for('threads.new', pid=package.id, title='Package approval comments'))
|
return redirect(url_for('threads.new', pid=package.id, title='Package approval comments'))
|
||||||
|
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/packages/<author>/<name>/remove/", methods=["GET", "POST"])
|
@bp.route("/packages/<author>/<name>/remove/", methods=["GET", "POST"])
|
||||||
@ -440,9 +440,9 @@ def remove(package):
|
|||||||
reason = request.form.get("reason") or "?"
|
reason = request.form.get("reason") or "?"
|
||||||
|
|
||||||
if "delete" in request.form:
|
if "delete" in request.form:
|
||||||
if not package.checkPerm(current_user, Permission.DELETE_PACKAGE):
|
if not package.check_perm(current_user, Permission.DELETE_PACKAGE):
|
||||||
flash(gettext("You don't have permission to do that"), "danger")
|
flash(gettext("You don't have permission to do that"), "danger")
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
package.state = PackageState.DELETED
|
package.state = PackageState.DELETED
|
||||||
|
|
||||||
@ -456,21 +456,21 @@ def remove(package):
|
|||||||
|
|
||||||
return redirect(url)
|
return redirect(url)
|
||||||
elif "unapprove" in request.form:
|
elif "unapprove" in request.form:
|
||||||
if not package.checkPerm(current_user, Permission.UNAPPROVE_PACKAGE):
|
if not package.check_perm(current_user, Permission.UNAPPROVE_PACKAGE):
|
||||||
flash(gettext("You don't have permission to do that"), "danger")
|
flash(gettext("You don't have permission to do that"), "danger")
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
package.state = PackageState.WIP
|
package.state = PackageState.WIP
|
||||||
|
|
||||||
msg = "Unapproved {}, reason={}".format(package.title, reason)
|
msg = "Unapproved {}, reason={}".format(package.title, reason)
|
||||||
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_APPROVAL, msg, package.getURL("packages.view"), package)
|
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_APPROVAL, msg, package.get_url("packages.view"), package)
|
||||||
addAuditLog(AuditSeverity.EDITOR, current_user, msg, package.getURL("packages.view"), package)
|
addAuditLog(AuditSeverity.EDITOR, current_user, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
flash(gettext("Unapproved package"), "success")
|
flash(gettext("Unapproved package"), "success")
|
||||||
|
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
else:
|
else:
|
||||||
abort(400)
|
abort(400)
|
||||||
|
|
||||||
@ -485,9 +485,9 @@ class PackageMaintainersForm(FlaskForm):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def edit_maintainers(package):
|
def edit_maintainers(package):
|
||||||
if not package.checkPerm(current_user, Permission.EDIT_MAINTAINERS):
|
if not package.check_perm(current_user, Permission.EDIT_MAINTAINERS):
|
||||||
flash(gettext("You don't have permission to edit maintainers"), "danger")
|
flash(gettext("You don't have permission to edit maintainers"), "danger")
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
form = PackageMaintainersForm(formdata=request.form)
|
form = PackageMaintainersForm(formdata=request.form)
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
@ -504,12 +504,12 @@ def edit_maintainers(package):
|
|||||||
if thread:
|
if thread:
|
||||||
thread.watchers.append(user)
|
thread.watchers.append(user)
|
||||||
addNotification(user, current_user, NotificationType.MAINTAINER,
|
addNotification(user, current_user, NotificationType.MAINTAINER,
|
||||||
"Added you as a maintainer of {}".format(package.title), package.getURL("packages.view"), package)
|
"Added you as a maintainer of {}".format(package.title), package.get_url("packages.view"), package)
|
||||||
|
|
||||||
for user in package.maintainers:
|
for user in package.maintainers:
|
||||||
if user != package.author and not user in users:
|
if user != package.author and not user in users:
|
||||||
addNotification(user, current_user, NotificationType.MAINTAINER,
|
addNotification(user, current_user, NotificationType.MAINTAINER,
|
||||||
"Removed you as a maintainer of {}".format(package.title), package.getURL("packages.view"), package)
|
"Removed you as a maintainer of {}".format(package.title), package.get_url("packages.view"), package)
|
||||||
|
|
||||||
package.maintainers.clear()
|
package.maintainers.clear()
|
||||||
package.maintainers.extend(users)
|
package.maintainers.extend(users)
|
||||||
@ -517,13 +517,13 @@ def edit_maintainers(package):
|
|||||||
package.maintainers.append(package.author)
|
package.maintainers.append(package.author)
|
||||||
|
|
||||||
msg = "Edited {} maintainers".format(package.title)
|
msg = "Edited {} maintainers".format(package.title)
|
||||||
addNotification(package.author, current_user, NotificationType.MAINTAINER, msg, package.getURL("packages.view"), package)
|
addNotification(package.author, current_user, NotificationType.MAINTAINER, msg, package.get_url("packages.view"), package)
|
||||||
severity = AuditSeverity.NORMAL if current_user == package.author else AuditSeverity.MODERATION
|
severity = AuditSeverity.NORMAL if current_user == package.author else AuditSeverity.MODERATION
|
||||||
addAuditLog(severity, current_user, msg, package.getURL("packages.view"), package)
|
addAuditLog(severity, current_user, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
users = User.query.filter(User.rank >= UserRank.NEW_MEMBER).order_by(db.asc(User.username)).all()
|
users = User.query.filter(User.rank >= UserRank.NEW_MEMBER).order_by(db.asc(User.username)).all()
|
||||||
|
|
||||||
@ -545,19 +545,19 @@ def remove_self_maintainers(package):
|
|||||||
package.maintainers.remove(current_user)
|
package.maintainers.remove(current_user)
|
||||||
|
|
||||||
addNotification(package.author, current_user, NotificationType.MAINTAINER,
|
addNotification(package.author, current_user, NotificationType.MAINTAINER,
|
||||||
"Removed themself as a maintainer of {}".format(package.title), package.getURL("packages.view"), package)
|
"Removed themself as a maintainer of {}".format(package.title), package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/packages/<author>/<name>/audit/")
|
@bp.route("/packages/<author>/<name>/audit/")
|
||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def audit(package):
|
def audit(package):
|
||||||
if not (package.checkPerm(current_user, Permission.EDIT_PACKAGE) or
|
if not (package.check_perm(current_user, Permission.EDIT_PACKAGE) or
|
||||||
package.checkPerm(current_user, Permission.APPROVE_NEW)):
|
package.check_perm(current_user, Permission.APPROVE_NEW)):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
page = get_int_or_abort(request.args.get("page"), 1)
|
page = get_int_or_abort(request.args.get("page"), 1)
|
||||||
@ -605,7 +605,7 @@ def alias_create_edit(package: Package, alias_id: int = None):
|
|||||||
form.populate_obj(alias)
|
form.populate_obj(alias)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(package.getURL("packages.alias_list"))
|
return redirect(package.get_url("packages.alias_list"))
|
||||||
|
|
||||||
return render_template("packages/alias_create_edit.html", package=package, form=form)
|
return render_template("packages/alias_create_edit.html", package=package, form=form)
|
||||||
|
|
||||||
@ -655,8 +655,8 @@ def game_support(package):
|
|||||||
if package.type != PackageType.MOD and package.type != PackageType.TXP:
|
if package.type != PackageType.MOD and package.type != PackageType.TXP:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
can_edit = package.checkPerm(current_user, Permission.EDIT_PACKAGE)
|
can_edit = package.check_perm(current_user, Permission.EDIT_PACKAGE)
|
||||||
if not (can_edit or package.checkPerm(current_user, Permission.APPROVE_NEW)):
|
if not (can_edit or package.check_perm(current_user, Permission.APPROVE_NEW)):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
force_game_detection = package.supported_games.filter(and_(
|
force_game_detection = package.supported_games.filter(and_(
|
||||||
@ -694,7 +694,7 @@ def game_support(package):
|
|||||||
except LogicError as e:
|
except LogicError as e:
|
||||||
flash(e.message, "danger")
|
flash(e.message, "danger")
|
||||||
|
|
||||||
next_url = package.getURL("packages.game_support")
|
next_url = package.get_url("packages.game_support")
|
||||||
|
|
||||||
enable_support_detection = form.enable_support_detection.data or force_game_detection
|
enable_support_detection = form.enable_support_detection.data or force_game_detection
|
||||||
if enable_support_detection != package.enable_game_support_detection:
|
if enable_support_detection != package.enable_game_support_detection:
|
||||||
@ -706,7 +706,7 @@ def game_support(package):
|
|||||||
|
|
||||||
package.supports_all_games = form.supports_all_games.data
|
package.supports_all_games = form.supports_all_games.data
|
||||||
|
|
||||||
addAuditLog(AuditSeverity.NORMAL, current_user, "Edited game support", package.getURL("packages.game_support"), package)
|
addAuditLog(AuditSeverity.NORMAL, current_user, "Edited game support", package.get_url("packages.game_support"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@ -76,8 +76,8 @@ class EditPackageReleaseForm(FlaskForm):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def create_release(package):
|
def create_release(package):
|
||||||
if not package.checkPerm(current_user, Permission.MAKE_RELEASE):
|
if not package.check_perm(current_user, Permission.MAKE_RELEASE):
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
# Initial form class from post data and default data
|
# Initial form class from post data and default data
|
||||||
form = CreatePackageReleaseForm()
|
form = CreatePackageReleaseForm()
|
||||||
@ -94,11 +94,11 @@ def create_release(package):
|
|||||||
try:
|
try:
|
||||||
if form["uploadOpt"].data == "vcs":
|
if form["uploadOpt"].data == "vcs":
|
||||||
rel = do_create_vcs_release(current_user, package, form.title.data,
|
rel = do_create_vcs_release(current_user, package, form.title.data,
|
||||||
form.vcsLabel.data, form.min_rel.data.getActual(), form.max_rel.data.getActual())
|
form.vcsLabel.data, form.min_rel.data.get_actual(), form.max_rel.data.get_actual())
|
||||||
else:
|
else:
|
||||||
rel = do_create_zip_release(current_user, package, form.title.data,
|
rel = do_create_zip_release(current_user, package, form.title.data,
|
||||||
form.file_upload.data, form.min_rel.data.getActual(), form.max_rel.data.getActual())
|
form.file_upload.data, form.min_rel.data.get_actual(), form.max_rel.data.get_actual())
|
||||||
return redirect(url_for("tasks.check", id=rel.task_id, r=rel.getEditURL()))
|
return redirect(url_for("tasks.check", id=rel.task_id, r=rel.get_edit_url()))
|
||||||
except LogicError as e:
|
except LogicError as e:
|
||||||
flash(e.message, "danger")
|
flash(e.message, "danger")
|
||||||
|
|
||||||
@ -151,10 +151,10 @@ def edit_release(package, id):
|
|||||||
if release is None or release.package != package:
|
if release is None or release.package != package:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
canEdit = package.checkPerm(current_user, Permission.MAKE_RELEASE)
|
canEdit = package.check_perm(current_user, Permission.MAKE_RELEASE)
|
||||||
canApprove = release.checkPerm(current_user, Permission.APPROVE_RELEASE)
|
canApprove = release.check_perm(current_user, Permission.APPROVE_RELEASE)
|
||||||
if not (canEdit or canApprove):
|
if not (canEdit or canApprove):
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
# Initial form class from post data and default data
|
# Initial form class from post data and default data
|
||||||
form = EditPackageReleaseForm(formdata=request.form, obj=release)
|
form = EditPackageReleaseForm(formdata=request.form, obj=release)
|
||||||
@ -166,10 +166,10 @@ def edit_release(package, id):
|
|||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if canEdit:
|
if canEdit:
|
||||||
release.title = form["title"].data
|
release.title = form["title"].data
|
||||||
release.min_rel = form["min_rel"].data.getActual()
|
release.min_rel = form["min_rel"].data.get_actual()
|
||||||
release.max_rel = form["max_rel"].data.getActual()
|
release.max_rel = form["max_rel"].data.get_actual()
|
||||||
|
|
||||||
if package.checkPerm(current_user, Permission.CHANGE_RELEASE_URL):
|
if package.check_perm(current_user, Permission.CHANGE_RELEASE_URL):
|
||||||
release.url = form["url"].data
|
release.url = form["url"].data
|
||||||
release.task_id = form["task_id"].data
|
release.task_id = form["task_id"].data
|
||||||
if release.task_id is not None:
|
if release.task_id is not None:
|
||||||
@ -181,7 +181,7 @@ def edit_release(package, id):
|
|||||||
release.approved = False
|
release.approved = False
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(package.getURL("packages.list_releases"))
|
return redirect(package.get_url("packages.list_releases"))
|
||||||
|
|
||||||
return render_template("packages/release_edit.html", package=package, release=release, form=form)
|
return render_template("packages/release_edit.html", package=package, release=release, form=form)
|
||||||
|
|
||||||
@ -202,8 +202,8 @@ class BulkReleaseForm(FlaskForm):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def bulk_change_release(package):
|
def bulk_change_release(package):
|
||||||
if not package.checkPerm(current_user, Permission.MAKE_RELEASE):
|
if not package.check_perm(current_user, Permission.MAKE_RELEASE):
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
# Initial form class from post data and default data
|
# Initial form class from post data and default data
|
||||||
form = BulkReleaseForm()
|
form = BulkReleaseForm()
|
||||||
@ -215,13 +215,13 @@ def bulk_change_release(package):
|
|||||||
|
|
||||||
for release in package.releases.all():
|
for release in package.releases.all():
|
||||||
if form["set_min"].data and (not only_change_none or release.min_rel is None):
|
if form["set_min"].data and (not only_change_none or release.min_rel is None):
|
||||||
release.min_rel = form["min_rel"].data.getActual()
|
release.min_rel = form["min_rel"].data.get_actual()
|
||||||
if form["set_max"].data and (not only_change_none or release.max_rel is None):
|
if form["set_max"].data and (not only_change_none or release.max_rel is None):
|
||||||
release.max_rel = form["max_rel"].data.getActual()
|
release.max_rel = form["max_rel"].data.get_actual()
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(package.getURL("packages.list_releases"))
|
return redirect(package.get_url("packages.list_releases"))
|
||||||
|
|
||||||
return render_template("packages/release_bulk_change.html", package=package, form=form)
|
return render_template("packages/release_bulk_change.html", package=package, form=form)
|
||||||
|
|
||||||
@ -234,13 +234,13 @@ def delete_release(package, id):
|
|||||||
if release is None or release.package != package:
|
if release is None or release.package != package:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not release.checkPerm(current_user, Permission.DELETE_RELEASE):
|
if not release.check_perm(current_user, Permission.DELETE_RELEASE):
|
||||||
return redirect(package.getURL("packages.list_releases"))
|
return redirect(package.get_url("packages.list_releases"))
|
||||||
|
|
||||||
db.session.delete(release)
|
db.session.delete(release)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
|
|
||||||
class PackageUpdateConfigFrom(FlaskForm):
|
class PackageUpdateConfigFrom(FlaskForm):
|
||||||
@ -288,12 +288,12 @@ def set_update_config(package, form):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def update_config(package):
|
def update_config(package):
|
||||||
if not package.checkPerm(current_user, Permission.MAKE_RELEASE):
|
if not package.check_perm(current_user, Permission.MAKE_RELEASE):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
if not package.repo:
|
if not package.repo:
|
||||||
flash(gettext("Please add a Git repository URL in order to set up automatic releases"), "danger")
|
flash(gettext("Please add a Git repository URL in order to set up automatic releases"), "danger")
|
||||||
return redirect(package.getURL("packages.create_edit"))
|
return redirect(package.get_url("packages.create_edit"))
|
||||||
|
|
||||||
form = PackageUpdateConfigFrom(obj=package.update_config)
|
form = PackageUpdateConfigFrom(obj=package.update_config)
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
@ -317,9 +317,9 @@ def update_config(package):
|
|||||||
|
|
||||||
if not form.disable.data and package.releases.count() == 0:
|
if not form.disable.data and package.releases.count() == 0:
|
||||||
flash(gettext("Now, please create an initial release"), "success")
|
flash(gettext("Now, please create an initial release"), "success")
|
||||||
return redirect(package.getURL("packages.create_release"))
|
return redirect(package.get_url("packages.create_release"))
|
||||||
|
|
||||||
return redirect(package.getURL("packages.list_releases"))
|
return redirect(package.get_url("packages.list_releases"))
|
||||||
|
|
||||||
return render_template("packages/update_config.html", package=package, form=form)
|
return render_template("packages/update_config.html", package=package, form=form)
|
||||||
|
|
||||||
@ -328,11 +328,11 @@ def update_config(package):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def setup_releases(package):
|
def setup_releases(package):
|
||||||
if not package.checkPerm(current_user, Permission.MAKE_RELEASE):
|
if not package.check_perm(current_user, Permission.MAKE_RELEASE):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
if package.update_config:
|
if package.update_config:
|
||||||
return redirect(package.getURL("packages.update_config"))
|
return redirect(package.get_url("packages.update_config"))
|
||||||
|
|
||||||
return render_template("packages/release_wizard.html", package=package)
|
return render_template("packages/release_wizard.html", package=package)
|
||||||
|
|
||||||
|
@ -54,13 +54,13 @@ class ReviewForm(FlaskForm):
|
|||||||
def review(package):
|
def review(package):
|
||||||
if current_user in package.maintainers:
|
if current_user in package.maintainers:
|
||||||
flash(gettext("You can't review your own package!"), "danger")
|
flash(gettext("You can't review your own package!"), "danger")
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
if package.state != PackageState.APPROVED:
|
if package.state != PackageState.APPROVED:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
review = PackageReview.query.filter_by(package=package, author=current_user).first()
|
review = PackageReview.query.filter_by(package=package, author=current_user).first()
|
||||||
can_review = review is not None or current_user.canReviewRL()
|
can_review = review is not None or current_user.can_review_ratelimit()
|
||||||
|
|
||||||
if not can_review:
|
if not can_review:
|
||||||
flash(gettext("You've reviewed too many packages recently. Please wait before trying again, and consider making your reviews more detailed"), "danger")
|
flash(gettext("You've reviewed too many packages recently. Please wait before trying again, and consider making your reviews more detailed"), "danger")
|
||||||
@ -75,7 +75,7 @@ def review(package):
|
|||||||
|
|
||||||
# Validate and submit
|
# Validate and submit
|
||||||
elif can_review and form.validate_on_submit():
|
elif can_review and form.validate_on_submit():
|
||||||
if has_blocked_domains(form.comment.data, current_user.username, f"review of {package.getId()}"):
|
if has_blocked_domains(form.comment.data, current_user.username, f"review of {package.get_id()}"):
|
||||||
flash(gettext("Linking to blocked sites is not allowed"), "danger")
|
flash(gettext("Linking to blocked sites is not allowed"), "danger")
|
||||||
else:
|
else:
|
||||||
was_new = False
|
was_new = False
|
||||||
@ -114,7 +114,7 @@ def review(package):
|
|||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
package.recalcScore()
|
package.recalculate_score()
|
||||||
|
|
||||||
if was_new:
|
if was_new:
|
||||||
notif_msg = "New review '{}'".format(form.title.data)
|
notif_msg = "New review '{}'".format(form.title.data)
|
||||||
@ -128,11 +128,11 @@ def review(package):
|
|||||||
|
|
||||||
if was_new:
|
if was_new:
|
||||||
post_discord_webhook.delay(thread.author.username,
|
post_discord_webhook.delay(thread.author.username,
|
||||||
"Reviewed {}: {}".format(package.title, thread.getViewURL(absolute=True)), False)
|
"Reviewed {}: {}".format(package.title, thread.get_view_url(absolute=True)), False)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
return render_template("packages/review_create_edit.html",
|
return render_template("packages/review_create_edit.html",
|
||||||
form=form, package=package, review=review)
|
form=form, package=package, review=review)
|
||||||
@ -148,7 +148,7 @@ def delete_review(package, reviewer):
|
|||||||
if review is None or review.package != package:
|
if review is None or review.package != package:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not review.checkPerm(current_user, Permission.DELETE_REVIEW):
|
if not review.check_perm(current_user, Permission.DELETE_REVIEW):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
thread = review.thread
|
thread = review.thread
|
||||||
@ -164,18 +164,18 @@ def delete_review(package, reviewer):
|
|||||||
|
|
||||||
msg = "Converted review by {} to thread".format(review.author.display_name)
|
msg = "Converted review by {} to thread".format(review.author.display_name)
|
||||||
addAuditLog(AuditSeverity.MODERATION if current_user.username != reviewer else AuditSeverity.NORMAL,
|
addAuditLog(AuditSeverity.MODERATION if current_user.username != reviewer else AuditSeverity.NORMAL,
|
||||||
current_user, msg, thread.getViewURL(), thread.package)
|
current_user, msg, thread.get_view_url(), thread.package)
|
||||||
|
|
||||||
notif_msg = "Deleted review '{}', comments were kept as a thread".format(thread.title)
|
notif_msg = "Deleted review '{}', comments were kept as a thread".format(thread.title)
|
||||||
addNotification(package.maintainers, current_user, NotificationType.OTHER, notif_msg, url_for("threads.view", id=thread.id), package)
|
addNotification(package.maintainers, current_user, NotificationType.OTHER, notif_msg, url_for("threads.view", id=thread.id), package)
|
||||||
|
|
||||||
db.session.delete(review)
|
db.session.delete(review)
|
||||||
|
|
||||||
package.recalcScore()
|
package.recalculate_score()
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
|
|
||||||
def handle_review_vote(package: Package, review_id: int):
|
def handle_review_vote(package: Package, review_id: int):
|
||||||
@ -219,7 +219,7 @@ def review_vote(package, review_id):
|
|||||||
if next_url and is_safe_url(next_url):
|
if next_url and is_safe_url(next_url):
|
||||||
return redirect(next_url)
|
return redirect(next_url)
|
||||||
else:
|
else:
|
||||||
return redirect(review.thread.getViewURL())
|
return redirect(review.thread.get_view_url())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/packages/<author>/<name>/review-votes/")
|
@bp.route("/packages/<author>/<name>/review-votes/")
|
||||||
@ -228,7 +228,7 @@ def review_vote(package, review_id):
|
|||||||
def review_votes(package):
|
def review_votes(package):
|
||||||
user_biases = {}
|
user_biases = {}
|
||||||
for review in package.reviews:
|
for review in package.reviews:
|
||||||
review_sign = review.asWeight()
|
review_sign = review.as_weight()
|
||||||
for vote in review.votes:
|
for vote in review.votes:
|
||||||
user_biases[vote.user.username] = user_biases.get(vote.user.username, [0, 0])
|
user_biases[vote.user.username] = user_biases.get(vote.user.username, [0, 0])
|
||||||
vote_sign = 1 if vote.is_positive else -1
|
vote_sign = 1 if vote.is_positive else -1
|
||||||
|
@ -50,8 +50,8 @@ class EditPackageScreenshotsForm(FlaskForm):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def screenshots(package):
|
def screenshots(package):
|
||||||
if not package.checkPerm(current_user, Permission.ADD_SCREENSHOTS):
|
if not package.check_perm(current_user, Permission.ADD_SCREENSHOTS):
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
form = EditPackageScreenshotsForm(obj=package)
|
form = EditPackageScreenshotsForm(obj=package)
|
||||||
form.cover_image.query = package.screenshots
|
form.cover_image.query = package.screenshots
|
||||||
@ -61,7 +61,7 @@ def screenshots(package):
|
|||||||
if order:
|
if order:
|
||||||
try:
|
try:
|
||||||
do_order_screenshots(current_user, package, order.split(","))
|
do_order_screenshots(current_user, package, order.split(","))
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
except LogicError as e:
|
except LogicError as e:
|
||||||
flash(e.message, "danger")
|
flash(e.message, "danger")
|
||||||
|
|
||||||
@ -77,15 +77,15 @@ def screenshots(package):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def create_screenshot(package):
|
def create_screenshot(package):
|
||||||
if not package.checkPerm(current_user, Permission.ADD_SCREENSHOTS):
|
if not package.check_perm(current_user, Permission.ADD_SCREENSHOTS):
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
|
|
||||||
# Initial form class from post data and default data
|
# Initial form class from post data and default data
|
||||||
form = CreateScreenshotForm()
|
form = CreateScreenshotForm()
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
try:
|
try:
|
||||||
do_create_screenshot(current_user, package, form.title.data, form.file_upload.data, False)
|
do_create_screenshot(current_user, package, form.title.data, form.file_upload.data, False)
|
||||||
return redirect(package.getURL("packages.screenshots"))
|
return redirect(package.get_url("packages.screenshots"))
|
||||||
except LogicError as e:
|
except LogicError as e:
|
||||||
flash(e.message, "danger")
|
flash(e.message, "danger")
|
||||||
|
|
||||||
@ -100,10 +100,10 @@ def edit_screenshot(package, id):
|
|||||||
if screenshot is None or screenshot.package != package:
|
if screenshot is None or screenshot.package != package:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
canEdit = package.checkPerm(current_user, Permission.ADD_SCREENSHOTS)
|
canEdit = package.check_perm(current_user, Permission.ADD_SCREENSHOTS)
|
||||||
canApprove = package.checkPerm(current_user, Permission.APPROVE_SCREENSHOT)
|
canApprove = package.check_perm(current_user, Permission.APPROVE_SCREENSHOT)
|
||||||
if not (canEdit or canApprove):
|
if not (canEdit or canApprove):
|
||||||
return redirect(package.getURL("packages.screenshots"))
|
return redirect(package.get_url("packages.screenshots"))
|
||||||
|
|
||||||
# Initial form class from post data and default data
|
# Initial form class from post data and default data
|
||||||
form = EditScreenshotForm(obj=screenshot)
|
form = EditScreenshotForm(obj=screenshot)
|
||||||
@ -119,7 +119,7 @@ def edit_screenshot(package, id):
|
|||||||
screenshot.approved = wasApproved
|
screenshot.approved = wasApproved
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return redirect(package.getURL("packages.screenshots"))
|
return redirect(package.get_url("packages.screenshots"))
|
||||||
|
|
||||||
return render_template("packages/screenshot_edit.html", package=package, screenshot=screenshot, form=form)
|
return render_template("packages/screenshot_edit.html", package=package, screenshot=screenshot, form=form)
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ def delete_screenshot(package, id):
|
|||||||
if screenshot is None or screenshot.package != package:
|
if screenshot is None or screenshot.package != package:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not package.checkPerm(current_user, Permission.ADD_SCREENSHOTS):
|
if not package.check_perm(current_user, Permission.ADD_SCREENSHOTS):
|
||||||
flash(gettext("Permission denied"), "danger")
|
flash(gettext("Permission denied"), "danger")
|
||||||
return redirect(url_for("homepage.home"))
|
return redirect(url_for("homepage.home"))
|
||||||
|
|
||||||
@ -143,4 +143,4 @@ def delete_screenshot(package, id):
|
|||||||
db.session.delete(screenshot)
|
db.session.delete(screenshot)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(package.getURL("packages.screenshots"))
|
return redirect(package.get_url("packages.screenshots"))
|
||||||
|
@ -60,7 +60,7 @@ def list_all():
|
|||||||
@login_required
|
@login_required
|
||||||
def subscribe(id):
|
def subscribe(id):
|
||||||
thread = Thread.query.get(id)
|
thread = Thread.query.get(id)
|
||||||
if thread is None or not thread.checkPerm(current_user, Permission.SEE_THREAD):
|
if thread is None or not thread.check_perm(current_user, Permission.SEE_THREAD):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if current_user in thread.watchers:
|
if current_user in thread.watchers:
|
||||||
@ -70,14 +70,14 @@ def subscribe(id):
|
|||||||
thread.watchers.append(current_user)
|
thread.watchers.append(current_user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/threads/<int:id>/unsubscribe/", methods=["POST"])
|
@bp.route("/threads/<int:id>/unsubscribe/", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def unsubscribe(id):
|
def unsubscribe(id):
|
||||||
thread = Thread.query.get(id)
|
thread = Thread.query.get(id)
|
||||||
if thread is None or not thread.checkPerm(current_user, Permission.SEE_THREAD):
|
if thread is None or not thread.check_perm(current_user, Permission.SEE_THREAD):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if current_user in thread.watchers:
|
if current_user in thread.watchers:
|
||||||
@ -87,14 +87,14 @@ def unsubscribe(id):
|
|||||||
else:
|
else:
|
||||||
flash(gettext("Already not subscribed!"), "success")
|
flash(gettext("Already not subscribed!"), "success")
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/threads/<int:id>/set-lock/", methods=["POST"])
|
@bp.route("/threads/<int:id>/set-lock/", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def set_lock(id):
|
def set_lock(id):
|
||||||
thread = Thread.query.get(id)
|
thread = Thread.query.get(id)
|
||||||
if thread is None or not thread.checkPerm(current_user, Permission.LOCK_THREAD):
|
if thread is None or not thread.check_perm(current_user, Permission.LOCK_THREAD):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
thread.locked = isYes(request.args.get("lock"))
|
thread.locked = isYes(request.args.get("lock"))
|
||||||
@ -109,19 +109,19 @@ def set_lock(id):
|
|||||||
msg = "Unlocked thread '{}'".format(thread.title)
|
msg = "Unlocked thread '{}'".format(thread.title)
|
||||||
flash(gettext("Unlocked thread"), "success")
|
flash(gettext("Unlocked thread"), "success")
|
||||||
|
|
||||||
addNotification(thread.watchers, current_user, NotificationType.OTHER, msg, thread.getViewURL(), thread.package)
|
addNotification(thread.watchers, current_user, NotificationType.OTHER, msg, thread.get_view_url(), thread.package)
|
||||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg, thread.getViewURL(), thread.package)
|
addAuditLog(AuditSeverity.MODERATION, current_user, msg, thread.get_view_url(), thread.package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/threads/<int:id>/delete/", methods=["GET", "POST"])
|
@bp.route("/threads/<int:id>/delete/", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def delete_thread(id):
|
def delete_thread(id):
|
||||||
thread = Thread.query.get(id)
|
thread = Thread.query.get(id)
|
||||||
if thread is None or not thread.checkPerm(current_user, Permission.DELETE_THREAD):
|
if thread is None or not thread.check_perm(current_user, Permission.DELETE_THREAD):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
@ -157,21 +157,21 @@ def delete_reply(id):
|
|||||||
|
|
||||||
if thread.first_reply == reply:
|
if thread.first_reply == reply:
|
||||||
flash(gettext("Cannot delete thread opening post!"), "danger")
|
flash(gettext("Cannot delete thread opening post!"), "danger")
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
if not reply.checkPerm(current_user, Permission.DELETE_REPLY):
|
if not reply.check_perm(current_user, Permission.DELETE_REPLY):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
return render_template("threads/delete_reply.html", thread=thread, reply=reply)
|
return render_template("threads/delete_reply.html", thread=thread, reply=reply)
|
||||||
|
|
||||||
msg = "Deleted reply by {}".format(reply.author.display_name)
|
msg = "Deleted reply by {}".format(reply.author.display_name)
|
||||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg, thread.getViewURL(), thread.package, reply.comment)
|
addAuditLog(AuditSeverity.MODERATION, current_user, msg, thread.get_view_url(), thread.package, reply.comment)
|
||||||
|
|
||||||
db.session.delete(reply)
|
db.session.delete(reply)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
|
|
||||||
class CommentForm(FlaskForm):
|
class CommentForm(FlaskForm):
|
||||||
@ -194,7 +194,7 @@ def edit_reply(id):
|
|||||||
if reply is None or reply.thread != thread:
|
if reply is None or reply.thread != thread:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not reply.checkPerm(current_user, Permission.EDIT_REPLY):
|
if not reply.check_perm(current_user, Permission.EDIT_REPLY):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
form = CommentForm(formdata=request.form, obj=reply)
|
form = CommentForm(formdata=request.form, obj=reply)
|
||||||
@ -205,14 +205,14 @@ def edit_reply(id):
|
|||||||
else:
|
else:
|
||||||
msg = "Edited reply by {}".format(reply.author.display_name)
|
msg = "Edited reply by {}".format(reply.author.display_name)
|
||||||
severity = AuditSeverity.NORMAL if current_user == reply.author else AuditSeverity.MODERATION
|
severity = AuditSeverity.NORMAL if current_user == reply.author else AuditSeverity.MODERATION
|
||||||
addNotification(reply.author, current_user, NotificationType.OTHER, msg, thread.getViewURL(), thread.package)
|
addNotification(reply.author, current_user, NotificationType.OTHER, msg, thread.get_view_url(), thread.package)
|
||||||
addAuditLog(severity, current_user, msg, thread.getViewURL(), thread.package, reply.comment)
|
addAuditLog(severity, current_user, msg, thread.get_view_url(), thread.package, reply.comment)
|
||||||
|
|
||||||
reply.comment = comment
|
reply.comment = comment
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
return render_template("threads/edit_reply.html", thread=thread, reply=reply, form=form)
|
return render_template("threads/edit_reply.html", thread=thread, reply=reply, form=form)
|
||||||
|
|
||||||
@ -220,20 +220,20 @@ def edit_reply(id):
|
|||||||
@bp.route("/threads/<int:id>/", methods=["GET", "POST"])
|
@bp.route("/threads/<int:id>/", methods=["GET", "POST"])
|
||||||
def view(id):
|
def view(id):
|
||||||
thread: Thread = Thread.query.get(id)
|
thread: Thread = Thread.query.get(id)
|
||||||
if thread is None or not thread.checkPerm(current_user, Permission.SEE_THREAD):
|
if thread is None or not thread.check_perm(current_user, Permission.SEE_THREAD):
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
form = CommentForm(formdata=request.form) if thread.checkPerm(current_user, Permission.COMMENT_THREAD) else None
|
form = CommentForm(formdata=request.form) if thread.check_perm(current_user, Permission.COMMENT_THREAD) else None
|
||||||
|
|
||||||
# Check that title is none to load comments into textarea if redirected from new thread page
|
# Check that title is none to load comments into textarea if redirected from new thread page
|
||||||
if form and form.validate_on_submit() and request.form.get("title") is None:
|
if form and form.validate_on_submit() and request.form.get("title") is None:
|
||||||
comment = form.comment.data
|
comment = form.comment.data
|
||||||
|
|
||||||
if not current_user.canCommentRL():
|
if not current_user.can_comment_ratelimit():
|
||||||
flash(gettext("Please wait before commenting again"), "danger")
|
flash(gettext("Please wait before commenting again"), "danger")
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
if has_blocked_domains(comment, current_user.username, f"reply to {thread.getViewURL(True)}"):
|
if has_blocked_domains(comment, current_user.username, f"reply to {thread.get_view_url(True)}"):
|
||||||
flash(gettext("Linking to blocked sites is not allowed"), "danger")
|
flash(gettext("Linking to blocked sites is not allowed"), "danger")
|
||||||
return render_template("threads/view.html", thread=thread, form=form)
|
return render_template("threads/view.html", thread=thread, form=form)
|
||||||
|
|
||||||
@ -253,23 +253,23 @@ def view(id):
|
|||||||
|
|
||||||
msg = "Mentioned by {} in '{}'".format(current_user.display_name, thread.title)
|
msg = "Mentioned by {} in '{}'".format(current_user.display_name, thread.title)
|
||||||
addNotification(mentioned, current_user, NotificationType.THREAD_REPLY,
|
addNotification(mentioned, current_user, NotificationType.THREAD_REPLY,
|
||||||
msg, thread.getViewURL(), thread.package)
|
msg, thread.get_view_url(), thread.package)
|
||||||
|
|
||||||
thread.watchers.append(mentioned)
|
thread.watchers.append(mentioned)
|
||||||
|
|
||||||
msg = "New comment on '{}'".format(thread.title)
|
msg = "New comment on '{}'".format(thread.title)
|
||||||
addNotification(thread.watchers, current_user, NotificationType.THREAD_REPLY, msg, thread.getViewURL(), thread.package)
|
addNotification(thread.watchers, current_user, NotificationType.THREAD_REPLY, msg, thread.get_view_url(), thread.package)
|
||||||
|
|
||||||
if thread.author == get_system_user():
|
if thread.author == get_system_user():
|
||||||
approvers = User.query.filter(User.rank >= UserRank.APPROVER).all()
|
approvers = User.query.filter(User.rank >= UserRank.APPROVER).all()
|
||||||
addNotification(approvers, current_user, NotificationType.EDITOR_MISC, msg,
|
addNotification(approvers, current_user, NotificationType.EDITOR_MISC, msg,
|
||||||
thread.getViewURL(), thread.package)
|
thread.get_view_url(), thread.package)
|
||||||
post_discord_webhook.delay(current_user.username,
|
post_discord_webhook.delay(current_user.username,
|
||||||
"Replied to bot messages: {}".format(thread.getViewURL(absolute=True)), True)
|
"Replied to bot messages: {}".format(thread.get_view_url(absolute=True)), True)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
return render_template("threads/view.html", thread=thread, form=form)
|
return render_template("threads/view.html", thread=thread, form=form)
|
||||||
|
|
||||||
@ -300,7 +300,7 @@ def new():
|
|||||||
is_review_thread = package and not package.approved
|
is_review_thread = package and not package.approved
|
||||||
|
|
||||||
# Check that user can make the thread
|
# Check that user can make the thread
|
||||||
if package and not package.checkPerm(current_user, Permission.CREATE_THREAD):
|
if package and not package.check_perm(current_user, Permission.CREATE_THREAD):
|
||||||
flash(gettext("Unable to create thread!"), "danger")
|
flash(gettext("Unable to create thread!"), "danger")
|
||||||
return redirect(url_for("homepage.home"))
|
return redirect(url_for("homepage.home"))
|
||||||
|
|
||||||
@ -308,13 +308,13 @@ def new():
|
|||||||
elif is_review_thread and package.review_thread is not None:
|
elif is_review_thread and package.review_thread is not None:
|
||||||
# Redirect submit to `view` page, which checks for `title` in the form data and so won't commit the reply
|
# Redirect submit to `view` page, which checks for `title` in the form data and so won't commit the reply
|
||||||
flash(gettext("An approval thread already exists! Consider replying there instead"), "danger")
|
flash(gettext("An approval thread already exists! Consider replying there instead"), "danger")
|
||||||
return redirect(package.review_thread.getViewURL(), code=307)
|
return redirect(package.review_thread.get_view_url(), code=307)
|
||||||
|
|
||||||
elif not current_user.canOpenThreadRL():
|
elif not current_user.can_open_thread_ratelimit():
|
||||||
flash(gettext("Please wait before opening another thread"), "danger")
|
flash(gettext("Please wait before opening another thread"), "danger")
|
||||||
|
|
||||||
if package:
|
if package:
|
||||||
return redirect(package.getURL("packages.view"))
|
return redirect(package.get_url("packages.view"))
|
||||||
else:
|
else:
|
||||||
return redirect(url_for("homepage.home"))
|
return redirect(url_for("homepage.home"))
|
||||||
|
|
||||||
@ -359,24 +359,24 @@ def new():
|
|||||||
|
|
||||||
msg = "Mentioned by {} in new thread '{}'".format(current_user.display_name, thread.title)
|
msg = "Mentioned by {} in new thread '{}'".format(current_user.display_name, thread.title)
|
||||||
addNotification(mentioned, current_user, NotificationType.NEW_THREAD,
|
addNotification(mentioned, current_user, NotificationType.NEW_THREAD,
|
||||||
msg, thread.getViewURL(), thread.package)
|
msg, thread.get_view_url(), thread.package)
|
||||||
|
|
||||||
thread.watchers.append(mentioned)
|
thread.watchers.append(mentioned)
|
||||||
|
|
||||||
notif_msg = "New thread '{}'".format(thread.title)
|
notif_msg = "New thread '{}'".format(thread.title)
|
||||||
if package is not None:
|
if package is not None:
|
||||||
addNotification(package.maintainers, current_user, NotificationType.NEW_THREAD, notif_msg, thread.getViewURL(), package)
|
addNotification(package.maintainers, current_user, NotificationType.NEW_THREAD, notif_msg, thread.get_view_url(), package)
|
||||||
|
|
||||||
approvers = User.query.filter(User.rank >= UserRank.APPROVER).all()
|
approvers = User.query.filter(User.rank >= UserRank.APPROVER).all()
|
||||||
addNotification(approvers, current_user, NotificationType.EDITOR_MISC, notif_msg, thread.getViewURL(), package)
|
addNotification(approvers, current_user, NotificationType.EDITOR_MISC, notif_msg, thread.get_view_url(), package)
|
||||||
|
|
||||||
if is_review_thread:
|
if is_review_thread:
|
||||||
post_discord_webhook.delay(current_user.username,
|
post_discord_webhook.delay(current_user.username,
|
||||||
"Opened approval thread: {}".format(thread.getViewURL(absolute=True)), True)
|
"Opened approval thread: {}".format(thread.get_view_url(absolute=True)), True)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(thread.getViewURL())
|
return redirect(thread.get_view_url())
|
||||||
|
|
||||||
|
|
||||||
return render_template("threads/new.html", form=form, allow_private_change=allow_private_change, package=package)
|
return render_template("threads/new.html", form=form, allow_private_change=allow_private_change, package=package)
|
||||||
|
@ -106,7 +106,7 @@ def apply_all_updates(username):
|
|||||||
.order_by(db.asc(Package.title)).all()
|
.order_by(db.asc(Package.title)).all()
|
||||||
|
|
||||||
for package in outdated_packages:
|
for package in outdated_packages:
|
||||||
if not package.checkPerm(current_user, Permission.MAKE_RELEASE):
|
if not package.check_perm(current_user, Permission.MAKE_RELEASE):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if package.releases.filter(or_(PackageRelease.task_id.isnot(None),
|
if package.releases.filter(or_(PackageRelease.task_id.isnot(None),
|
||||||
@ -129,8 +129,8 @@ def apply_all_updates(username):
|
|||||||
|
|
||||||
msg = "Created release {} (Applied all Git Update Detection)".format(rel.title)
|
msg = "Created release {} (Applied all Git Update Detection)".format(rel.title)
|
||||||
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg,
|
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg,
|
||||||
rel.getURL("packages.create_edit"), package)
|
rel.get_url("packages.create_edit"), package)
|
||||||
addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.getURL("packages.view"), package)
|
addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.get_url("packages.view"), package)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(url_for("todo.view_user", username=username))
|
return redirect(url_for("todo.view_user", username=username))
|
||||||
@ -174,7 +174,7 @@ def confirm_supports_all_games(username=None):
|
|||||||
db.session.merge(package)
|
db.session.merge(package)
|
||||||
|
|
||||||
addAuditLog(AuditSeverity.NORMAL, current_user, "Enabled 'Supports all games' (bulk)",
|
addAuditLog(AuditSeverity.NORMAL, current_user, "Enabled 'Supports all games' (bulk)",
|
||||||
package.getURL("packages.game_support"), package)
|
package.get_url("packages.game_support"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ def profile(username):
|
|||||||
if not user:
|
if not user:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not current_user.is_authenticated or (user != current_user and not current_user.canAccessTodoList()):
|
if not current_user.is_authenticated or (user != current_user and not current_user.can_access_todo_list()):
|
||||||
packages = user.packages.filter_by(state=PackageState.APPROVED)
|
packages = user.packages.filter_by(state=PackageState.APPROVED)
|
||||||
maintained_packages = user.maintained_packages.filter_by(state=PackageState.APPROVED)
|
maintained_packages = user.maintained_packages.filter_by(state=PackageState.APPROVED)
|
||||||
else:
|
else:
|
||||||
|
@ -59,7 +59,7 @@ def handle_profile_edit(form: UserProfileForm, user: User, username: str):
|
|||||||
url_for("users.profile", username=username))
|
url_for("users.profile", username=username))
|
||||||
|
|
||||||
display_name = form.display_name.data or user.username
|
display_name = form.display_name.data or user.username
|
||||||
if user.checkPerm(current_user, Permission.CHANGE_DISPLAY_NAME) and \
|
if user.check_perm(current_user, Permission.CHANGE_DISPLAY_NAME) and \
|
||||||
user.display_name != display_name:
|
user.display_name != display_name:
|
||||||
|
|
||||||
if User.query.filter(User.id != user.id,
|
if User.query.filter(User.id != user.id,
|
||||||
@ -82,7 +82,7 @@ def handle_profile_edit(form: UserProfileForm, user: User, username: str):
|
|||||||
.format(user.username, user.display_name),
|
.format(user.username, user.display_name),
|
||||||
url_for("users.profile", username=username))
|
url_for("users.profile", username=username))
|
||||||
|
|
||||||
if user.checkPerm(current_user, Permission.CHANGE_PROFILE_URLS):
|
if user.check_perm(current_user, Permission.CHANGE_PROFILE_URLS):
|
||||||
if has_blocked_domains(form.website_url.data, current_user.username, f"{user.username}'s website_url") or \
|
if has_blocked_domains(form.website_url.data, current_user.username, f"{user.username}'s website_url") or \
|
||||||
has_blocked_domains(form.donate_url.data, current_user.username, f"{user.username}'s donate_url"):
|
has_blocked_domains(form.donate_url.data, current_user.username, f"{user.username}'s donate_url"):
|
||||||
flash(gettext("Linking to blocked sites is not allowed"), "danger")
|
flash(gettext("Linking to blocked sites is not allowed"), "danger")
|
||||||
@ -124,7 +124,7 @@ def make_settings_form():
|
|||||||
}
|
}
|
||||||
|
|
||||||
for notificationType in NotificationType:
|
for notificationType in NotificationType:
|
||||||
key = "pref_" + notificationType.toName()
|
key = "pref_" + notificationType.to_name()
|
||||||
attrs[key] = BooleanField("")
|
attrs[key] = BooleanField("")
|
||||||
attrs[key + "_digest"] = BooleanField("")
|
attrs[key + "_digest"] = BooleanField("")
|
||||||
|
|
||||||
@ -135,15 +135,15 @@ SettingsForm = make_settings_form()
|
|||||||
|
|
||||||
def handle_email_notifications(user, prefs: UserNotificationPreferences, is_new, form):
|
def handle_email_notifications(user, prefs: UserNotificationPreferences, is_new, form):
|
||||||
for notificationType in NotificationType:
|
for notificationType in NotificationType:
|
||||||
field_email = getattr(form, "pref_" + notificationType.toName()).data
|
field_email = getattr(form, "pref_" + notificationType.to_name()).data
|
||||||
field_digest = getattr(form, "pref_" + notificationType.toName() + "_digest").data or field_email
|
field_digest = getattr(form, "pref_" + notificationType.to_name() + "_digest").data or field_email
|
||||||
prefs.set_can_email(notificationType, field_email)
|
prefs.set_can_email(notificationType, field_email)
|
||||||
prefs.set_can_digest(notificationType, field_digest)
|
prefs.set_can_digest(notificationType, field_digest)
|
||||||
|
|
||||||
if is_new:
|
if is_new:
|
||||||
db.session.add(prefs)
|
db.session.add(prefs)
|
||||||
|
|
||||||
if user.checkPerm(current_user, Permission.CHANGE_EMAIL):
|
if user.check_perm(current_user, Permission.CHANGE_EMAIL):
|
||||||
newEmail = form.email.data
|
newEmail = form.email.data
|
||||||
if newEmail and newEmail != user.email and newEmail.strip() != "":
|
if newEmail and newEmail != user.email and newEmail.strip() != "":
|
||||||
if EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0:
|
if EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0:
|
||||||
@ -182,7 +182,7 @@ def email_notifications(username=None):
|
|||||||
if not user:
|
if not user:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
|
if not user.check_perm(current_user, Permission.CHANGE_EMAIL):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
is_new = False
|
is_new = False
|
||||||
@ -195,8 +195,8 @@ def email_notifications(username=None):
|
|||||||
types = []
|
types = []
|
||||||
for notificationType in NotificationType:
|
for notificationType in NotificationType:
|
||||||
types.append(notificationType)
|
types.append(notificationType)
|
||||||
data["pref_" + notificationType.toName()] = prefs.get_can_email(notificationType)
|
data["pref_" + notificationType.to_name()] = prefs.get_can_email(notificationType)
|
||||||
data["pref_" + notificationType.toName() + "_digest"] = prefs.get_can_digest(notificationType)
|
data["pref_" + notificationType.to_name() + "_digest"] = prefs.get_can_digest(notificationType)
|
||||||
|
|
||||||
data["email"] = user.email
|
data["email"] = user.email
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ def modtools(username):
|
|||||||
if not user:
|
if not user:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
|
if not user.check_perm(current_user, Permission.CHANGE_EMAIL):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
form = ModToolsForm(obj=user)
|
form = ModToolsForm(obj=user)
|
||||||
@ -295,7 +295,7 @@ def modtools(username):
|
|||||||
url_for("users.profile", username=username))
|
url_for("users.profile", username=username))
|
||||||
|
|
||||||
# Copy form fields to user_profile fields
|
# Copy form fields to user_profile fields
|
||||||
if user.checkPerm(current_user, Permission.CHANGE_USERNAMES):
|
if user.check_perm(current_user, Permission.CHANGE_USERNAMES):
|
||||||
if user.username != form.username.data:
|
if user.username != form.username.data:
|
||||||
for package in user.packages:
|
for package in user.packages:
|
||||||
alias = PackageAlias(user.username, package.name)
|
alias = PackageAlias(user.username, package.name)
|
||||||
@ -308,12 +308,12 @@ def modtools(username):
|
|||||||
user.forums_username = nonEmptyOrNone(form.forums_username.data)
|
user.forums_username = nonEmptyOrNone(form.forums_username.data)
|
||||||
user.github_username = nonEmptyOrNone(form.github_username.data)
|
user.github_username = nonEmptyOrNone(form.github_username.data)
|
||||||
|
|
||||||
if user.checkPerm(current_user, Permission.CHANGE_RANK):
|
if user.check_perm(current_user, Permission.CHANGE_RANK):
|
||||||
newRank = form["rank"].data
|
newRank = form["rank"].data
|
||||||
if current_user.rank.atLeast(newRank):
|
if current_user.rank.atLeast(newRank):
|
||||||
if newRank != user.rank:
|
if newRank != user.rank:
|
||||||
user.rank = form["rank"].data
|
user.rank = form["rank"].data
|
||||||
msg = "Set rank of {} to {}".format(user.display_name, user.rank.getTitle())
|
msg = "Set rank of {} to {}".format(user.display_name, user.rank.get_title())
|
||||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg,
|
addAuditLog(AuditSeverity.MODERATION, current_user, msg,
|
||||||
url_for("users.profile", username=username))
|
url_for("users.profile", username=username))
|
||||||
else:
|
else:
|
||||||
@ -333,7 +333,7 @@ def modtools_set_email(username):
|
|||||||
if not user:
|
if not user:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
|
if not user.check_perm(current_user, Permission.CHANGE_EMAIL):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
user.email = request.form["email"]
|
user.email = request.form["email"]
|
||||||
@ -364,7 +364,7 @@ def modtools_ban(username):
|
|||||||
if not user:
|
if not user:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CHANGE_RANK):
|
if not user.check_perm(current_user, Permission.CHANGE_RANK):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
message = request.form["message"]
|
message = request.form["message"]
|
||||||
@ -394,7 +394,7 @@ def modtools_unban(username):
|
|||||||
if not user:
|
if not user:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
if not user.checkPerm(current_user, Permission.CHANGE_RANK):
|
if not user.check_perm(current_user, Permission.CHANGE_RANK):
|
||||||
abort(403)
|
abort(403)
|
||||||
|
|
||||||
if user.ban:
|
if user.ban:
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from typing import List, Dict, Optional, Iterable
|
from typing import List, Dict
|
||||||
|
|
||||||
import sqlalchemy.orm
|
import sqlalchemy.orm
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ class GameSupportResolver:
|
|||||||
print(f"Resolving for {key}", file=sys.stderr)
|
print(f"Resolving for {key}", file=sys.stderr)
|
||||||
|
|
||||||
history = history.copy()
|
history = history.copy()
|
||||||
history.append(package.getId())
|
history.append(package.get_id())
|
||||||
|
|
||||||
if package.type == PackageType.GAME:
|
if package.type == PackageType.GAME:
|
||||||
return {package.id}
|
return {package.id}
|
||||||
@ -135,7 +135,7 @@ class GameSupportResolver:
|
|||||||
self.resolved_packages[key] = retval
|
self.resolved_packages[key] = retval
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def update_all(self) -> None:
|
def init_all(self) -> None:
|
||||||
for package in self.session.query(Package).filter(Package.type == PackageType.MOD, Package.state != PackageState.DELETED).all():
|
for package in self.session.query(Package).filter(Package.type == PackageType.MOD, Package.state != PackageState.DELETED).all():
|
||||||
retval = self.resolve(package, [])
|
retval = self.resolve(package, [])
|
||||||
for game_id in retval:
|
for game_id in retval:
|
||||||
|
@ -109,7 +109,7 @@ def get_package_overview_for_user(user: Optional[User], start_date: datetime.dat
|
|||||||
if user:
|
if user:
|
||||||
package_title_by_id[package.id] = package.title
|
package_title_by_id[package.id] = package.title
|
||||||
else:
|
else:
|
||||||
package_title_by_id[package.id] = package.getId()
|
package_title_by_id[package.id] = package.get_id()
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ def validate_package_for_approval(package: Package) -> List[ValidationError]:
|
|||||||
# Don't bother validating any more until we have a release
|
# Don't bother validating any more until we have a release
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
missing_deps = package.getMissingHardDependenciesQuery().all()
|
missing_deps = package.get_missing_hard_dependencies_query().all()
|
||||||
if len(missing_deps) > 0:
|
if len(missing_deps) > 0:
|
||||||
retval.append(("danger", lazy_gettext(
|
retval.append(("danger", lazy_gettext(
|
||||||
"The following hard dependencies need to be added to ContentDB first: %(deps)s", deps=missing_deps)))
|
"The following hard dependencies need to be added to ContentDB first: %(deps)s", deps=missing_deps)))
|
||||||
|
@ -106,16 +106,16 @@ def validate(data: dict):
|
|||||||
|
|
||||||
def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, data: dict,
|
def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, data: dict,
|
||||||
reason: str = None):
|
reason: str = None):
|
||||||
if not package.checkPerm(user, Permission.EDIT_PACKAGE):
|
if not package.check_perm(user, Permission.EDIT_PACKAGE):
|
||||||
raise LogicError(403, lazy_gettext("You don't have permission to edit this package"))
|
raise LogicError(403, lazy_gettext("You don't have permission to edit this package"))
|
||||||
|
|
||||||
if "name" in data and package.name != data["name"] and \
|
if "name" in data and package.name != data["name"] and \
|
||||||
not package.checkPerm(user, Permission.CHANGE_NAME):
|
not package.check_perm(user, Permission.CHANGE_NAME):
|
||||||
raise LogicError(403, lazy_gettext("You don't have permission to change the package name"))
|
raise LogicError(403, lazy_gettext("You don't have permission to change the package name"))
|
||||||
|
|
||||||
before_dict = None
|
before_dict = None
|
||||||
if not was_new:
|
if not was_new:
|
||||||
before_dict = package.getAsDictionary("/")
|
before_dict = package.as_dict("/")
|
||||||
|
|
||||||
for alias, to in ALIASES.items():
|
for alias, to in ALIASES.items():
|
||||||
if alias in data:
|
if alias in data:
|
||||||
@ -125,7 +125,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
|
|||||||
|
|
||||||
for field in ["short_desc", "desc", "website", "issueTracker", "repo", "video_url", "donate_url"]:
|
for field in ["short_desc", "desc", "website", "issueTracker", "repo", "video_url", "donate_url"]:
|
||||||
if field in data and has_blocked_domains(data[field], user.username,
|
if field in data and has_blocked_domains(data[field], user.username,
|
||||||
f"{field} of {package.getId()}"):
|
f"{field} of {package.get_id()}"):
|
||||||
raise LogicError(403, lazy_gettext("Linking to blocked sites is not allowed"))
|
raise LogicError(403, lazy_gettext("Linking to blocked sites is not allowed"))
|
||||||
|
|
||||||
if "type" in data:
|
if "type" in data:
|
||||||
@ -193,7 +193,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
|
|||||||
package.content_warnings.append(warning)
|
package.content_warnings.append(warning)
|
||||||
|
|
||||||
if not was_new:
|
if not was_new:
|
||||||
after_dict = package.getAsDictionary("/")
|
after_dict = package.as_dict("/")
|
||||||
diff = diff_dictionaries(before_dict, after_dict)
|
diff = diff_dictionaries(before_dict, after_dict)
|
||||||
|
|
||||||
if reason is None:
|
if reason is None:
|
||||||
@ -206,7 +206,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
|
|||||||
msg += " [" + diff_desc + "]"
|
msg += " [" + diff_desc + "]"
|
||||||
|
|
||||||
severity = AuditSeverity.NORMAL if user in package.maintainers else AuditSeverity.EDITOR
|
severity = AuditSeverity.NORMAL if user in package.maintainers else AuditSeverity.EDITOR
|
||||||
addAuditLog(severity, user, msg, package.getURL("packages.view"), package, json.dumps(diff, indent=4))
|
addAuditLog(severity, user, msg, package.get_url("packages.view"), package, json.dumps(diff, indent=4))
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ from app.utils import AuditSeverity, addAuditLog, nonEmptyOrNone
|
|||||||
|
|
||||||
|
|
||||||
def check_can_create_release(user: User, package: Package):
|
def check_can_create_release(user: User, package: Package):
|
||||||
if not package.checkPerm(user, Permission.MAKE_RELEASE):
|
if not package.check_perm(user, Permission.MAKE_RELEASE):
|
||||||
raise LogicError(403, lazy_gettext("You don't have permission to make releases"))
|
raise LogicError(403, lazy_gettext("You don't have permission to make releases"))
|
||||||
|
|
||||||
five_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=5)
|
five_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=5)
|
||||||
@ -54,7 +54,7 @@ def do_create_vcs_release(user: User, package: Package, title: str, ref: str,
|
|||||||
msg = "Created release {}".format(rel.title)
|
msg = "Created release {}".format(rel.title)
|
||||||
else:
|
else:
|
||||||
msg = "Created release {} ({})".format(rel.title, reason)
|
msg = "Created release {} ({})".format(rel.title, reason)
|
||||||
addAuditLog(AuditSeverity.NORMAL, user, msg, package.getURL("packages.view"), package)
|
addAuditLog(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ def do_create_zip_release(user: User, package: Package, title: str, file,
|
|||||||
msg = "Created release {}".format(rel.title)
|
msg = "Created release {}".format(rel.title)
|
||||||
else:
|
else:
|
||||||
msg = "Created release {} ({})".format(rel.title, reason)
|
msg = "Created release {} ({})".format(rel.title, reason)
|
||||||
addAuditLog(AuditSeverity.NORMAL, user, msg, package.getURL("packages.view"), package)
|
addAuditLog(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ def do_create_screenshot(user: User, package: Package, title: str, file, is_cove
|
|||||||
ss.package = package
|
ss.package = package
|
||||||
ss.title = title or "Untitled"
|
ss.title = title or "Untitled"
|
||||||
ss.url = uploaded_url
|
ss.url = uploaded_url
|
||||||
ss.approved = package.checkPerm(user, Permission.APPROVE_SCREENSHOT)
|
ss.approved = package.check_perm(user, Permission.APPROVE_SCREENSHOT)
|
||||||
ss.order = counter
|
ss.order = counter
|
||||||
ss.width, ss.height = get_image_size(uploaded_path)
|
ss.width, ss.height = get_image_size(uploaded_path)
|
||||||
|
|
||||||
@ -42,8 +42,8 @@ def do_create_screenshot(user: User, package: Package, title: str, file, is_cove
|
|||||||
else:
|
else:
|
||||||
msg = "Created screenshot {} ({})".format(ss.title, reason)
|
msg = "Created screenshot {} ({})".format(ss.title, reason)
|
||||||
|
|
||||||
addNotification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.getURL("packages.view"), package)
|
addNotification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.get_url("packages.view"), package)
|
||||||
addAuditLog(AuditSeverity.NORMAL, user, msg, package.getURL("packages.view"), package)
|
addAuditLog(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@ -63,12 +63,12 @@ class AuditSeverity(enum.Enum):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def getTitle(self):
|
def get_title(self):
|
||||||
return self.name.replace("_", " ").title()
|
return self.name.replace("_", " ").title()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def choices(cls):
|
def choices(cls):
|
||||||
return [(choice, choice.getTitle()) for choice in cls]
|
return [(choice, choice.get_title()) for choice in cls]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def coerce(cls, item):
|
def coerce(cls, item):
|
||||||
@ -106,14 +106,14 @@ class AuditLogEntry(db.Model):
|
|||||||
self.package = package
|
self.package = package
|
||||||
self.description = description
|
self.description = description
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to AuditLogEntry.checkPerm()")
|
raise Exception("Unknown permission given to AuditLogEntry.check_perm()")
|
||||||
|
|
||||||
if perm == Permission.VIEW_AUDIT_DESCRIPTION:
|
if perm == Permission.VIEW_AUDIT_DESCRIPTION:
|
||||||
return user.rank.atLeast(UserRank.APPROVER if self.package is not None else UserRank.MODERATOR)
|
return user.rank.atLeast(UserRank.APPROVER if self.package is not None else UserRank.MODERATOR)
|
||||||
@ -156,11 +156,11 @@ class ForumTopic(db.Model):
|
|||||||
|
|
||||||
return self.link.replace("repo.or.cz/w/", "repo.or.cz/")
|
return self.link.replace("repo.or.cz/w/", "repo.or.cz/")
|
||||||
|
|
||||||
def getAsDictionary(self):
|
def as_dict(self):
|
||||||
return {
|
return {
|
||||||
"author": self.author.username,
|
"author": self.author.username,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"type": self.type.toName(),
|
"type": self.type.to_name(),
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
"id": self.topic_id,
|
"id": self.topic_id,
|
||||||
"link": self.link,
|
"link": self.link,
|
||||||
@ -171,14 +171,14 @@ class ForumTopic(db.Model):
|
|||||||
"created_at": self.created_at.isoformat(),
|
"created_at": self.created_at.isoformat(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to ForumTopic.checkPerm()")
|
raise Exception("Unknown permission given to ForumTopic.check_perm()")
|
||||||
|
|
||||||
if perm == Permission.TOPIC_DISCARD:
|
if perm == Permission.TOPIC_DISCARD:
|
||||||
return self.author == user or user.rank.atLeast(UserRank.EDITOR)
|
return self.author == user or user.rank.atLeast(UserRank.EDITOR)
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import enum
|
import enum
|
||||||
import typing
|
|
||||||
|
|
||||||
from flask import url_for
|
from flask import url_for
|
||||||
from flask_babel import lazy_gettext
|
from flask_babel import lazy_gettext
|
||||||
@ -55,7 +54,7 @@ class PackageType(enum.Enum):
|
|||||||
GAME = "Game"
|
GAME = "Game"
|
||||||
TXP = "Texture Pack"
|
TXP = "Texture Pack"
|
||||||
|
|
||||||
def toName(self):
|
def to_name(self):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -104,7 +103,7 @@ class PackageDevState(enum.Enum):
|
|||||||
DEPRECATED = "Deprecated"
|
DEPRECATED = "Deprecated"
|
||||||
LOOKING_FOR_MAINTAINER = "Looking for Maintainer"
|
LOOKING_FOR_MAINTAINER = "Looking for Maintainer"
|
||||||
|
|
||||||
def toName(self):
|
def to_name(self):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -161,7 +160,7 @@ class PackageState(enum.Enum):
|
|||||||
APPROVED = "Approved"
|
APPROVED = "Approved"
|
||||||
DELETED = "Deleted"
|
DELETED = "Deleted"
|
||||||
|
|
||||||
def toName(self):
|
def to_name(self):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
def verb(self):
|
def verb(self):
|
||||||
@ -503,26 +502,23 @@ class Package(db.Model):
|
|||||||
|
|
||||||
return Package.query.filter(Package.name == parts[1], Package.author.has(username=parts[0])).first()
|
return Package.query.filter(Package.name == parts[1], Package.author.has(username=parts[0])).first()
|
||||||
|
|
||||||
def getId(self):
|
def get_id(self):
|
||||||
return "{}/{}".format(self.author.username, self.name)
|
return "{}/{}".format(self.author.username, self.name)
|
||||||
|
|
||||||
def getIsFOSS(self):
|
def get_sorted_dependencies(self, is_hard=None):
|
||||||
return self.license.is_foss and self.media_license.is_foss
|
|
||||||
|
|
||||||
def getSortedDependencies(self, is_hard=None):
|
|
||||||
query = self.dependencies
|
query = self.dependencies
|
||||||
if is_hard is not None:
|
if is_hard is not None:
|
||||||
query = query.filter_by(optional=not is_hard)
|
query = query.filter_by(optional=not is_hard)
|
||||||
|
|
||||||
deps = query.all()
|
deps = query.all()
|
||||||
deps.sort(key = lambda x: x.getName())
|
deps.sort(key=lambda x: x.getName())
|
||||||
return deps
|
return deps
|
||||||
|
|
||||||
def getSortedHardDependencies(self):
|
def get_sorted_hard_dependencies(self):
|
||||||
return self.getSortedDependencies(True)
|
return self.get_sorted_dependencies(True)
|
||||||
|
|
||||||
def getSortedOptionalDependencies(self):
|
def get_sorted_optional_dependencies(self):
|
||||||
return self.getSortedDependencies(False)
|
return self.get_sorted_dependencies(False)
|
||||||
|
|
||||||
def get_sorted_game_support(self):
|
def get_sorted_game_support(self):
|
||||||
query = self.supported_games.filter(PackageGameSupport.game.has(state=PackageState.APPROVED))
|
query = self.supported_games.filter(PackageGameSupport.game.has(state=PackageState.APPROVED))
|
||||||
@ -542,18 +538,18 @@ class Package(db.Model):
|
|||||||
return self.supports_all_games or \
|
return self.supports_all_games or \
|
||||||
self.supported_games.filter(PackageGameSupport.confidence > 1).count() > 0
|
self.supported_games.filter(PackageGameSupport.confidence > 1).count() > 0
|
||||||
|
|
||||||
def getAsDictionaryKey(self):
|
def as_key_dict(self):
|
||||||
return {
|
return {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"author": self.author.username,
|
"author": self.author.username,
|
||||||
"type": self.type.toName(),
|
"type": self.type.to_name(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAsDictionaryShort(self, base_url, version=None, release_id=None, no_load=False):
|
def as_short_dict(self, base_url, version=None, release_id=None, no_load=False):
|
||||||
tnurl = self.getThumbnailURL(1)
|
tnurl = self.get_thumb_url(1)
|
||||||
|
|
||||||
if release_id is None and no_load == False:
|
if release_id is None and no_load == False:
|
||||||
release = self.getDownloadRelease(version=version)
|
release = self.get_download_release(version=version)
|
||||||
release_id = release and release.id
|
release_id = release and release.id
|
||||||
|
|
||||||
short_desc = self.short_desc
|
short_desc = self.short_desc
|
||||||
@ -565,10 +561,10 @@ class Package(db.Model):
|
|||||||
"title": self.title,
|
"title": self.title,
|
||||||
"author": self.author.username,
|
"author": self.author.username,
|
||||||
"short_description": short_desc,
|
"short_description": short_desc,
|
||||||
"type": self.type.toName(),
|
"type": self.type.to_name(),
|
||||||
"release": release_id,
|
"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 ],
|
"aliases": [alias.as_dict() for alias in self.aliases],
|
||||||
}
|
}
|
||||||
|
|
||||||
if not ret["aliases"]:
|
if not ret["aliases"]:
|
||||||
@ -576,9 +572,9 @@ class Package(db.Model):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def getAsDictionary(self, base_url, version=None):
|
def as_dict(self, base_url, version=None):
|
||||||
tnurl = self.getThumbnailURL(1)
|
tnurl = self.get_thumb_url(1)
|
||||||
release = self.getDownloadRelease(version=version)
|
release = self.get_download_release(version=version)
|
||||||
return {
|
return {
|
||||||
"author": self.author.username,
|
"author": self.author.username,
|
||||||
"maintainers": [x.username for x in self.maintainers],
|
"maintainers": [x.username for x in self.maintainers],
|
||||||
@ -590,7 +586,7 @@ class Package(db.Model):
|
|||||||
"title": self.title,
|
"title": self.title,
|
||||||
"short_description": self.short_desc,
|
"short_description": self.short_desc,
|
||||||
"long_description": self.desc,
|
"long_description": self.desc,
|
||||||
"type": self.type.toName(),
|
"type": self.type.to_name(),
|
||||||
"created_at": self.created_at.isoformat(),
|
"created_at": self.created_at.isoformat(),
|
||||||
|
|
||||||
"license": self.license.name,
|
"license": self.license.name,
|
||||||
@ -610,7 +606,7 @@ class Package(db.Model):
|
|||||||
"thumbnail": (base_url + tnurl) if tnurl is not None else None,
|
"thumbnail": (base_url + tnurl) if tnurl is not None else None,
|
||||||
"screenshots": [base_url + ss.url for ss in self.screenshots],
|
"screenshots": [base_url + ss.url for ss in self.screenshots],
|
||||||
|
|
||||||
"url": base_url + self.getURL("packages.download"),
|
"url": base_url + self.get_url("packages.download"),
|
||||||
"release": release and release.id,
|
"release": release and release.id,
|
||||||
|
|
||||||
"score": round(self.score * 10) / 10,
|
"score": round(self.score * 10) / 10,
|
||||||
@ -620,86 +616,86 @@ class Package(db.Model):
|
|||||||
{
|
{
|
||||||
"supports": support.supports,
|
"supports": support.supports,
|
||||||
"confidence": support.confidence,
|
"confidence": support.confidence,
|
||||||
"game": support.game.getAsDictionaryShort(base_url, version)
|
"game": support.game.as_short_dict(base_url, version)
|
||||||
} for support in self.supported_games.all()
|
} for support in self.supported_games.all()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def getThumbnailOrPlaceholder(self, level=2):
|
def get_thumb_or_placeholder(self, level=2):
|
||||||
return self.getThumbnailURL(level) or "/static/placeholder.png"
|
return self.get_thumb_url(level) or "/static/placeholder.png"
|
||||||
|
|
||||||
def getThumbnailURL(self, level=2, abs=False):
|
def get_thumb_url(self, level=2, abs=False):
|
||||||
screenshot = self.main_screenshot
|
screenshot = self.main_screenshot
|
||||||
url = screenshot.getThumbnailURL(level) if screenshot is not None else None
|
url = screenshot.get_thumb_url(level) if screenshot is not None else None
|
||||||
if abs:
|
if abs:
|
||||||
from app.utils import abs_url
|
from app.utils import abs_url
|
||||||
return abs_url(url)
|
return abs_url(url)
|
||||||
else:
|
else:
|
||||||
return url
|
return url
|
||||||
|
|
||||||
def getCoverImageURL(self):
|
def get_cover_image_url(self):
|
||||||
screenshot = self.cover_image or self.main_screenshot
|
screenshot = self.cover_image or self.main_screenshot
|
||||||
return screenshot and screenshot.getThumbnailURL(4)
|
return screenshot and screenshot.get_thumb_url(4)
|
||||||
|
|
||||||
def getURL(self, endpoint, absolute=False, **kwargs):
|
def get_url(self, endpoint, absolute=False, **kwargs):
|
||||||
if absolute:
|
if absolute:
|
||||||
from app.utils import abs_url_for
|
from app.utils import abs_url_for
|
||||||
return abs_url_for(endpoint, author=self.author.username, name=self.name, **kwargs)
|
return abs_url_for(endpoint, author=self.author.username, name=self.name, **kwargs)
|
||||||
else:
|
else:
|
||||||
return url_for(endpoint, author=self.author.username, name=self.name, **kwargs)
|
return url_for(endpoint, author=self.author.username, name=self.name, **kwargs)
|
||||||
|
|
||||||
def getShieldURL(self, type):
|
def get_shield_url(self, type):
|
||||||
from app.utils import abs_url_for
|
from app.utils import abs_url_for
|
||||||
return abs_url_for("packages.shield",
|
return abs_url_for("packages.shield",
|
||||||
author=self.author.username, name=self.name, type=type)
|
author=self.author.username, name=self.name, type=type)
|
||||||
|
|
||||||
def makeShield(self, type):
|
def make_shield(self, type):
|
||||||
return "[![ContentDB]({})]({})" \
|
return "[![ContentDB]({})]({})" \
|
||||||
.format(self.getShieldURL(type), self.getURL("packages.view", True))
|
.format(self.get_shield_url(type), self.get_url("packages.view", True))
|
||||||
|
|
||||||
def getSetStateURL(self, state):
|
def get_set_state_url(self, state):
|
||||||
if type(state) == str:
|
if type(state) == str:
|
||||||
state = PackageState[state]
|
state = PackageState[state]
|
||||||
elif type(state) != PackageState:
|
elif type(state) != PackageState:
|
||||||
raise Exception("Unknown state given to Package.canMoveToState()")
|
raise Exception("Unknown state given to Package.can_move_to_state()")
|
||||||
|
|
||||||
return url_for("packages.move_to_state",
|
return url_for("packages.move_to_state",
|
||||||
author=self.author.username, name=self.name, state=state.name.lower())
|
author=self.author.username, name=self.name, state=state.name.lower())
|
||||||
|
|
||||||
def getDownloadRelease(self, version=None):
|
def get_download_release(self, version=None):
|
||||||
for rel in self.releases:
|
for rel in self.releases:
|
||||||
if rel.approved and (version is None or
|
if rel.approved and (version is None or
|
||||||
((rel.min_rel is None or rel.min_rel_id <= version.id) and
|
((rel.min_rel is None or rel.min_rel_id <= version.id) and
|
||||||
(rel.max_rel is None or rel.max_rel_id >= version.id))):
|
(rel.max_rel is None or rel.max_rel_id >= version.id))):
|
||||||
return rel
|
return rel
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to Package.checkPerm()")
|
raise Exception("Unknown permission given to Package.check_perm()")
|
||||||
|
|
||||||
isOwner = user == self.author
|
is_owner = user == self.author
|
||||||
isMaintainer = isOwner or user.rank.atLeast(UserRank.EDITOR) or user in self.maintainers
|
is_maintainer = is_owner or user.rank.atLeast(UserRank.EDITOR) or user in self.maintainers
|
||||||
isApprover = user.rank.atLeast(UserRank.APPROVER)
|
is_approver = user.rank.atLeast(UserRank.APPROVER)
|
||||||
|
|
||||||
if perm == Permission.CREATE_THREAD:
|
if perm == Permission.CREATE_THREAD:
|
||||||
return user.rank.atLeast(UserRank.NEW_MEMBER)
|
return user.rank.atLeast(UserRank.NEW_MEMBER)
|
||||||
|
|
||||||
# Members can edit their own packages, and editors can edit any packages
|
# Members can edit their own packages, and editors can edit any packages
|
||||||
elif perm == Permission.MAKE_RELEASE or perm == Permission.ADD_SCREENSHOTS:
|
elif perm == Permission.MAKE_RELEASE or perm == Permission.ADD_SCREENSHOTS:
|
||||||
return isMaintainer
|
return is_maintainer
|
||||||
|
|
||||||
elif perm == Permission.EDIT_PACKAGE:
|
elif perm == Permission.EDIT_PACKAGE:
|
||||||
return isMaintainer and user.rank.atLeast(UserRank.NEW_MEMBER)
|
return is_maintainer and user.rank.atLeast(UserRank.NEW_MEMBER)
|
||||||
|
|
||||||
elif perm == Permission.APPROVE_RELEASE:
|
elif perm == Permission.APPROVE_RELEASE:
|
||||||
return (isMaintainer or isApprover) and user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
|
return (is_maintainer or is_approver) and user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
|
||||||
|
|
||||||
# Anyone can change the package name when not approved, but only editors when approved
|
# Anyone can change the package name when not approved, but only editors when approved
|
||||||
elif perm == Permission.CHANGE_NAME:
|
elif perm == Permission.CHANGE_NAME:
|
||||||
@ -707,17 +703,17 @@ class Package(db.Model):
|
|||||||
|
|
||||||
# Editors can change authors and approve new packages
|
# Editors can change authors and approve new packages
|
||||||
elif perm == Permission.APPROVE_NEW or perm == Permission.CHANGE_AUTHOR:
|
elif perm == Permission.APPROVE_NEW or perm == Permission.CHANGE_AUTHOR:
|
||||||
return isApprover
|
return is_approver
|
||||||
|
|
||||||
elif perm == Permission.APPROVE_SCREENSHOT:
|
elif perm == Permission.APPROVE_SCREENSHOT:
|
||||||
return (isMaintainer or isApprover) and \
|
return (is_maintainer or is_approver) and \
|
||||||
user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
|
user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
|
||||||
|
|
||||||
elif perm == Permission.EDIT_MAINTAINERS or perm == Permission.DELETE_PACKAGE:
|
elif perm == Permission.EDIT_MAINTAINERS or perm == Permission.DELETE_PACKAGE:
|
||||||
return isOwner or user.rank.atLeast(UserRank.EDITOR)
|
return is_owner or user.rank.atLeast(UserRank.EDITOR)
|
||||||
|
|
||||||
elif perm == Permission.UNAPPROVE_PACKAGE:
|
elif perm == Permission.UNAPPROVE_PACKAGE:
|
||||||
return isOwner or user.rank.atLeast(UserRank.APPROVER)
|
return is_owner or user.rank.atLeast(UserRank.APPROVER)
|
||||||
|
|
||||||
elif perm == Permission.CHANGE_RELEASE_URL:
|
elif perm == Permission.CHANGE_RELEASE_URL:
|
||||||
return user.rank.atLeast(UserRank.MODERATOR)
|
return user.rank.atLeast(UserRank.MODERATOR)
|
||||||
@ -725,65 +721,64 @@ class Package(db.Model):
|
|||||||
else:
|
else:
|
||||||
raise Exception("Permission {} is not related to packages".format(perm.name))
|
raise Exception("Permission {} is not related to packages".format(perm.name))
|
||||||
|
|
||||||
def getMissingHardDependenciesQuery(self):
|
def get_missing_hard_dependencies_query(self):
|
||||||
return MetaPackage.query \
|
return MetaPackage.query \
|
||||||
.filter(~ MetaPackage.packages.any(state=PackageState.APPROVED)) \
|
.filter(~ MetaPackage.packages.any(state=PackageState.APPROVED)) \
|
||||||
.filter(MetaPackage.dependencies.any(optional=False, depender=self)) \
|
.filter(MetaPackage.dependencies.any(optional=False, depender=self)) \
|
||||||
.order_by(db.asc(MetaPackage.name))
|
.order_by(db.asc(MetaPackage.name))
|
||||||
|
|
||||||
def getMissingHardDependencies(self):
|
def get_missing_hard_dependencies(self):
|
||||||
return [mp.name for mp in self.getMissingHardDependenciesQuery().all()]
|
return [mp.name for mp in self.get_missing_hard_dependencies_query().all()]
|
||||||
|
|
||||||
def canMoveToState(self, user, state):
|
def can_move_to_state(self, user, state):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(state) == str:
|
if type(state) == str:
|
||||||
state = PackageState[state]
|
state = PackageState[state]
|
||||||
elif type(state) != PackageState:
|
elif type(state) != PackageState:
|
||||||
raise Exception("Unknown state given to Package.canMoveToState()")
|
raise Exception("Unknown state given to Package.can_move_to_state()")
|
||||||
|
|
||||||
if state not in PACKAGE_STATE_FLOW[self.state]:
|
if state not in PACKAGE_STATE_FLOW[self.state]:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if state == PackageState.READY_FOR_REVIEW or state == PackageState.APPROVED:
|
if state == PackageState.READY_FOR_REVIEW or state == PackageState.APPROVED:
|
||||||
if state == PackageState.APPROVED and not self.checkPerm(user, Permission.APPROVE_NEW):
|
if state == PackageState.APPROVED and not self.check_perm(user, Permission.APPROVE_NEW):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not (self.checkPerm(user, Permission.APPROVE_NEW) or self.checkPerm(user, Permission.EDIT_PACKAGE)):
|
if not (self.check_perm(user, Permission.APPROVE_NEW) or self.check_perm(user, Permission.EDIT_PACKAGE)):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if state == PackageState.APPROVED and ("Other" in self.license.name or "Other" in self.media_license.name):
|
if state == PackageState.APPROVED and ("Other" in self.license.name or "Other" in self.media_license.name):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.getMissingHardDependenciesQuery().count() > 0:
|
if self.get_missing_hard_dependencies_query().count() > 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
needsScreenshot = \
|
needs_screenshot = \
|
||||||
(self.type == self.type.GAME or self.type == self.type.TXP) and \
|
(self.type == self.type.GAME or self.type == self.type.TXP) and self.screenshots.count() == 0
|
||||||
self.screenshots.count() == 0
|
|
||||||
|
|
||||||
return self.releases.filter(PackageRelease.task_id==None).count() > 0 and not needsScreenshot
|
return self.releases.filter(PackageRelease.task_id==None).count() > 0 and not needs_screenshot
|
||||||
|
|
||||||
elif state == PackageState.CHANGES_NEEDED:
|
elif state == PackageState.CHANGES_NEEDED:
|
||||||
return self.checkPerm(user, Permission.APPROVE_NEW)
|
return self.check_perm(user, Permission.APPROVE_NEW)
|
||||||
|
|
||||||
elif state == PackageState.WIP:
|
elif state == PackageState.WIP:
|
||||||
return self.checkPerm(user, Permission.EDIT_PACKAGE) and \
|
return self.check_perm(user, Permission.EDIT_PACKAGE) and \
|
||||||
(user in self.maintainers or user.rank.atLeast(UserRank.ADMIN))
|
(user in self.maintainers or user.rank.atLeast(UserRank.ADMIN))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getNextStates(self, user):
|
def get_next_states(self, user):
|
||||||
states = []
|
states = []
|
||||||
|
|
||||||
for state in PackageState:
|
for state in PackageState:
|
||||||
if self.canMoveToState(user, state):
|
if self.can_move_to_state(user, state):
|
||||||
states.append(state)
|
states.append(state)
|
||||||
|
|
||||||
return states
|
return states
|
||||||
|
|
||||||
def getScoreDict(self):
|
def as_score_dict(self):
|
||||||
return {
|
return {
|
||||||
"author": self.author.username,
|
"author": self.author.username,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
@ -793,16 +788,16 @@ class Package(db.Model):
|
|||||||
"downloads": self.downloads
|
"downloads": self.downloads
|
||||||
}
|
}
|
||||||
|
|
||||||
def recalcScore(self):
|
def recalculate_score(self):
|
||||||
review_scores = [ 100 * r.asWeight() for r in self.reviews ]
|
review_scores = [ 100 * r.as_weight() for r in self.reviews ]
|
||||||
self.score = self.score_downloads + sum(review_scores)
|
self.score = self.score_downloads + sum(review_scores)
|
||||||
|
|
||||||
|
|
||||||
class MetaPackage(db.Model):
|
class MetaPackage(db.Model):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
name = db.Column(db.String(100), unique=True, nullable=False)
|
name = db.Column(db.String(100), unique=True, nullable=False)
|
||||||
dependencies = db.relationship("Dependency", back_populates="meta_package", lazy="dynamic")
|
dependencies = db.relationship("Dependency", back_populates="meta_package", lazy="dynamic")
|
||||||
packages = db.relationship("Package", lazy="dynamic", back_populates="provides", secondary=PackageProvides)
|
packages = db.relationship("Package", lazy="dynamic", back_populates="provides", secondary=PackageProvides)
|
||||||
|
|
||||||
mp_name_valid = db.CheckConstraint("name ~* '^[a-z0-9_]+$'")
|
mp_name_valid = db.CheckConstraint("name ~* '^[a-z0-9_]+$'")
|
||||||
|
|
||||||
@ -866,7 +861,7 @@ class ContentWarning(db.Model):
|
|||||||
regex = re.compile("[^a-z_]")
|
regex = re.compile("[^a-z_]")
|
||||||
self.name = regex.sub("", self.title.lower().replace(" ", "_"))
|
self.name = regex.sub("", self.title.lower().replace(" ", "_"))
|
||||||
|
|
||||||
def getAsDictionary(self):
|
def as_dict(self):
|
||||||
description = self.description if self.description != "" else None
|
description = self.description if self.description != "" else None
|
||||||
return { "name": self.name, "title": self.title, "description": description }
|
return { "name": self.name, "title": self.title, "description": description }
|
||||||
|
|
||||||
@ -892,7 +887,7 @@ class Tag(db.Model):
|
|||||||
regex = re.compile("[^a-z_]")
|
regex = re.compile("[^a-z_]")
|
||||||
self.name = regex.sub("", self.title.lower().replace(" ", "_"))
|
self.name = regex.sub("", self.title.lower().replace(" ", "_"))
|
||||||
|
|
||||||
def getAsDictionary(self):
|
def as_dict(self):
|
||||||
description = self.description if self.description != "" else None
|
description = self.description if self.description != "" else None
|
||||||
return {
|
return {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
@ -912,10 +907,10 @@ class MinetestRelease(db.Model):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
|
|
||||||
def getActual(self):
|
def get_actual(self):
|
||||||
return None if self.name == "None" else self
|
return None if self.name == "None" else self
|
||||||
|
|
||||||
def getAsDictionary(self):
|
def as_dict(self):
|
||||||
return {
|
return {
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"protocol_version": self.protocol,
|
"protocol_version": self.protocol,
|
||||||
@ -972,7 +967,7 @@ class PackageRelease(db.Model):
|
|||||||
def file_path(self):
|
def file_path(self):
|
||||||
return self.url.replace("/uploads/", app.config["UPLOAD_DIR"])
|
return self.url.replace("/uploads/", app.config["UPLOAD_DIR"])
|
||||||
|
|
||||||
def getAsDictionary(self):
|
def as_dict(self):
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
@ -980,11 +975,11 @@ class PackageRelease(db.Model):
|
|||||||
"release_date": self.releaseDate.isoformat(),
|
"release_date": self.releaseDate.isoformat(),
|
||||||
"commit": self.commit_hash,
|
"commit": self.commit_hash,
|
||||||
"downloads": self.downloads,
|
"downloads": self.downloads,
|
||||||
"min_minetest_version": self.min_rel and self.min_rel.getAsDictionary(),
|
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
|
||||||
"max_minetest_version": self.max_rel and self.max_rel.getAsDictionary(),
|
"max_minetest_version": self.max_rel and self.max_rel.as_dict(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def getLongAsDictionary(self):
|
def as_long_dict(self):
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
@ -992,24 +987,24 @@ class PackageRelease(db.Model):
|
|||||||
"release_date": self.releaseDate.isoformat(),
|
"release_date": self.releaseDate.isoformat(),
|
||||||
"commit": self.commit_hash,
|
"commit": self.commit_hash,
|
||||||
"downloads": self.downloads,
|
"downloads": self.downloads,
|
||||||
"min_minetest_version": self.min_rel and self.min_rel.getAsDictionary(),
|
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
|
||||||
"max_minetest_version": self.max_rel and self.max_rel.getAsDictionary(),
|
"max_minetest_version": self.max_rel and self.max_rel.as_dict(),
|
||||||
"package": self.package.getAsDictionaryKey()
|
"package": self.package.as_key_dict()
|
||||||
}
|
}
|
||||||
|
|
||||||
def getEditURL(self):
|
def get_edit_url(self):
|
||||||
return url_for("packages.edit_release",
|
return url_for("packages.edit_release",
|
||||||
author=self.package.author.username,
|
author=self.package.author.username,
|
||||||
name=self.package.name,
|
name=self.package.name,
|
||||||
id=self.id)
|
id=self.id)
|
||||||
|
|
||||||
def getDeleteURL(self):
|
def get_delete_url(self):
|
||||||
return url_for("packages.delete_release",
|
return url_for("packages.delete_release",
|
||||||
author=self.package.author.username,
|
author=self.package.author.username,
|
||||||
name=self.package.name,
|
name=self.package.name,
|
||||||
id=self.id)
|
id=self.id)
|
||||||
|
|
||||||
def getDownloadURL(self):
|
def get_download_url(self):
|
||||||
return url_for("packages.download_release",
|
return url_for("packages.download_release",
|
||||||
author=self.package.author.username,
|
author=self.package.author.username,
|
||||||
name=self.package.name,
|
name=self.package.name,
|
||||||
@ -1018,11 +1013,11 @@ class PackageRelease(db.Model):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.releaseDate = datetime.datetime.now()
|
self.releaseDate = datetime.datetime.now()
|
||||||
|
|
||||||
def getDownloadFileName(self):
|
def get_download_filename(self):
|
||||||
return f"{self.package.name}_{self.id}.zip"
|
return f"{self.package.name}_{self.id}.zip"
|
||||||
|
|
||||||
def approve(self, user):
|
def approve(self, user):
|
||||||
if not self.checkPerm(user, Permission.APPROVE_RELEASE):
|
if not self.check_perm(user, Permission.APPROVE_RELEASE):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if self.approved:
|
if self.approved:
|
||||||
@ -1038,22 +1033,22 @@ class PackageRelease(db.Model):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to PackageRelease.checkPerm()")
|
raise Exception("Unknown permission given to PackageRelease.check_perm()")
|
||||||
|
|
||||||
isMaintainer = user == self.package.author or user in self.package.maintainers
|
is_maintainer = user == self.package.author or user in self.package.maintainers
|
||||||
|
|
||||||
if perm == Permission.DELETE_RELEASE:
|
if perm == Permission.DELETE_RELEASE:
|
||||||
if user.rank.atLeast(UserRank.ADMIN):
|
if user.rank.atLeast(UserRank.ADMIN):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not (isMaintainer or user.rank.atLeast(UserRank.EDITOR)):
|
if not (is_maintainer or user.rank.atLeast(UserRank.EDITOR)):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not self.package.approved or self.task_id is not None:
|
if not self.package.approved or self.task_id is not None:
|
||||||
@ -1066,7 +1061,7 @@ class PackageRelease(db.Model):
|
|||||||
return count > 0
|
return count > 0
|
||||||
elif perm == Permission.APPROVE_RELEASE:
|
elif perm == Permission.APPROVE_RELEASE:
|
||||||
return user.rank.atLeast(UserRank.APPROVER) or \
|
return user.rank.atLeast(UserRank.APPROVER) or \
|
||||||
(isMaintainer and user.rank.atLeast(
|
(is_maintainer and user.rank.atLeast(
|
||||||
UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER))
|
UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER))
|
||||||
else:
|
else:
|
||||||
raise Exception("Permission {} is not related to releases".format(perm.name))
|
raise Exception("Permission {} is not related to releases".format(perm.name))
|
||||||
@ -1103,22 +1098,22 @@ class PackageScreenshot(db.Model):
|
|||||||
def file_path(self):
|
def file_path(self):
|
||||||
return self.url.replace("/uploads/", app.config["UPLOAD_DIR"])
|
return self.url.replace("/uploads/", app.config["UPLOAD_DIR"])
|
||||||
|
|
||||||
def getEditURL(self):
|
def get_edit_url(self):
|
||||||
return url_for("packages.edit_screenshot",
|
return url_for("packages.edit_screenshot",
|
||||||
author=self.package.author.username,
|
author=self.package.author.username,
|
||||||
name=self.package.name,
|
name=self.package.name,
|
||||||
id=self.id)
|
id=self.id)
|
||||||
|
|
||||||
def getDeleteURL(self):
|
def get_delete_url(self):
|
||||||
return url_for("packages.delete_screenshot",
|
return url_for("packages.delete_screenshot",
|
||||||
author=self.package.author.username,
|
author=self.package.author.username,
|
||||||
name=self.package.name,
|
name=self.package.name,
|
||||||
id=self.id)
|
id=self.id)
|
||||||
|
|
||||||
def getThumbnailURL(self, level=2):
|
def get_thumb_url(self, level=2):
|
||||||
return self.url.replace("/uploads/", "/thumbnails/{:d}/".format(level))
|
return self.url.replace("/uploads/", "/thumbnails/{:d}/".format(level))
|
||||||
|
|
||||||
def getAsDictionary(self, base_url=""):
|
def as_dict(self, base_url=""):
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
"order": self.order,
|
"order": self.order,
|
||||||
@ -1136,7 +1131,7 @@ class PackageUpdateTrigger(enum.Enum):
|
|||||||
COMMIT = "New Commit"
|
COMMIT = "New Commit"
|
||||||
TAG = "New Tag"
|
TAG = "New Tag"
|
||||||
|
|
||||||
def toName(self):
|
def to_name(self):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -1199,7 +1194,7 @@ class PackageUpdateConfig(db.Model):
|
|||||||
return self.last_tag or self.last_commit
|
return self.last_tag or self.last_commit
|
||||||
|
|
||||||
def get_create_release_url(self):
|
def get_create_release_url(self):
|
||||||
return self.package.getURL("packages.create_release", title=self.get_title(), ref=self.get_ref())
|
return self.package.get_url("packages.create_release", title=self.get_title(), ref=self.get_ref())
|
||||||
|
|
||||||
|
|
||||||
class PackageAlias(db.Model):
|
class PackageAlias(db.Model):
|
||||||
@ -1215,11 +1210,11 @@ class PackageAlias(db.Model):
|
|||||||
self.author = author
|
self.author = author
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def getEditURL(self):
|
def get_edit_url(self):
|
||||||
return url_for("packages.alias_create_edit", author=self.package.author.username,
|
return url_for("packages.alias_create_edit", author=self.package.author.username,
|
||||||
name=self.package.name, alias_id=self.id)
|
name=self.package.name, alias_id=self.id)
|
||||||
|
|
||||||
def getAsDictionary(self):
|
def as_dict(self):
|
||||||
return f"{self.author}/{self.name}"
|
return f"{self.author}/{self.name}"
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,27 +66,27 @@ class Thread(db.Model):
|
|||||||
else:
|
else:
|
||||||
return comment
|
return comment
|
||||||
|
|
||||||
def getViewURL(self, absolute=False):
|
def get_view_url(self, absolute=False):
|
||||||
if absolute:
|
if absolute:
|
||||||
from ..utils import abs_url_for
|
from ..utils import abs_url_for
|
||||||
return abs_url_for("threads.view", id=self.id)
|
return abs_url_for("threads.view", id=self.id)
|
||||||
else:
|
else:
|
||||||
return url_for("threads.view", id=self.id, _external=False)
|
return url_for("threads.view", id=self.id, _external=False)
|
||||||
|
|
||||||
def getSubscribeURL(self):
|
def get_subscribe_url(self):
|
||||||
return url_for("threads.subscribe", id=self.id)
|
return url_for("threads.subscribe", id=self.id)
|
||||||
|
|
||||||
def getUnsubscribeURL(self):
|
def get_unsubscribe_url(self):
|
||||||
return url_for("threads.unsubscribe", id=self.id)
|
return url_for("threads.unsubscribe", id=self.id)
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return perm == Permission.SEE_THREAD and not self.private
|
return perm == Permission.SEE_THREAD and not self.private
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to Thread.checkPerm()")
|
raise Exception("Unknown permission given to Thread.check_perm()")
|
||||||
|
|
||||||
isMaintainer = user == self.author or (self.package is not None and self.package.author == user)
|
isMaintainer = user == self.author or (self.package is not None and self.package.author == user)
|
||||||
if self.package:
|
if self.package:
|
||||||
@ -145,16 +145,16 @@ class ThreadReply(db.Model):
|
|||||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
|
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
|
||||||
|
|
||||||
def get_url(self, absolute=False):
|
def get_url(self, absolute=False):
|
||||||
return self.thread.getViewURL(absolute) + "#reply-" + str(self.id)
|
return self.thread.get_view_url(absolute) + "#reply-" + str(self.id)
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to ThreadReply.checkPerm()")
|
raise Exception("Unknown permission given to ThreadReply.check_perm()")
|
||||||
|
|
||||||
if perm == Permission.EDIT_REPLY:
|
if perm == Permission.EDIT_REPLY:
|
||||||
return user.rank.atLeast(UserRank.NEW_MEMBER if user == self.author else UserRank.MODERATOR) and not self.thread.locked
|
return user.rank.atLeast(UserRank.NEW_MEMBER if user == self.author else UserRank.MODERATOR) and not self.thread.locked
|
||||||
@ -191,7 +191,7 @@ class PackageReview(db.Model):
|
|||||||
user_vote = next(filter(lambda vote: vote.user == current_user, votes), None)
|
user_vote = next(filter(lambda vote: vote.user == current_user, votes), None)
|
||||||
return pos, neg, user_vote.is_positive if user_vote else None
|
return pos, neg, user_vote.is_positive if user_vote else None
|
||||||
|
|
||||||
def getAsDictionary(self, include_package=False):
|
def as_dict(self, include_package=False):
|
||||||
pos, neg, _user = self.get_totals()
|
pos, neg, _user = self.get_totals()
|
||||||
ret = {
|
ret = {
|
||||||
"is_positive": self.rating > 3,
|
"is_positive": self.rating > 3,
|
||||||
@ -209,19 +209,19 @@ class PackageReview(db.Model):
|
|||||||
"comment": self.thread.first_reply.comment,
|
"comment": self.thread.first_reply.comment,
|
||||||
}
|
}
|
||||||
if include_package:
|
if include_package:
|
||||||
ret["package"] = self.package.getAsDictionaryKey()
|
ret["package"] = self.package.as_key_dict()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def asWeight(self):
|
def as_weight(self):
|
||||||
"""
|
"""
|
||||||
From (1, 5) to (-1 to 1)
|
From (1, 5) to (-1 to 1)
|
||||||
"""
|
"""
|
||||||
return (self.rating - 3.0) / 2.0
|
return (self.rating - 3.0) / 2.0
|
||||||
|
|
||||||
def getEditURL(self):
|
def get_edit_url(self):
|
||||||
return self.package.getURL("packages.review")
|
return self.package.get_url("packages.review")
|
||||||
|
|
||||||
def getDeleteURL(self):
|
def get_delete_url(self):
|
||||||
return url_for("packages.delete_review",
|
return url_for("packages.delete_review",
|
||||||
author=self.package.author.username,
|
author=self.package.author.username,
|
||||||
name=self.package.name,
|
name=self.package.name,
|
||||||
@ -238,14 +238,14 @@ class PackageReview(db.Model):
|
|||||||
(pos, neg, _) = self.get_totals()
|
(pos, neg, _) = self.get_totals()
|
||||||
self.score = 3 * (pos - neg) + 1
|
self.score = 3 * (pos - neg) + 1
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to PackageReview.checkPerm()")
|
raise Exception("Unknown permission given to PackageReview.check_perm()")
|
||||||
|
|
||||||
if perm == Permission.DELETE_REVIEW:
|
if perm == Permission.DELETE_REVIEW:
|
||||||
return user == self.author or user.rank.atLeast(UserRank.MODERATOR)
|
return user == self.author or user.rank.atLeast(UserRank.MODERATOR)
|
||||||
|
@ -41,10 +41,10 @@ class UserRank(enum.Enum):
|
|||||||
def atLeast(self, min):
|
def atLeast(self, min):
|
||||||
return self.value >= min.value
|
return self.value >= min.value
|
||||||
|
|
||||||
def getTitle(self):
|
def get_title(self):
|
||||||
return self.name.replace("_", " ").title()
|
return self.name.replace("_", " ").title()
|
||||||
|
|
||||||
def toName(self):
|
def to_name(self):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -52,7 +52,7 @@ class UserRank(enum.Enum):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def choices(cls):
|
def choices(cls):
|
||||||
return [(choice, choice.getTitle()) for choice in cls]
|
return [(choice, choice.get_title()) for choice in cls]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def coerce(cls, item):
|
def coerce(cls, item):
|
||||||
@ -93,7 +93,7 @@ class Permission(enum.Enum):
|
|||||||
VIEW_AUDIT_DESCRIPTION = "VIEW_AUDIT_DESCRIPTION"
|
VIEW_AUDIT_DESCRIPTION = "VIEW_AUDIT_DESCRIPTION"
|
||||||
|
|
||||||
# Only return true if the permission is valid for *all* contexts
|
# Only return true if the permission is valid for *all* contexts
|
||||||
# See Package.checkPerm for package-specific contexts
|
# See Package.check_perm for package-specific contexts
|
||||||
def check(self, user):
|
def check(self, user):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
@ -108,10 +108,10 @@ class Permission(enum.Enum):
|
|||||||
return user.rank.atLeast(UserRank.EDITOR)
|
return user.rank.atLeast(UserRank.EDITOR)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("Non-global permission checked globally. Use Package.checkPerm or User.checkPerm instead.")
|
raise Exception("Non-global permission checked globally. Use Package.check_perm or User.check_perm instead.")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def checkPerm(user, perm):
|
def check_perm(user, perm):
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
@ -213,14 +213,10 @@ class User(db.Model, UserMixin):
|
|||||||
self.password = password
|
self.password = password
|
||||||
self.rank = UserRank.NOT_JOINED
|
self.rank = UserRank.NOT_JOINED
|
||||||
|
|
||||||
def canAccessTodoList(self):
|
def can_access_todo_list(self):
|
||||||
return Permission.APPROVE_NEW.check(self) or \
|
return Permission.APPROVE_NEW.check(self) or Permission.APPROVE_RELEASE.check(self)
|
||||||
Permission.APPROVE_RELEASE.check(self)
|
|
||||||
|
|
||||||
def isClaimed(self):
|
def get_profile_pic_url(self):
|
||||||
return self.rank.atLeast(UserRank.NEW_MEMBER)
|
|
||||||
|
|
||||||
def getProfilePicURL(self):
|
|
||||||
if self.profile_pic:
|
if self.profile_pic:
|
||||||
return self.profile_pic
|
return self.profile_pic
|
||||||
elif self.rank == UserRank.BOT:
|
elif self.rank == UserRank.BOT:
|
||||||
@ -228,14 +224,14 @@ class User(db.Model, UserMixin):
|
|||||||
else:
|
else:
|
||||||
return gravatar(self.email or f"{self.username}@content.minetest.net")
|
return gravatar(self.email or f"{self.username}@content.minetest.net")
|
||||||
|
|
||||||
def checkPerm(self, user, perm):
|
def check_perm(self, user, perm):
|
||||||
if not user.is_authenticated:
|
if not user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if type(perm) == str:
|
if type(perm) == str:
|
||||||
perm = Permission[perm]
|
perm = Permission[perm]
|
||||||
elif type(perm) != Permission:
|
elif type(perm) != Permission:
|
||||||
raise Exception("Unknown permission given to User.checkPerm()")
|
raise Exception("Unknown permission given to User.check_perm()")
|
||||||
|
|
||||||
# Members can edit their own packages, and editors can edit any packages
|
# Members can edit their own packages, and editors can edit any packages
|
||||||
if perm == Permission.CHANGE_AUTHOR:
|
if perm == Permission.CHANGE_AUTHOR:
|
||||||
@ -256,7 +252,7 @@ class User(db.Model, UserMixin):
|
|||||||
else:
|
else:
|
||||||
raise Exception("Permission {} is not related to users".format(perm.name))
|
raise Exception("Permission {} is not related to users".format(perm.name))
|
||||||
|
|
||||||
def canCommentRL(self):
|
def can_comment_ratelimit(self):
|
||||||
from app.models import ThreadReply
|
from app.models import ThreadReply
|
||||||
|
|
||||||
factor = 1
|
factor = 1
|
||||||
@ -279,7 +275,7 @@ class User(db.Model, UserMixin):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def canOpenThreadRL(self):
|
def can_open_thread_ratelimit(self):
|
||||||
from app.models import Thread
|
from app.models import Thread
|
||||||
|
|
||||||
factor = 1
|
factor = 1
|
||||||
@ -291,10 +287,10 @@ class User(db.Model, UserMixin):
|
|||||||
factor = 2
|
factor = 2
|
||||||
|
|
||||||
hour_ago = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
|
hour_ago = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
|
||||||
return Thread.query.filter_by(author=self) \
|
return Thread.query.filter_by(author=self)\
|
||||||
.filter(Thread.created_at > hour_ago).count() < 2 * factor
|
.filter(Thread.created_at > hour_ago).count() < 2 * factor
|
||||||
|
|
||||||
def canReviewRL(self):
|
def can_review_ratelimit(self):
|
||||||
from app.models import PackageReview
|
from app.models import PackageReview
|
||||||
|
|
||||||
factor = 1
|
factor = 1
|
||||||
@ -310,8 +306,7 @@ class User(db.Model, UserMixin):
|
|||||||
|
|
||||||
hour_ago = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
|
hour_ago = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
|
||||||
return PackageReview.query.filter_by(author=self) \
|
return PackageReview.query.filter_by(author=self) \
|
||||||
.filter(PackageReview.created_at > hour_ago).count() < 10 * factor
|
.filter(PackageReview.created_at > hour_ago).count() < 10 * factor
|
||||||
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if other is None:
|
if other is None:
|
||||||
@ -324,9 +319,9 @@ class User(db.Model, UserMixin):
|
|||||||
return self.id == other.id
|
return self.id == other.id
|
||||||
|
|
||||||
def can_see_edit_profile(self, current_user):
|
def can_see_edit_profile(self, current_user):
|
||||||
return self.checkPerm(current_user, Permission.CHANGE_USERNAMES) or \
|
return self.check_perm(current_user, Permission.CHANGE_USERNAMES) or \
|
||||||
self.checkPerm(current_user, Permission.CHANGE_EMAIL) or \
|
self.check_perm(current_user, Permission.CHANGE_EMAIL) or \
|
||||||
self.checkPerm(current_user, Permission.CHANGE_RANK)
|
self.check_perm(current_user, Permission.CHANGE_RANK)
|
||||||
|
|
||||||
def can_delete(self):
|
def can_delete(self):
|
||||||
from app.models import ForumTopic
|
from app.models import ForumTopic
|
||||||
@ -392,10 +387,10 @@ class NotificationType(enum.Enum):
|
|||||||
OTHER = 0
|
OTHER = 0
|
||||||
|
|
||||||
|
|
||||||
def getTitle(self):
|
def get_title(self):
|
||||||
return self.name.replace("_", " ").title()
|
return self.name.replace("_", " ").title()
|
||||||
|
|
||||||
def toName(self):
|
def to_name(self):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
def get_description(self):
|
def get_description(self):
|
||||||
@ -430,7 +425,7 @@ class NotificationType(enum.Enum):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def choices(cls):
|
def choices(cls):
|
||||||
return [(choice, choice.getTitle()) for choice in cls]
|
return [(choice, choice.get_title()) for choice in cls]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def coerce(cls, item):
|
def coerce(cls, item):
|
||||||
@ -512,21 +507,21 @@ class UserNotificationPreferences(db.Model):
|
|||||||
self.pref_other = 0
|
self.pref_other = 0
|
||||||
|
|
||||||
def get_can_email(self, notification_type):
|
def get_can_email(self, notification_type):
|
||||||
return getattr(self, "pref_" + notification_type.toName()) == 2
|
return getattr(self, "pref_" + notification_type.to_name()) == 2
|
||||||
|
|
||||||
def set_can_email(self, notification_type, value):
|
def set_can_email(self, notification_type, value):
|
||||||
value = 2 if value else 0
|
value = 2 if value else 0
|
||||||
setattr(self, "pref_" + notification_type.toName(), value)
|
setattr(self, "pref_" + notification_type.to_name(), value)
|
||||||
|
|
||||||
def get_can_digest(self, notification_type):
|
def get_can_digest(self, notification_type):
|
||||||
return getattr(self, "pref_" + notification_type.toName()) >= 1
|
return getattr(self, "pref_" + notification_type.to_name()) >= 1
|
||||||
|
|
||||||
def set_can_digest(self, notification_type, value):
|
def set_can_digest(self, notification_type, value):
|
||||||
if self.get_can_email(notification_type):
|
if self.get_can_email(notification_type):
|
||||||
return
|
return
|
||||||
|
|
||||||
value = 1 if value else 0
|
value = 1 if value else 0
|
||||||
setattr(self, "pref_" + notification_type.toName(), value)
|
setattr(self, "pref_" + notification_type.to_name(), value)
|
||||||
|
|
||||||
|
|
||||||
class UserBan(db.Model):
|
class UserBan(db.Model):
|
||||||
|
@ -128,7 +128,7 @@ class QueryBuilder:
|
|||||||
|
|
||||||
def toJson(package: Package):
|
def toJson(package: Package):
|
||||||
release_id = releases.get(package.id)
|
release_id = releases.get(package.id)
|
||||||
return package.getAsDictionaryShort(current_app.config["BASE_URL"], release_id=release_id, no_load=True)
|
return package.as_short_dict(current_app.config["BASE_URL"], release_id=release_id, no_load=True)
|
||||||
|
|
||||||
return [toJson(pkg) for pkg in packages]
|
return [toJson(pkg) for pkg in packages]
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
|
|||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
|
|
||||||
task_url = url_for('tasks.check', id=self.request.id)
|
task_url = url_for('tasks.check', id=self.request.id)
|
||||||
msg = f"{err}\n\n[View Release]({release.getEditURL()}) | [View Task]({task_url})"
|
msg = f"{err}\n\n[View Release]({release.get_edit_url()}) | [View Task]({task_url})"
|
||||||
post_bot_message(release.package, f"Release {release.title} validation failed", msg)
|
post_bot_message(release.package, f"Release {release.title} validation failed", msg)
|
||||||
|
|
||||||
if "Fails validation" not in release.title:
|
if "Fails validation" not in release.title:
|
||||||
@ -309,7 +309,7 @@ def check_update_config_impl(package):
|
|||||||
db.session.add(rel)
|
db.session.add(rel)
|
||||||
|
|
||||||
msg = "Created release {} (Git Update Detection)".format(rel.title)
|
msg = "Created release {} (Git Update Detection)".format(rel.title)
|
||||||
addSystemAuditLog(AuditSeverity.NORMAL, msg, package.getURL("packages.view"), package)
|
addSystemAuditLog(AuditSeverity.NORMAL, msg, package.get_url("packages.view"), package)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ def check_update_config(self, package_id):
|
|||||||
.strip()
|
.strip()
|
||||||
|
|
||||||
msg = "Error: {}.\n\n[Change update configuration]({}) | [View task]({})" \
|
msg = "Error: {}.\n\n[Change update configuration]({}) | [View task]({})" \
|
||||||
.format(err, package.getURL("packages.update_config"), url_for("tasks.check", id=self.request.id))
|
.format(err, package.get_url("packages.update_config"), url_for("tasks.check", id=self.request.id))
|
||||||
|
|
||||||
post_bot_message(package, "Failed to check git repository", msg)
|
post_bot_message(package, "Failed to check git repository", msg)
|
||||||
|
|
||||||
|
@ -24,6 +24,6 @@ def updatePackageScores():
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
for package in Package.query.all():
|
for package in Package.query.all():
|
||||||
package.recalcScore()
|
package.recalculate_score()
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -36,7 +36,7 @@ def post_discord_webhook(username: Optional[str], content: str, is_queue: bool,
|
|||||||
json["username"] = username
|
json["username"] = username
|
||||||
user = User.query.filter_by(username=username).first()
|
user = User.query.filter_by(username=username).first()
|
||||||
if user:
|
if user:
|
||||||
json["avatar_url"] = user.getProfilePicURL().replace("/./", "/")
|
json["avatar_url"] = user.get_profile_pic_url().replace("/./", "/")
|
||||||
if json["avatar_url"].startswith("/"):
|
if json["avatar_url"].startswith("/"):
|
||||||
json["avatar_url"] = app.config["BASE_URL"] + json["avatar_url"]
|
json["avatar_url"] = app.config["BASE_URL"] + json["avatar_url"]
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ def search_in_releases(query: str, file_filter: str):
|
|||||||
continue
|
continue
|
||||||
elif exit_code == 0:
|
elif exit_code == 0:
|
||||||
results.append({
|
results.append({
|
||||||
"package": package.getAsDictionaryKey(),
|
"package": package.as_key_dict(),
|
||||||
"lines": handle.stdout.read(),
|
"lines": handle.stdout.read(),
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ def search_in_releases(query: str, file_filter: str):
|
|||||||
# Create new
|
# Create new
|
||||||
while len(running) < 1 and len(packages) > 0:
|
while len(running) < 1 and len(packages) > 0:
|
||||||
package = packages.pop()
|
package = packages.pop()
|
||||||
release: Optional[PackageRelease] = package.getDownloadRelease()
|
release: Optional[PackageRelease] = package.get_download_release()
|
||||||
if release:
|
if release:
|
||||||
handle = Popen(["zipgrep", query, release.file_path, file_filter], stdout=PIPE, encoding="UTF-8")
|
handle = Popen(["zipgrep", query, release.file_path, file_filter], stdout=PIPE, encoding="UTF-8")
|
||||||
running.append([package, handle])
|
running.append([package, handle])
|
||||||
|
@ -20,7 +20,7 @@ def inject_debug():
|
|||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_functions():
|
def inject_functions():
|
||||||
check_global_perm = Permission.checkPerm
|
check_global_perm = Permission.check_perm
|
||||||
return dict(abs_url_for=abs_url_for, url_set_query=url_set_query, url_set_anchor=url_set_anchor,
|
return dict(abs_url_for=abs_url_for, url_set_query=url_set_query, url_set_anchor=url_set_anchor,
|
||||||
check_global_perm=check_global_perm, get_headings=get_headings, url_current=url_current)
|
check_global_perm=check_global_perm, get_headings=get_headings, url_current=url_current)
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ def inject_functions():
|
|||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_todo():
|
def inject_todo():
|
||||||
todo_list_count = None
|
todo_list_count = None
|
||||||
if current_user and current_user.is_authenticated and current_user.canAccessTodoList():
|
if current_user and current_user.is_authenticated and current_user.can_access_todo_list():
|
||||||
todo_list_count = Package.query.filter_by(state=PackageState.READY_FOR_REVIEW).count()
|
todo_list_count = Package.query.filter_by(state=PackageState.READY_FOR_REVIEW).count()
|
||||||
todo_list_count += PackageRelease.query.filter_by(approved=False, task_id=None).count()
|
todo_list_count += PackageRelease.query.filter_by(approved=False, task_id=None).count()
|
||||||
|
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-auto text-muted" style="min-width: 250px;">
|
<div class="col-sm-auto text-muted" style="min-width: 250px;">
|
||||||
<a href="{{ package.getURL('packages.view') }}">
|
<a href="{{ package.get_url('packages.view') }}">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-auto">
|
<div class="col-sm-auto">
|
||||||
<a href="{{ package.getURL('packages.view') }}" class="btn btn-sm btn-secondary mr-1">
|
<a href="{{ package.get_url('packages.view') }}" class="btn btn-sm btn-secondary mr-1">
|
||||||
{{ _("View package") }}
|
{{ _("View package") }}
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ package.donate_url_actual }}" class="btn btn-sm btn-primary" rel="nofollow">
|
<a href="{{ package.donate_url_actual }}" class="btn btn-sm btn-primary" rel="nofollow">
|
||||||
|
@ -34,5 +34,5 @@
|
|||||||
{{ _("Unsubscribe") }}
|
{{ _("Unsubscribe") }}
|
||||||
</a> <br>
|
</a> <br>
|
||||||
|
|
||||||
{{ _("This is a '%(type)s' notification.", type=notification.type.getTitle()) }}
|
{{ _("This is a '%(type)s' notification.", type=notification.type.get_title()) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -33,10 +33,10 @@
|
|||||||
</ol>
|
</ol>
|
||||||
<div class="carousel-inner">
|
<div class="carousel-inner">
|
||||||
{% for package in spotlight_pkgs %}
|
{% for package in spotlight_pkgs %}
|
||||||
{% set cover_image = package.getCoverImageURL() %}
|
{% set cover_image = package.get_cover_image_url() %}
|
||||||
{% set tags = package.tags | sort(attribute="views", reverse=True) %}
|
{% set tags = package.tags | sort(attribute="views", reverse=True) %}
|
||||||
<div class="carousel-item {% if loop.index == 1 %}active{% endif %}">
|
<div class="carousel-item {% if loop.index == 1 %}active{% endif %}">
|
||||||
<a href="{{ package.getURL("packages.view") }}">
|
<a href="{{ package.get_url("packages.view") }}">
|
||||||
<div class="embed-responsive embed-responsive-16by9">
|
<div class="embed-responsive embed-responsive-16by9">
|
||||||
<img class="embed-responsive-item" src="{{ cover_image }}"
|
<img class="embed-responsive-item" src="{{ cover_image }}"
|
||||||
alt="{{ _('%(title)s by %(author)s', title=package.title, author=package.author.display_name) }}">
|
alt="{{ _('%(title)s by %(author)s', title=package.title, author=package.author.display_name) }}">
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="list-group mt-3">
|
<div class="list-group mt-3">
|
||||||
{% for entry in log %}
|
{% for entry in log %}
|
||||||
<a class="list-group-item list-group-item-action"
|
<a class="list-group-item list-group-item-action"
|
||||||
{% if entry.description and entry.checkPerm(current_user, 'VIEW_AUDIT_DESCRIPTION') %}
|
{% if entry.description and entry.check_perm(current_user, 'VIEW_AUDIT_DESCRIPTION') %}
|
||||||
href="{{ url_for('admin.audit_view', id_=entry.id) }}">
|
href="{{ url_for('admin.audit_view', id_=entry.id) }}">
|
||||||
{% else %}
|
{% else %}
|
||||||
href="{{ entry.url }}">
|
href="{{ entry.url }}">
|
||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<div class="row {% if entry.severity == entry.severity.NORMAL %}text-muted{% endif %}">
|
<div class="row {% if entry.severity == entry.severity.NORMAL %}text-muted{% endif %}">
|
||||||
<div class="col-sm-auto text-center" style="width: 50px;"
|
<div class="col-sm-auto text-center" style="width: 50px;"
|
||||||
title="{{ _('Severity: %(sev)s.', sev=entry.severity.getTitle()) }}">
|
title="{{ _('Severity: %(sev)s.', sev=entry.severity.get_title()) }}">
|
||||||
{% if entry.severity == entry.severity.MODERATION %}
|
{% if entry.severity == entry.severity.MODERATION %}
|
||||||
<i class="fas fa-exclamation-triangle" style="color: yellow;"></i>
|
<i class="fas fa-exclamation-triangle" style="color: yellow;"></i>
|
||||||
{% elif entry.severity == entry.severity.EDITOR %}
|
{% elif entry.severity == entry.severity.EDITOR %}
|
||||||
@ -25,7 +25,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
||||||
style="max-height: 22px;"
|
style="max-height: 22px;"
|
||||||
src="{{ entry.causer.getProfilePicURL() }}" />
|
src="{{ entry.causer.get_profile_pic_url() }}" />
|
||||||
|
|
||||||
<span class="pl-2">{{ entry.causer.username }}</span>
|
<span class="pl-2">{{ entry.causer.username }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -50,7 +50,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ entry.package.getThumbnailOrPlaceholder() }}" />
|
src="{{ entry.package.get_thumb_or_placeholder() }}" />
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
{{ _("State") }}: <strong>{{ package.state.value }}</strong>
|
{{ _("State") }}: <strong>{{ package.state.value }}</strong>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{% for state in package.getNextStates(current_user) %}
|
{% for state in package.get_next_states(current_user) %}
|
||||||
<form class="col-auto" method="post" action="{{ package.getSetStateURL(state) }}">
|
<form class="col-auto" method="post" action="{{ package.get_set_state_url(state) }}">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<input class="btn btn-sm btn-primary" type="submit" value="{{ state.verb() }}" />
|
<input class="btn btn-sm btn-primary" type="submit" value="{{ state.verb() }}" />
|
||||||
</form>
|
</form>
|
||||||
@ -16,13 +16,13 @@
|
|||||||
{% set level = "warning" %}
|
{% set level = "warning" %}
|
||||||
{% if package.releases.filter_by(task_id=None).count() == 0 %}
|
{% if package.releases.filter_by(task_id=None).count() == 0 %}
|
||||||
{% set message %}
|
{% set message %}
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
{% if package.update_config %}
|
{% if package.update_config %}
|
||||||
<a class="btn btn-sm btn-warning float-right" href="{{ package.getURL('packages.create_release') }}">
|
<a class="btn btn-sm btn-warning float-right" href="{{ package.get_url('packages.create_release') }}">
|
||||||
{{ _("Create release") }}
|
{{ _("Create release") }}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="btn btn-sm btn-warning float-right" href="{{ package.getURL('packages.setup_releases') }}">
|
<a class="btn btn-sm btn-warning float-right" href="{{ package.get_url('packages.setup_releases') }}">
|
||||||
{{ _("Set up releases") }}
|
{{ _("Set up releases") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -40,8 +40,8 @@
|
|||||||
{% elif (package.type == package.type.GAME or package.type == package.type.TXP) and package.screenshots.count() == 0 %}
|
{% elif (package.type == package.type.GAME or package.type == package.type.TXP) and package.screenshots.count() == 0 %}
|
||||||
{% set message = _("You need to add at least one screenshot.") %}
|
{% set message = _("You need to add at least one screenshot.") %}
|
||||||
|
|
||||||
{% elif package.getMissingHardDependenciesQuery().count() > 0 %}
|
{% elif package.get_missing_hard_dependencies_query().count() > 0 %}
|
||||||
{% set deps = package.getMissingHardDependencies() | join(", ") %}
|
{% set deps = package.get_missing_hard_dependencies() | join(", ") %}
|
||||||
{% set message = _("The following hard dependencies need to be added to ContentDB first: %(deps)s", deps=deps) %}
|
{% set message = _("The following hard dependencies need to be added to ContentDB first: %(deps)s", deps=deps) %}
|
||||||
|
|
||||||
{% elif topic_error_lvl == "danger" %}
|
{% elif topic_error_lvl == "danger" %}
|
||||||
@ -58,15 +58,15 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if package.state == package.state.READY_FOR_REVIEW %}
|
{% if package.state == package.state.READY_FOR_REVIEW %}
|
||||||
{% if not package.getDownloadRelease() %}
|
{% if not package.get_download_release() %}
|
||||||
{{ _("Please wait for the release to be approved.") }}
|
{{ _("Please wait for the release to be approved.") }}
|
||||||
{% elif package.checkPerm(current_user, "APPROVE_NEW") %}
|
{% elif package.check_perm(current_user, "APPROVE_NEW") %}
|
||||||
{{ _("You can now approve this package if you're ready.") }}
|
{{ _("You can now approve this package if you're ready.") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _("Please wait for the package to be approved.") }}
|
{{ _("Please wait for the package to be approved.") }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
|
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
|
||||||
{{ _("You can now submit this package for approval if you're ready.") }}
|
{{ _("You can now submit this package for approval if you're ready.") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _("This package can be submitted for approval when ready.") }}
|
{{ _("This package can be submitted for approval when ready.") }}
|
||||||
@ -95,7 +95,7 @@
|
|||||||
|
|
||||||
{% if conflicting_modnames %}
|
{% if conflicting_modnames %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
<a class="float-right btn btn-sm btn-warning" href="{{ package.getURL('packages.similar') }}">
|
<a class="float-right btn btn-sm btn-warning" href="{{ package.get_url('packages.similar') }}">
|
||||||
More info
|
More info
|
||||||
</a>
|
</a>
|
||||||
{% if conflicting_modnames | length > 4 %}
|
{% if conflicting_modnames | length > 4 %}
|
||||||
@ -106,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if not package.review_thread and (package.author == current_user or package.checkPerm(current_user, "APPROVE_NEW")) %}
|
{% if not package.review_thread and (package.author == current_user or package.check_perm(current_user, "APPROVE_NEW")) %}
|
||||||
<div class="alert alert-secondary">
|
<div class="alert alert-secondary">
|
||||||
<a class="float-right btn btn-sm btn-secondary" href="{{ url_for('threads.new', pid=package.id, title='Package approval comments') }}">
|
<a class="float-right btn btn-sm btn-secondary" href="{{ url_for('threads.new', pid=package.id, title='Package approval comments') }}">
|
||||||
{{ _("Open Thread") }}
|
{{ _("Open Thread") }}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% macro render_pkgtile(package, show_author) -%}
|
{% macro render_pkgtile(package, show_author) -%}
|
||||||
<li class="packagetile flex-fill"><a href="{{ package.getURL("packages.view") }}"
|
<li class="packagetile flex-fill"><a href="{{ package.get_url("packages.view") }}"
|
||||||
style="background-image: url({{ package.getThumbnailOrPlaceholder(2) }});">
|
style="background-image: url({{ package.get_thumb_or_placeholder(2) }});">
|
||||||
<div class="packagegridscrub"></div>
|
<div class="packagegridscrub"></div>
|
||||||
<div class="packagegridinfo">
|
<div class="packagegridinfo">
|
||||||
<h3>
|
<h3>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% macro render_releases_edit(releases, package) %}
|
{% macro render_releases_edit(releases, package) %}
|
||||||
{% for rel in releases %}
|
{% for rel in releases %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ rel.getEditURL() }}">
|
<a class="list-group-item list-group-item-action" href="{{ rel.get_edit_url() }}">
|
||||||
{{ rel.title }}
|
{{ rel.title }}
|
||||||
<span class="text-muted ml-1">
|
<span class="text-muted ml-1">
|
||||||
{% if rel.min_rel and rel.max_rel %}
|
{% if rel.min_rel and rel.max_rel %}
|
||||||
@ -26,8 +26,8 @@
|
|||||||
|
|
||||||
{% macro render_releases_download(releases, package, current_user) %}
|
{% macro render_releases_download(releases, package, current_user) %}
|
||||||
{% for rel in releases %}
|
{% for rel in releases %}
|
||||||
{% if rel.approved or package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE") %}
|
{% if rel.approved or package.check_perm(current_user, "MAKE_RELEASE") or rel.check_perm(current_user, "APPROVE_RELEASE") %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ rel.getDownloadURL() }}">
|
<a class="list-group-item list-group-item-action" href="{{ rel.get_download_url() }}">
|
||||||
{{ rel.title }}
|
{{ rel.title }}
|
||||||
<span class="text-muted ml-1">
|
<span class="text-muted ml-1">
|
||||||
{% if rel.min_rel and rel.max_rel %}
|
{% if rel.min_rel and rel.max_rel %}
|
||||||
@ -55,8 +55,8 @@
|
|||||||
{% macro render_releases(releases, package, current_user) -%}
|
{% macro render_releases(releases, package, current_user) -%}
|
||||||
{% for rel in releases %}
|
{% for rel in releases %}
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
<a class="btn btn-sm btn-primary float-right" href="{{ rel.getEditURL() }}">
|
<a class="btn btn-sm btn-primary float-right" href="{{ rel.get_edit_url() }}">
|
||||||
{% if not rel.task_id and not rel.approved and rel.checkPerm(current_user, "APPROVE_RELEASE") %}
|
{% if not rel.task_id and not rel.approved and rel.check_perm(current_user, "APPROVE_RELEASE") %}
|
||||||
{{ _("Edit / Approve") }}
|
{{ _("Edit / Approve") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _("Edit") }}
|
{{ _("Edit") }}
|
||||||
@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
{% if not rel.approved %}<i>{% endif %}
|
{% if not rel.approved %}<i>{% endif %}
|
||||||
|
|
||||||
<a href="{{ rel.getDownloadURL() }}" rel="nofollow" download="{{ rel.getDownloadFileName() }}">
|
<a href="{{ rel.get_download_url() }}" rel="nofollow" download="{{ rel.get_download_filename() }}">
|
||||||
{{ rel.title }}
|
{{ rel.title }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@ -88,8 +88,8 @@
|
|||||||
|
|
||||||
{{ _("created %(date)s", date=rel.releaseDate | date) }}.
|
{{ _("created %(date)s", date=rel.releaseDate | date) }}.
|
||||||
</small>
|
</small>
|
||||||
{% if (package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE")) and rel.task_id %}
|
{% if (package.check_perm(current_user, "MAKE_RELEASE") or rel.check_perm(current_user, "APPROVE_RELEASE")) and rel.task_id %}
|
||||||
<a href="{{ url_for('tasks.check', id=rel.task_id, r=package.getURL("packages.view")) }}">
|
<a href="{{ url_for('tasks.check', id=rel.task_id, r=package.get_url("packages.view")) }}">
|
||||||
{{ _("Importing...") }}
|
{{ _("Importing...") }}
|
||||||
</a>
|
</a>
|
||||||
{% elif not rel.approved %}
|
{% elif not rel.approved %}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<a id="{{ review_anchor }}"></a>
|
<a id="{{ review_anchor }}"></a>
|
||||||
<div class="col-md-1 p-1">
|
<div class="col-md-1 p-1">
|
||||||
<a href="{{ url_for('users.profile', username=review.author.username) }}">
|
<a href="{{ url_for('users.profile', username=review.author.username) }}">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ review.author.getProfilePicURL() }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ review.author.get_profile_pic_url() }}">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-auto pl-1 pr-3 pt-2 text-center" style=" font-size: 200%;">
|
<div class="col-md-auto pl-1 pr-3 pt-2 text-center" style=" font-size: 200%;">
|
||||||
@ -58,7 +58,7 @@
|
|||||||
<div class="card-body markdown">
|
<div class="card-body markdown">
|
||||||
{% if current_user == review.author %}
|
{% if current_user == review.author %}
|
||||||
<a class="btn btn-primary btn-sm ml-1 float-right"
|
<a class="btn btn-primary btn-sm ml-1 float-right"
|
||||||
href="{{ review.package.getURL("packages.review") }}">
|
href="{{ review.package.get_url("packages.review") }}">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
<div class="btn-toolbar mt-2 mb-0">
|
<div class="btn-toolbar mt-2 mb-0">
|
||||||
{% if show_package_link %}
|
{% if show_package_link %}
|
||||||
<a class="btn btn-primary mr-1" href="{{ review.package.getURL("packages.view") }}">
|
<a class="btn btn-primary mr-1" href="{{ review.package.get_url("packages.view") }}">
|
||||||
{{ _("%(title)s by %(author)s",
|
{{ _("%(title)s by %(author)s",
|
||||||
title="<b>" | safe + review.package.title + "</b>" | safe,
|
title="<b>" | safe + review.package.title + "</b>" | safe,
|
||||||
author=review.package.author.display_name) }}
|
author=review.package.author.display_name) }}
|
||||||
@ -105,7 +105,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
{{ _("Review") }}
|
{{ _("Review") }}
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="{{ package.getURL("packages.review") }}" class="card-body">
|
<form method="post" action="{{ package.get_url("packages.review") }}" class="card-body">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<p>
|
<p>
|
||||||
{{ _("Do you recommend this %(type)s?", type=package.type.text | lower) }}
|
{{ _("Do you recommend this %(type)s?", type=package.type.text | lower) }}
|
||||||
@ -148,7 +148,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
{{ _("Review") }}
|
{{ _("Review") }}
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="{{ package.getURL("packages.review") }}" class="card-body">
|
<form method="post" action="{{ package.get_url("packages.review") }}" class="card-body">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<p>
|
<p>
|
||||||
{{ _("Do you recommend this %(type)s?", type=package.type.text | lower) }}
|
{{ _("Do you recommend this %(type)s?", type=package.type.text | lower) }}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
{% for package in user.packages.filter_by(state='APPROVED').all() %}
|
{% for package in user.packages.filter_by(state='APPROVED').all() %}
|
||||||
<a class="dropdown-item" href="{{ package.getURL('packages.statistics') }}">
|
<a class="dropdown-item" href="{{ package.get_url('packages.statistics') }}">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<li class="row my-2 mx-0">
|
<li class="row my-2 mx-0">
|
||||||
<div class="col-md-1 p-1">
|
<div class="col-md-1 p-1">
|
||||||
<a href="{{ url_for('users.profile', username=r.author.username) }}">
|
<a href="{{ url_for('users.profile', username=r.author.username) }}">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ r.author.getProfilePicURL() }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ r.author.get_profile_pic_url() }}">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col pr-0">
|
<div class="col pr-0">
|
||||||
@ -28,7 +28,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if r.author.rank == r.author.rank.BOT %}
|
{% if r.author.rank == r.author.rank.BOT %}
|
||||||
<span class="badge badge-dark">
|
<span class="badge badge-dark">
|
||||||
{{ r.author.rank.getTitle() }}
|
{{ r.author.rank.get_title() }}
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body markdown">
|
<div class="card-body markdown">
|
||||||
{% if r.checkPerm(current_user, "DELETE_REPLY") %}
|
{% if r.check_perm(current_user, "DELETE_REPLY") %}
|
||||||
<a class="float-right btn btn-secondary btn-sm ml-2"
|
<a class="float-right btn btn-secondary btn-sm ml-2"
|
||||||
href="{{ url_for('threads.delete_reply', id=thread.id, reply=r.id) }}">
|
href="{{ url_for('threads.delete_reply', id=thread.id, reply=r.id) }}">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
@ -55,10 +55,10 @@
|
|||||||
|
|
||||||
{% if current_user == thread.author and thread.review and thread.first_reply == r %}
|
{% if current_user == thread.author and thread.review and thread.first_reply == r %}
|
||||||
<a class="float-right btn btn-primary btn-sm ml-2"
|
<a class="float-right btn btn-primary btn-sm ml-2"
|
||||||
href="{{ thread.review.package.getURL('packages.review') }}">
|
href="{{ thread.review.package.get_url('packages.review') }}">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
</a>
|
</a>
|
||||||
{% elif r.checkPerm(current_user, "EDIT_REPLY") %}
|
{% elif r.check_perm(current_user, "EDIT_REPLY") %}
|
||||||
<a class="float-right btn btn-primary btn-sm ml-2"
|
<a class="float-right btn btn-primary btn-sm ml-2"
|
||||||
href="{{ url_for('threads.edit_reply', id=thread.id, reply=r.id) }}">
|
href="{{ url_for('threads.edit_reply', id=thread.id, reply=r.id) }}">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
@ -68,7 +68,7 @@
|
|||||||
{{ r.comment | markdown }}
|
{{ r.comment | markdown }}
|
||||||
|
|
||||||
{% if thread.first_reply == r and thread.review %}
|
{% if thread.first_reply == r and thread.review %}
|
||||||
{{ render_review_vote(thread.review, current_user, thread.getViewURL()) }}
|
{{ render_review_vote(thread.review, current_user, thread.get_view_url()) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -81,7 +81,7 @@
|
|||||||
<li class="row my-2 mx-0 align-items-center">
|
<li class="row my-2 mx-0 align-items-center">
|
||||||
<div class="col-md-1 p-1">
|
<div class="col-md-1 p-1">
|
||||||
<a href="{{ url_for('users.profile', username=r.author.username) }}">
|
<a href="{{ url_for('users.profile', username=r.author.username) }}">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ r.author.getProfilePicURL() }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ r.author.get_profile_pic_url() }}">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
@ -137,7 +137,7 @@
|
|||||||
<div class="row mt-0 mb-4 comments mx-0">
|
<div class="row mt-0 mb-4 comments mx-0">
|
||||||
<div class="col-md-1 p-1">
|
<div class="col-md-1 p-1">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
||||||
src="{{ current_user.getProfilePicURL() }}">
|
src="{{ current_user.get_profile_pic_url() }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="col pr-0">
|
<div class="col pr-0">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@ -146,12 +146,12 @@
|
|||||||
<a name="reply"></a>
|
<a name="reply"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if not current_user.canCommentRL() %}
|
{% if not current_user.can_comment_ratelimit() %}
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<textarea class="form-control" readonly disabled>{{ _("Please wait before commenting again.") }}</textarea><br />
|
<textarea class="form-control" readonly disabled>{{ _("Please wait before commenting again.") }}</textarea><br />
|
||||||
<input class="btn btn-primary" type="submit" disabled value="Comment" />
|
<input class="btn btn-primary" type="submit" disabled value="Comment" />
|
||||||
</div>
|
</div>
|
||||||
{% elif not thread.checkPerm(current_user, "COMMENT_THREAD") %}
|
{% elif not thread.check_perm(current_user, "COMMENT_THREAD") %}
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if thread.locked %}
|
{% if thread.locked %}
|
||||||
<textarea class="form-control" readonly disabled>{{ _("This thread has been locked.") }}</textarea><br />
|
<textarea class="form-control" readonly disabled>{{ _("This thread has been locked.") }}</textarea><br />
|
||||||
@ -266,7 +266,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ t.package.getThumbnailOrPlaceholder() }}" /><br />
|
src="{{ t.package.get_thumb_or_placeholder() }}" /><br />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ t.package.title }}
|
{{ t.package.title }}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
{% set config = package.update_config %}
|
{% set config = package.update_config %}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<a class="col-sm-auto text-muted" style="min-width: 200px;" href="{{ package.getURL("packages.view") }}">
|
<a class="col-sm-auto text-muted" style="min-width: 200px;" href="{{ package.get_url("packages.view") }}">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
<div class="col-sm-auto">
|
<div class="col-sm-auto">
|
||||||
{% if not show_config %}
|
{% if not show_config %}
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
<a class="btn btn-sm btn-primary mr-2" href="{{ config.get_create_release_url() }}">
|
<a class="btn btn-sm btn-primary mr-2" href="{{ config.get_create_release_url() }}">
|
||||||
<i class="fas fa-plus mr-1"></i>
|
<i class="fas fa-plus mr-1"></i>
|
||||||
{{ _("Release") }}
|
{{ _("Release") }}
|
||||||
@ -42,8 +42,8 @@
|
|||||||
{{ _("Repo") }}
|
{{ _("Repo") }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
<a class="btn btn-sm btn-secondary" href="{{ package.getURL("packages.update_config") }}">
|
<a class="btn btn-sm btn-secondary" href="{{ package.get_url("packages.update_config") }}">
|
||||||
<i class="fas fa-cog mr-1"></i>
|
<i class="fas fa-cog mr-1"></i>
|
||||||
{{ _("Update settings") }}
|
{{ _("Update settings") }}
|
||||||
</a>
|
</a>
|
||||||
@ -60,13 +60,13 @@
|
|||||||
{% macro render_mtsupport_packages(packages, current_user, show_config=False) -%}
|
{% macro render_mtsupport_packages(packages, current_user, show_config=False) -%}
|
||||||
<div class="list-group mt-3">
|
<div class="list-group mt-3">
|
||||||
{% for package in packages %}
|
{% for package in packages %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ package.getURL('packages.list_releases') }}">
|
<a class="list-group-item list-group-item-action" href="{{ package.get_url('packages.list_releases') }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-auto text-muted" style="min-width: 200px;">
|
<div class="col-sm-auto text-muted" style="min-width: 200px;">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -74,7 +74,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
{% set release = package.getDownloadRelease() %}
|
{% set release = package.get_download_release() %}
|
||||||
{% if release %}
|
{% if release %}
|
||||||
{{ release.min_rel.name }} - {{ release.max_rel.name }}
|
{{ release.min_rel.name }} - {{ release.max_rel.name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -23,13 +23,13 @@
|
|||||||
<td>{{ topic.name or ""}}</td>
|
<td>{{ topic.name or ""}}</td>
|
||||||
<td>{{ topic.created_at | date }}</td>
|
<td>{{ topic.created_at | date }}</td>
|
||||||
<td class="btn-group">
|
<td class="btn-group">
|
||||||
{% if current_user == topic.author or topic.author.checkPerm(current_user, "CHANGE_AUTHOR") %}
|
{% if current_user == topic.author or topic.author.check_perm(current_user, "CHANGE_AUTHOR") %}
|
||||||
<a class="btn btn-primary"
|
<a class="btn btn-primary"
|
||||||
href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.getRepoURL(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
|
href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.getRepoURL(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
|
||||||
{{ _("Create") }}
|
{{ _("Create") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if show_discard and current_user.is_authenticated and topic.checkPerm(current_user, "TOPIC_DISCARD") %}
|
{% if show_discard and current_user.is_authenticated and topic.check_perm(current_user, "TOPIC_DISCARD") %}
|
||||||
<a class="btn btn-{% if topic.discarded %}success{% else %}danger{% endif %} topic-discard" data-tid={{ topic.topic_id }}>
|
<a class="btn btn-{% if topic.discarded %}success{% else %}danger{% endif %} topic-discard" data-tid={{ topic.topic_id }}>
|
||||||
{% if topic.discarded %}
|
{% if topic.discarded %}
|
||||||
{{ _("Show") }}
|
{{ _("Show") }}
|
||||||
@ -59,7 +59,7 @@
|
|||||||
{% if show_author %}
|
{% if show_author %}
|
||||||
by <a href="{{ url_for('users.profile', username=topic.author.username) }}">{{ topic.author.display_name }}</a>
|
by <a href="{{ url_for('users.profile', username=topic.author.username) }}">{{ topic.author.display_name }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if topic.author == current_user or topic.author.checkPerm(current_user, "CHANGE_AUTHOR") %}
|
{% if topic.author == current_user or topic.author.check_perm(current_user, "CHANGE_AUTHOR") %}
|
||||||
|
|
|
|
||||||
<a href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.getRepoURL(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
|
<a href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.getRepoURL(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
|
||||||
{{ _("Create") }}
|
{{ _("Create") }}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ n.package.getThumbnailOrPlaceholder() }}" />
|
src="{{ n.package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ n.package.title }}
|
{{ n.package.title }}
|
||||||
@ -53,7 +53,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
||||||
style="max-height: 22px;"
|
style="max-height: 22px;"
|
||||||
src="{{ n.causer.getProfilePicURL() }}" />
|
src="{{ n.causer.get_profile_pic_url() }}" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
@ -74,7 +74,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ n.package.getThumbnailOrPlaceholder() }}" />
|
src="{{ n.package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ n.package.title }}
|
{{ n.package.title }}
|
||||||
@ -91,7 +91,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
||||||
style="max-height: 22px;"
|
style="max-height: 22px;"
|
||||||
src="{{ n.causer.getProfilePicURL() }}" />
|
src="{{ n.causer.get_profile_pic_url() }}" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block link %}
|
{% block link %}
|
||||||
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
|
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<a class="btn btn-secondary" href="{{ package.getURL("packages.alias_list") }}">
|
<a class="btn btn-secondary" href="{{ package.get_url("packages.alias_list") }}">
|
||||||
{{ _("Back to Aliases") }}
|
{{ _("Back to Aliases") }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -5,18 +5,18 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block link %}
|
{% block link %}
|
||||||
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
|
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<a class="btn btn-primary float-right" href="{{ package.getURL("packages.alias_create_edit") }}">
|
<a class="btn btn-primary float-right" href="{{ package.get_url("packages.alias_create_edit") }}">
|
||||||
{{ _("Create") }}
|
{{ _("Create") }}
|
||||||
</a>
|
</a>
|
||||||
<h1>{{ _("Aliases for %(title)s by %(author)s", title=self.link(), author=package.author.display_name) }}</h1>
|
<h1>{{ _("Aliases for %(title)s by %(author)s", title=self.link(), author=package.author.display_name) }}</h1>
|
||||||
|
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% for alias in package.aliases %}
|
{% for alias in package.aliases %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ alias.getEditURL() }}">
|
<a class="list-group-item list-group-item-action" href="{{ alias.get_edit_url() }}">
|
||||||
{{ alias.author }} / {{ alias.name }}
|
{{ alias.author }} / {{ alias.name }}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
{{ render_field(form.type, class_="pkg_meta col-sm-2") }}
|
{{ render_field(form.type, class_="pkg_meta col-sm-2") }}
|
||||||
{{ render_field(form.title, class_="pkg_meta col-sm-6") }}
|
{{ render_field(form.title, class_="pkg_meta col-sm-6") }}
|
||||||
{% if package and package.approved and not package.checkPerm(current_user, "CHANGE_NAME") %}
|
{% if package and package.approved and not package.check_perm(current_user, "CHANGE_NAME") %}
|
||||||
{{ render_field(form.name, class_="pkg_meta col-sm-4",
|
{{ render_field(form.name, class_="pkg_meta col-sm-4",
|
||||||
readonly=True, hint=_("Please open a thread to request a name change")) }}
|
readonly=True, hint=_("Please open a thread to request a name change")) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block headextra %}
|
{% block headextra %}
|
||||||
{% if package.getThumbnailURL(3, True) %}
|
{% if package.get_thumb_url(3, True) %}
|
||||||
<meta name="og:image" content="{{ package.getThumbnailURL(3, True) }}"/>
|
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -21,40 +21,40 @@
|
|||||||
|
|
||||||
<h1 class="mb-5">
|
<h1 class="mb-5">
|
||||||
{{ _("Community Hub") }} -
|
{{ _("Community Hub") }} -
|
||||||
<a href="{{ package.getURL('packages.view') }}">
|
<a href="{{ package.get_url('packages.view') }}">
|
||||||
{{ _('%(title)s by %(author)s', title=package.title, author=package.author.display_name) }}
|
{{ _('%(title)s by %(author)s', title=package.title, author=package.author.display_name) }}
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<a href="{{ url_for('packages.list_all', sort='approved_at', order='desc', game=package.getId()) }}" class="btn btn-secondary float-right">
|
<a href="{{ url_for('packages.list_all', sort='approved_at', order='desc', game=package.get_id()) }}" class="btn btn-secondary float-right">
|
||||||
{{ _("See more") }}
|
{{ _("See more") }}
|
||||||
</a>
|
</a>
|
||||||
<h2 class="my-3">{{ _("Recently Added") }}</h2>
|
<h2 class="my-3">{{ _("Recently Added") }}</h2>
|
||||||
{{ render_pkggrid(new) }}
|
{{ render_pkggrid(new) }}
|
||||||
|
|
||||||
|
|
||||||
<a href="{{ url_for('packages.list_all', sort='last_release', order='desc', game=package.getId()) }}" class="btn btn-secondary float-right">
|
<a href="{{ url_for('packages.list_all', sort='last_release', order='desc', game=package.get_id()) }}" class="btn btn-secondary float-right">
|
||||||
{{ _("See more") }}
|
{{ _("See more") }}
|
||||||
</a>
|
</a>
|
||||||
<h2 class="my-3">{{ _("Recently Updated") }}</h2>
|
<h2 class="my-3">{{ _("Recently Updated") }}</h2>
|
||||||
{{ render_pkggrid(updated) }}
|
{{ render_pkggrid(updated) }}
|
||||||
|
|
||||||
|
|
||||||
<a href="{{ url_for('packages.list_all', type='mod', sort='score', order='desc', game=package.getId()) }}" class="btn btn-secondary float-right">
|
<a href="{{ url_for('packages.list_all', type='mod', sort='score', order='desc', game=package.get_id()) }}" class="btn btn-secondary float-right">
|
||||||
{{ _("See more") }}
|
{{ _("See more") }}
|
||||||
</a>
|
</a>
|
||||||
<h2 class="my-3">{{ _("Top Mods") }}</h2>
|
<h2 class="my-3">{{ _("Top Mods") }}</h2>
|
||||||
{{ render_pkggrid(pop_mod) }}
|
{{ render_pkggrid(pop_mod) }}
|
||||||
|
|
||||||
|
|
||||||
<a href="{{ url_for('packages.list_all', type='txp', sort='score', order='desc', game=package.getId()) }}" class="btn btn-secondary float-right">
|
<a href="{{ url_for('packages.list_all', type='txp', sort='score', order='desc', game=package.get_id()) }}" class="btn btn-secondary float-right">
|
||||||
{{ _("See more") }}
|
{{ _("See more") }}
|
||||||
</a>
|
</a>
|
||||||
<h2 class="my-3">{{ _("Top Texture Packs") }}</h2>
|
<h2 class="my-3">{{ _("Top Texture Packs") }}</h2>
|
||||||
{{ render_pkggrid(pop_txp) }}
|
{{ render_pkggrid(pop_txp) }}
|
||||||
|
|
||||||
|
|
||||||
<a href="{{ url_for('packages.list_all', sort='reviews', order='desc', game=package.getId()) }}" class="btn btn-secondary float-right">
|
<a href="{{ url_for('packages.list_all', sort='reviews', order='desc', game=package.get_id()) }}" class="btn btn-secondary float-right">
|
||||||
{{ _("See more") }}
|
{{ _("See more") }}
|
||||||
</a>
|
</a>
|
||||||
<h2 class="my-3">{{ _("Highest Reviewed") }}</h2>
|
<h2 class="my-3">{{ _("Highest Reviewed") }}</h2>
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
{% for support in package.get_sorted_game_support() %}
|
{% for support in package.get_sorted_game_support() %}
|
||||||
<a class="list-group-item list-group-item-action"
|
<a class="list-group-item list-group-item-action"
|
||||||
href="{{ support.game.getURL('packages.view') }}">
|
href="{{ support.game.get_url('packages.view') }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="col-5">
|
<span class="col-5">
|
||||||
{{ _("%(title)s by %(display_name)s",
|
{{ _("%(title)s by %(display_name)s",
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block headextra %}
|
{% block headextra %}
|
||||||
{% if package.getThumbnailURL(3, True) -%}
|
{% if package.get_thumb_url(3, True) -%}
|
||||||
<meta name="og:image" content="{{ package.getThumbnailURL(3, True) }}"/>
|
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -6,11 +6,11 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-3 mb-4">
|
<div class="col-md-3 mb-4">
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
<a class="list-group-item list-group-item-action" href="{{ package.getURL("packages.view") }}">
|
<a class="list-group-item list-group-item-action" href="{{ package.get_url("packages.view") }}">
|
||||||
<span class="row m-0 p-0">
|
<span class="row m-0 p-0">
|
||||||
<span class="col-auto m-0 p-0">
|
<span class="col-auto m-0 p-0">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1"
|
||||||
src="{{ package.getThumbnailOrPlaceholder(1) }}" alt="{{ _('Thumbnail') }}" style="max-height: 20px;">
|
src="{{ package.get_thumb_or_placeholder(1) }}" alt="{{ _('Thumbnail') }}" style="max-height: 20px;">
|
||||||
</span>
|
</span>
|
||||||
<span class="col m-0 p-0 pl-2">
|
<span class="col m-0 p-0 pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
|
@ -11,13 +11,13 @@
|
|||||||
<form method="POST" action="">
|
<form method="POST" action="">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
{{ render_field(form.title) }}
|
{{ render_field(form.title) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _("Title") }}: {{ release.title }}
|
{{ _("Title") }}: {{ release.title }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if package.checkPerm(current_user, "CHANGE_RELEASE_URL") %}
|
{% if package.check_perm(current_user, "CHANGE_RELEASE_URL") %}
|
||||||
{{ render_field(form.url) }}
|
{{ render_field(form.url) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _("URL") }}: <a href="{{ release.url }}">{{ release.url }}</a><br />
|
{{ _("URL") }}: <a href="{{ release.url }}">{{ release.url }}</a><br />
|
||||||
@ -29,14 +29,14 @@
|
|||||||
|
|
||||||
{% if release.task_id %}
|
{% if release.task_id %}
|
||||||
{{ _("Importing...") }}
|
{{ _("Importing...") }}
|
||||||
<a href="{{ url_for('tasks.check', id=release.task_id, r=release.getEditURL()) }}">{{ _("view task") }}</a><br />
|
<a href="{{ url_for('tasks.check', id=release.task_id, r=release.get_edit_url()) }}">{{ _("view task") }}</a><br />
|
||||||
{% if package.checkPerm(current_user, "CHANGE_RELEASE_URL") %}
|
{% if package.check_perm(current_user, "CHANGE_RELEASE_URL") %}
|
||||||
{{ render_field(form.task_id) }}
|
{{ render_field(form.task_id) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if release.checkPerm(current_user, "APPROVE_RELEASE") %}
|
{% if release.check_perm(current_user, "APPROVE_RELEASE") %}
|
||||||
{{ render_checkbox_field(form.approved, class_="my-3") }}
|
{{ render_checkbox_field(form.approved, class_="my-3") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _("Approved") }}: {{ release.approved }}
|
{{ _("Approved") }}: {{ release.approved }}
|
||||||
@ -69,8 +69,8 @@
|
|||||||
|
|
||||||
<h2 class="mt-5">{{ _("Delete Release") }}</h2>
|
<h2 class="mt-5">{{ _("Delete Release") }}</h2>
|
||||||
|
|
||||||
{% if release.checkPerm(current_user, "DELETE_RELEASE") %}
|
{% if release.check_perm(current_user, "DELETE_RELEASE") %}
|
||||||
<form method="POST" action="{{ release.getDeleteURL() }}" class="alert alert-secondary mb-5">
|
<form method="POST" action="{{ release.get_delete_url() }}" class="alert alert-secondary mb-5">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<input class="btn btn-sm btn-danger float-right" type="submit" value="{{ _('Delete') }}">
|
<input class="btn btn-sm btn-danger float-right" type="submit" value="{{ _('Delete') }}">
|
||||||
<b>{{ _("This is permanent.") }}</b>
|
<b>{{ _("This is permanent.") }}</b>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
{% if package.update_config %}
|
{% if package.update_config %}
|
||||||
<p class="alert alert-secondary mb-4">
|
<p class="alert alert-secondary mb-4">
|
||||||
<a class="float-right btn btn-sm btn-secondary" href="{{ package.getURL("packages.update_config") }}">{{ _("Settings") }}</a>
|
<a class="float-right btn btn-sm btn-secondary" href="{{ package.get_url("packages.update_config") }}">{{ _("Settings") }}</a>
|
||||||
{% if package.update_config.make_release %}
|
{% if package.update_config.make_release %}
|
||||||
{{ _("You have automatic releases enabled.") }}
|
{{ _("You have automatic releases enabled.") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -20,12 +20,12 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<p class="alert alert-info mb-4">
|
<p class="alert alert-info mb-4">
|
||||||
{% if package.repo %}
|
{% if package.repo %}
|
||||||
<a class="float-right btn btn-sm btn-info" href="{{ package.getURL("packages.setup_releases") }}">{{ _("Set up") }}</a>
|
<a class="float-right btn btn-sm btn-info" href="{{ package.get_url("packages.setup_releases") }}">{{ _("Set up") }}</a>
|
||||||
<i class="fas fa-info mr-2"></i>
|
<i class="fas fa-info mr-2"></i>
|
||||||
|
|
||||||
{{ _("You can create releases automatically when you push commits or tags to your repository.") }}
|
{{ _("You can create releases automatically when you push commits or tags to your repository.") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="float-right btn btn-sm btn-info" href="{{ package.getURL("packages.create_edit") }}">{{ _("Add Git repo") }}</a>
|
<a class="float-right btn btn-sm btn-info" href="{{ package.get_url("packages.create_edit") }}">{{ _("Add Git repo") }}</a>
|
||||||
<i class="fas fa-info mr-2"></i>
|
<i class="fas fa-info mr-2"></i>
|
||||||
|
|
||||||
{{ _("Using Git would allow you to create releases automatically when you push code or tags.") }}
|
{{ _("Using Git would allow you to create releases automatically when you push code or tags.") }}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<a class="btn btn-secondary float-right" href="{{ package.getURL("packages.view") }}">
|
<a class="btn btn-secondary float-right" href="{{ package.get_url("packages.view") }}">
|
||||||
{{ _("Later") }}
|
{{ _("Later") }}
|
||||||
</a>
|
</a>
|
||||||
<h1>{{ self.title() }}</h1>
|
<h1>{{ self.title() }}</h1>
|
||||||
@ -30,13 +30,13 @@
|
|||||||
<div class="col-md-6 mt-5">
|
<div class="col-md-6 mt-5">
|
||||||
<h3 class="mt-0">{{ _("Automatically (Recommended)") }}</h3>
|
<h3 class="mt-0">{{ _("Automatically (Recommended)") }}</h3>
|
||||||
<p>
|
<p>
|
||||||
<a class="btn btn-primary" href="{{ package.getURL("packages.update_config", trigger="commit") }}">
|
<a class="btn btn-primary" href="{{ package.get_url("packages.update_config", trigger="commit") }}">
|
||||||
{{ _("Rolling Release") }}
|
{{ _("Rolling Release") }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-primary ml-2" href="{{ package.getURL("packages.update_config", trigger="tag") }}">
|
<a class="btn btn-primary ml-2" href="{{ package.get_url("packages.update_config", trigger="tag") }}">
|
||||||
{{ _("On Git Tag") }}
|
{{ _("On Git Tag") }}
|
||||||
</a>
|
</a>
|
||||||
{# <a class="btn btn-secondary ml-2" href="{{ package.getURL("packages.update_config") }}">#}
|
{# <a class="btn btn-secondary ml-2" href="{{ package.get_url("packages.update_config") }}">#}
|
||||||
{# {{ _("Advanced") }}#}
|
{# {{ _("Advanced") }}#}
|
||||||
{# </a>#}
|
{# </a>#}
|
||||||
</p>
|
</p>
|
||||||
@ -45,10 +45,10 @@
|
|||||||
<div class="col-md-6 mt-5">
|
<div class="col-md-6 mt-5">
|
||||||
<h3 class="mt-0">{{ _("Manually") }}</h3>
|
<h3 class="mt-0">{{ _("Manually") }}</h3>
|
||||||
<p>
|
<p>
|
||||||
<a class="btn btn-secondary" href="{{ package.getURL("packages.update_config", action="notification") }}">
|
<a class="btn btn-secondary" href="{{ package.get_url("packages.update_config", action="notification") }}">
|
||||||
{{ _("With reminders") }}
|
{{ _("With reminders") }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-secondary ml-2" href="{{ package.getURL("packages.create_release") }}">
|
<a class="btn btn-secondary ml-2" href="{{ package.get_url("packages.create_release") }}">
|
||||||
{{ _("No reminders") }}
|
{{ _("No reminders") }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@ -65,13 +65,13 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="mt-5">
|
<p class="mt-5">
|
||||||
<a class="btn btn-primary" href="{{ package.getURL("packages.create_edit") }}">
|
<a class="btn btn-primary" href="{{ package.get_url("packages.create_edit") }}">
|
||||||
{{ _("Add Git repo") }}
|
{{ _("Add Git repo") }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-secondary ml-2" href="{{ package.getURL("packages.create_release") }}">
|
<a class="btn btn-secondary ml-2" href="{{ package.get_url("packages.create_release") }}">
|
||||||
{{ _("Create releases manually") }}
|
{{ _("Create releases manually") }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-secondary ml-2" href="{{ package.getURL("packages.view") }}">
|
<a class="btn btn-secondary ml-2" href="{{ package.get_url("packages.view") }}">
|
||||||
{{ _("Later") }}
|
{{ _("Later") }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -5,26 +5,26 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
<p class="float-right">
|
<p class="float-right">
|
||||||
{% if package.update_config %}
|
{% if package.update_config %}
|
||||||
<a class="btn btn-secondary" href="{{ package.getURL("packages.update_config") }}">
|
<a class="btn btn-secondary" href="{{ package.get_url("packages.update_config") }}">
|
||||||
<i class="fas fa-cog mr-1"></i>
|
<i class="fas fa-cog mr-1"></i>
|
||||||
{{ _("Update settings") }}
|
{{ _("Update settings") }}
|
||||||
</a>
|
</a>
|
||||||
{% elif package.repo %}
|
{% elif package.repo %}
|
||||||
<a class="btn btn-secondary" href="{{ package.getURL("packages.setup_releases") }}">
|
<a class="btn btn-secondary" href="{{ package.get_url("packages.setup_releases") }}">
|
||||||
<i class="fas fa-hat-wizard mr-1"></i>
|
<i class="fas fa-hat-wizard mr-1"></i>
|
||||||
{{ _("Set up automatic releases") }}
|
{{ _("Set up automatic releases") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<a class="btn btn-secondary ml-1" href="{{ package.getURL("packages.bulk_change_release") }}">
|
<a class="btn btn-secondary ml-1" href="{{ package.get_url("packages.bulk_change_release") }}">
|
||||||
<i class="fas fa-wrench mr-1"></i>
|
<i class="fas fa-wrench mr-1"></i>
|
||||||
{{ _("Bulk update") }}
|
{{ _("Bulk update") }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a class="btn btn-primary ml-1" href="{{ package.getURL("packages.create_release") }}">
|
<a class="btn btn-primary ml-1" href="{{ package.get_url("packages.create_release") }}">
|
||||||
<i class="fas fa-plus mr-1"></i>
|
<i class="fas fa-plus mr-1"></i>
|
||||||
{{ _("Create") }}
|
{{ _("Create") }}
|
||||||
</a>
|
</a>
|
||||||
@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% from "macros/releases.html" import render_releases_edit, render_releases_download %}
|
{% from "macros/releases.html" import render_releases_edit, render_releases_download %}
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
{{ render_releases_edit(package.releases, package) }}
|
{{ render_releases_edit(package.releases, package) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ render_releases_download(package.releases, package, current_user) }}
|
{{ render_releases_download(package.releases, package, current_user) }}
|
||||||
|
@ -31,7 +31,7 @@ Remove {{ package.title }}
|
|||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="btn btn-secondary float-right" href="{{ package.getURL("packages.view") }}">{{ _("Cancel") }}</a>
|
<a class="btn btn-secondary float-right" href="{{ package.get_url("packages.view") }}">{{ _("Cancel") }}</a>
|
||||||
|
|
||||||
<input type="submit" name="delete" value="{{ _('Remove') }}" class="btn btn-danger mr-2" />
|
<input type="submit" name="delete" value="{{ _('Remove') }}" class="btn btn-danger mr-2" />
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block link %}
|
{% block link %}
|
||||||
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
|
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@ -22,7 +22,7 @@
|
|||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
<div class="row mt-0 mb-4 comments mx-0">
|
<div class="row mt-0 mb-4 comments mx-0">
|
||||||
<div class="col-md-1 p-1">
|
<div class="col-md-1 p-1">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ current_user.getProfilePicURL() }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ current_user.get_profile_pic_url() }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@ -50,7 +50,7 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if review %}
|
{% if review %}
|
||||||
<form method="POST" action="{{ review.getDeleteURL() }}" class="alert alert-secondary my-5">
|
<form method="POST" action="{{ review.get_delete_url() }}" class="alert alert-secondary my-5">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<input class="btn btn-sm btn-danger float-right" type="submit" value="{{ _('Delete') }}">
|
<input class="btn btn-sm btn-danger float-right" type="submit" value="{{ _('Delete') }}">
|
||||||
<b>{{ _("Delete review.") }}</b>
|
<b>{{ _("Delete review.") }}</b>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block link %}
|
{% block link %}
|
||||||
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
|
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
@ -61,7 +61,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<i class="fas fa-minus mr-2"></i>
|
<i class="fas fa-minus mr-2"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ review.thread.getViewURL() }}">
|
<a href="{{ review.thread.get_view_url() }}">
|
||||||
{{ review.thread.title }}
|
{{ review.thread.title }}
|
||||||
</a> by {{ review.author.display_name }}
|
</a> by {{ review.author.display_name }}
|
||||||
</th>
|
</th>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
{{ render_field(form.title) }}
|
{{ render_field(form.title) }}
|
||||||
|
|
||||||
{% if package.checkPerm(current_user, "APPROVE_SCREENSHOT") %}
|
{% if package.check_perm(current_user, "APPROVE_SCREENSHOT") %}
|
||||||
{{ render_checkbox_field(form.approved) }}
|
{{ render_checkbox_field(form.approved) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<p>{{ _("Approved") }}: {{ screenshot.approved }}</p>
|
<p>{{ _("Approved") }}: {{ screenshot.approved }}</p>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
</form>
|
</form>
|
||||||
|
|
||||||
<a href="{{ screenshot.url }}" class="col-md-4 text-right">
|
<a href="{{ screenshot.url }}" class="col-md-4 text-right">
|
||||||
<img src="{{ screenshot.getThumbnailURL() }}" alt="{{ screenshot.title }}" />
|
<img src="{{ screenshot.get_thumb_url() }}" alt="{{ screenshot.title }}" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
|
{% if package.check_perm(current_user, "ADD_SCREENSHOTS") %}
|
||||||
<a href="{{ package.getURL('packages.create_screenshot') }}" class="btn btn-primary float-right">
|
<a href="{{ package.get_url('packages.create_screenshot') }}" class="btn btn-primary float-right">
|
||||||
<i class="fas fa-plus mr-1"></i>
|
<i class="fas fa-plus mr-1"></i>
|
||||||
{{ _("Add Image") }}
|
{{ _("Add Image") }}
|
||||||
</a>
|
</a>
|
||||||
@ -16,14 +16,14 @@
|
|||||||
<ul class="list-group sortable">
|
<ul class="list-group sortable">
|
||||||
{% set screenshots = package.screenshots.all() %}
|
{% set screenshots = package.screenshots.all() %}
|
||||||
{% for ss in screenshots %}
|
{% for ss in screenshots %}
|
||||||
{% if ss.approved or package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
|
{% if ss.approved or package.check_perm(current_user, "ADD_SCREENSHOTS") %}
|
||||||
<li class="list-group-item" data-id="{{ ss.id }}">
|
<li class="list-group-item" data-id="{{ ss.id }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto text-muted pr-2">
|
<div class="col-auto text-muted pr-2">
|
||||||
<i class="fas fa-bars"></i>
|
<i class="fas fa-bars"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<img class="img-fluid" style="max-height: 64px;" src="{{ ss.getThumbnailURL() }}" />
|
<img class="img-fluid" style="max-height: 64px;" src="{{ ss.get_thumb_url() }}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{{ ss.title }}
|
{{ ss.title }}
|
||||||
@ -52,9 +52,9 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ ss.getDeleteURL() }}" method="POST" class="col-auto text-right" role="form">
|
<form action="{{ ss.get_delete_url() }}" method="POST" class="col-auto text-right" role="form">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<a class="btn btn-sm btn-primary" href="{{ ss.getEditURL() }}">
|
<a class="btn btn-sm btn-primary" href="{{ ss.get_edit_url() }}">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
</a>
|
</a>
|
||||||
<button type="submit" class="btn btn-sm btn-danger ml-2">
|
<button type="submit" class="btn btn-sm btn-danger ml-2">
|
||||||
@ -90,7 +90,7 @@
|
|||||||
{{ _("The first screenshot in the list above will be the package thumbnail.") }}
|
{{ _("The first screenshot in the list above will be the package thumbnail.") }}
|
||||||
</p>
|
</p>
|
||||||
<div class="client-preview d-flex flex-row align-items-center">
|
<div class="client-preview d-flex flex-row align-items-center">
|
||||||
<img class="mt-thumb" src="{{ package.getThumbnailOrPlaceholder(1) }}" alt="{{ _('Thumbnail') }}">
|
<img class="mt-thumb" src="{{ package.get_thumb_or_placeholder(1) }}" alt="{{ _('Thumbnail') }}">
|
||||||
<div class="flex-grow desc align-self-stretch">
|
<div class="flex-grow desc align-self-stretch">
|
||||||
<p>
|
<p>
|
||||||
<span class="title">{{ package.title }}</span> by {{ package.author.username }}
|
<span class="title">{{ package.title }}</span> by {{ package.author.username }}
|
||||||
|
@ -13,23 +13,23 @@
|
|||||||
{{ _("Review link") }}:
|
{{ _("Review link") }}:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre><code>{{ package.getURL("packages.review", absolute=True) }}</code></pre>
|
<pre><code>{{ package.get_url("packages.review", absolute=True) }}</code></pre>
|
||||||
|
|
||||||
<h3>{{ _("Badges") }}</h3>
|
<h3>{{ _("Badges") }}</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{{ package.makeShield("title") | markdown }}
|
{{ package.make_shield("title") | markdown }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<pre><code>{{ package.makeShield("title") }}</code></pre>
|
<pre><code>{{ package.make_shield("title") }}</code></pre>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{{ package.makeShield("downloads") | markdown }}
|
{{ package.make_shield("downloads") | markdown }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<pre><code>{{ package.makeShield("downloads") }}</code></pre>
|
<pre><code>{{ package.make_shield("downloads") }}</code></pre>
|
||||||
</p>
|
</p>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1><a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a></h1>
|
<h1><a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a></h1>
|
||||||
<h2>{{ self.title() }}</h2>
|
<h2>{{ self.title() }}</h2>
|
||||||
|
|
||||||
{% if packages_modnames %}
|
{% if packages_modnames %}
|
||||||
@ -18,7 +18,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
{% for pkg in packages %}
|
{% for pkg in packages %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ pkg.getURL('packages.view') }}">
|
<a href="{{ pkg.get_url('packages.view') }}">
|
||||||
{{ _("%(title)s by %(author)s", title=pkg.title, author=pkg.author.display_name) }}
|
{{ _("%(title)s by %(author)s", title=pkg.title, author=pkg.author.display_name) }}
|
||||||
</a>
|
</a>
|
||||||
[{{ pkg.type.text }}]
|
[{{ pkg.type.text }}]
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="float-right">
|
<div class="float-right">
|
||||||
<a class="btn btn-secondary mr-2" href="{{ package.getURL('packages.stats_csv') }}">
|
<a class="btn btn-secondary mr-2" href="{{ package.get_url('packages.stats_csv') }}">
|
||||||
<i class="fas fa-download mr-1"></i>
|
<i class="fas fa-download mr-1"></i>
|
||||||
{{ _("Download (.csv)") }}
|
{{ _("Download (.csv)") }}
|
||||||
</a>
|
</a>
|
||||||
@ -21,5 +21,5 @@
|
|||||||
{{ render_package_selector(package.author, package=package) }}
|
{{ render_package_selector(package.author, package=package) }}
|
||||||
</div>
|
</div>
|
||||||
<h2 class="mt-0">{{ _("Statistics") }}</h2>
|
<h2 class="mt-0">{{ _("Statistics") }}</h2>
|
||||||
{{ render_package_stats(package.getURL('api.package_stats', start=start, end=end), package.downloads, start or end) }}
|
{{ render_package_stats(package.get_url('api.package_stats', start=start, end=end), package.downloads, start or end) }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{% set query=package.name %}
|
{% set query=package.name %}
|
||||||
{% set release = package.getDownloadRelease() %}
|
{% set release = package.get_download_release() %}
|
||||||
|
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
@ -12,8 +12,8 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block headextra %}
|
{% block headextra %}
|
||||||
{% if package.getThumbnailURL(3, True) -%}
|
{% if package.get_thumb_url(3, True) -%}
|
||||||
<meta name="og:image" content="{{ package.getThumbnailURL(3, True) }}"/>
|
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -31,8 +31,8 @@
|
|||||||
|
|
||||||
{% block download_btn %}
|
{% block download_btn %}
|
||||||
{% if release %}
|
{% if release %}
|
||||||
<a class="btn btn-block btn-download" rel="nofollow" download="{{ release.getDownloadFileName() }}"
|
<a class="btn btn-block btn-download" rel="nofollow" download="{{ release.get_download_filename() }}"
|
||||||
href="{{ release.getDownloadURL() }}">
|
href="{{ release.get_download_url() }}">
|
||||||
<div>
|
<div>
|
||||||
{{ _("Download") }}
|
{{ _("Download") }}
|
||||||
</div>
|
</div>
|
||||||
@ -90,7 +90,7 @@
|
|||||||
{% from "macros/package_approval.html" import render_banners %}
|
{% from "macros/package_approval.html" import render_banners %}
|
||||||
{{ render_banners(package, current_user, topic_error, topic_error_lvl, conflicting_modnames) }}
|
{{ render_banners(package, current_user, topic_error, topic_error_lvl, conflicting_modnames) }}
|
||||||
|
|
||||||
{% if review_thread and review_thread.checkPerm(current_user, "SEE_THREAD") %}
|
{% if review_thread and review_thread.check_perm(current_user, "SEE_THREAD") %}
|
||||||
<h2>{% if review_thread.private %}🔒{% endif %} {{ review_thread.title }}</h2>
|
<h2>{% if review_thread.private %}🔒{% endif %} {{ review_thread.title }}</h2>
|
||||||
{% if review_thread.private %}
|
{% if review_thread.private %}
|
||||||
<p><i>
|
<p><i>
|
||||||
@ -105,7 +105,7 @@
|
|||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% set cover_image = package.getCoverImageURL() %}
|
{% set cover_image = package.get_cover_image_url() %}
|
||||||
<header class="jumbotron pb-3"
|
<header class="jumbotron pb-3"
|
||||||
style="background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.7)), url('{{ cover_image }}');
|
style="background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.7)), url('{{ cover_image }}');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
@ -113,20 +113,20 @@
|
|||||||
background-position: center;">
|
background-position: center;">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="btn-group float-right mb-4">
|
<div class="btn-group float-right mb-4">
|
||||||
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
|
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
|
||||||
<a class="btn btn-primary" href="{{ package.getURL('packages.create_edit') }}">
|
<a class="btn btn-primary" href="{{ package.get_url('packages.create_edit') }}">
|
||||||
<i class="fas fa-pen mr-1"></i>
|
<i class="fas fa-pen mr-1"></i>
|
||||||
{{ _("Edit") }}
|
{{ _("Edit") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
<a class="btn btn-primary" href="{{ package.getURL('packages.create_release') }}">
|
<a class="btn btn-primary" href="{{ package.get_url('packages.create_release') }}">
|
||||||
<i class="fas fa-plus mr-1"></i>
|
<i class="fas fa-plus mr-1"></i>
|
||||||
{{ _("Release") }}
|
{{ _("Release") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if package.checkPerm(current_user, "DELETE_PACKAGE") or package.checkPerm(current_user, "UNAPPROVE_PACKAGE") %}
|
{% if package.check_perm(current_user, "DELETE_PACKAGE") or package.check_perm(current_user, "UNAPPROVE_PACKAGE") %}
|
||||||
<a class="btn btn-danger" href="{{ package.getURL('packages.remove') }}">
|
<a class="btn btn-danger" href="{{ package.get_url('packages.remove') }}">
|
||||||
<i class="fas fa-trash mr-1"></i>
|
<i class="fas fa-trash mr-1"></i>
|
||||||
{{ _("Remove") }}
|
{{ _("Remove") }}
|
||||||
</a>
|
</a>
|
||||||
@ -179,14 +179,14 @@
|
|||||||
<div class="info-row row" style="margin-top: 2rem;">
|
<div class="info-row row" style="margin-top: 2rem;">
|
||||||
<div class="btn-group-horizontal col">
|
<div class="btn-group-horizontal col">
|
||||||
<a class="btn" href="{{ url_for('users.profile', username=package.author.username) }}" title="{{ _("Author") }}">
|
<a class="btn" href="{{ url_for('users.profile', username=package.author.username) }}" title="{{ _("Author") }}">
|
||||||
<img src="{{ package.author.getProfilePicURL() }}" style="max-height: 1em; filter: none">
|
<img src="{{ package.author.get_profile_pic_url() }}" style="max-height: 1em; filter: none">
|
||||||
<span class="count">
|
<span class="count">
|
||||||
{{ package.author.display_name }}
|
{{ package.author.display_name }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
{% if release %}
|
{% if release %}
|
||||||
<a class="btn" rel="nofollow" href="{{ release.getDownloadURL() }}" title="{{ _('Downloads') }}"
|
<a class="btn" rel="nofollow" href="{{ release.get_download_url() }}" title="{{ _('Downloads') }}"
|
||||||
download="{{ release.getDownloadFileName() }}">
|
download="{{ release.get_download_filename() }}">
|
||||||
<i class="fas fa-download"></i>
|
<i class="fas fa-download"></i>
|
||||||
<span class="count">{{ package.downloads }}</span>
|
<span class="count">{{ package.downloads }}</span>
|
||||||
</a>
|
</a>
|
||||||
@ -229,7 +229,7 @@
|
|||||||
<span class="count">{{ _("Issue Tracker") }}</span>
|
<span class="count">{{ _("Issue Tracker") }}</span>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="btn" href="{{ package.getURL('packages.statistics') }}">
|
<a class="btn" href="{{ package.get_url('packages.statistics') }}">
|
||||||
<i class="fas fa-chart-line"></i>
|
<i class="fas fa-chart-line"></i>
|
||||||
<span class="count">{{ _("Statistics") }}</span>
|
<span class="count">{{ _("Statistics") }}</span>
|
||||||
</a>
|
</a>
|
||||||
@ -247,14 +247,14 @@
|
|||||||
<div class="col-md-9" style="padding-right: 45px;">
|
<div class="col-md-9" style="padding-right: 45px;">
|
||||||
{% set screenshots = package.screenshots.all() %}
|
{% set screenshots = package.screenshots.all() %}
|
||||||
|
|
||||||
{% if package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
|
{% if package.check_perm(current_user, "ADD_SCREENSHOTS") %}
|
||||||
<a href="{{ package.getURL('packages.screenshots') }}" class="btn btn-primary float-right">
|
<a href="{{ package.get_url('packages.screenshots') }}" class="btn btn-primary float-right">
|
||||||
<i class="fas fa-images mr-1"></i>
|
<i class="fas fa-images mr-1"></i>
|
||||||
{{ _("Edit") }}
|
{{ _("Edit") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if screenshots or package.checkPerm(current_user, "ADD_SCREENSHOTS") or package.video_url %}
|
{% if screenshots or package.check_perm(current_user, "ADD_SCREENSHOTS") or package.video_url %}
|
||||||
<ul class="gallery">
|
<ul class="gallery">
|
||||||
{% if package.video_url %}
|
{% if package.video_url %}
|
||||||
<li>
|
<li>
|
||||||
@ -267,12 +267,12 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if screenshots or package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
|
{% if screenshots or package.check_perm(current_user, "ADD_SCREENSHOTS") %}
|
||||||
{% for ss in screenshots %}
|
{% for ss in screenshots %}
|
||||||
{% if ss.approved or package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
|
{% if ss.approved or package.check_perm(current_user, "ADD_SCREENSHOTS") %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ ss.url }}" class="gallery-image">
|
<a href="{{ ss.url }}" class="gallery-image">
|
||||||
<img src="{{ ss.getThumbnailURL() }}" alt="{{ ss.title }}" title="{{ ss.title }}" />
|
<img src="{{ ss.get_thumb_url() }}" alt="{{ ss.title }}" title="{{ ss.title }}" />
|
||||||
{% if not ss.approved %}
|
{% if not ss.approved %}
|
||||||
<span class="badge bg-dark badge-tr">{{ _("Awaiting review") }}</span>
|
<span class="badge bg-dark badge-tr">{{ _("Awaiting review") }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -281,7 +281,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ package.getURL('packages.create_screenshot') }}">
|
<a href="{{ package.get_url('packages.create_screenshot') }}">
|
||||||
<i class="fas fa-plus screenshot-add"></i>
|
<i class="fas fa-plus screenshot-add"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -303,7 +303,7 @@
|
|||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
{% if has_review %}
|
{% if has_review %}
|
||||||
<p>
|
<p>
|
||||||
<a class="btn btn-primary" href="{{ package.getURL("packages.review") }}">
|
<a class="btn btn-primary" href="{{ package.get_url("packages.review") }}">
|
||||||
{{ _("Edit Review") }}
|
{{ _("Edit Review") }}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
@ -324,7 +324,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.ADMIN) %}
|
{% if current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.ADMIN) %}
|
||||||
<a href="{{ package.getURL('packages.review_votes') }}" class="btn btn-secondary">{{ _("Review Votes") }}</a>
|
<a href="{{ package.get_url('packages.review_votes') }}" class="btn btn-secondary">{{ _("Review Votes") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ render_reviews(package.reviews, current_user) }}
|
{{ render_reviews(package.reviews, current_user) }}
|
||||||
@ -337,7 +337,7 @@
|
|||||||
|
|
||||||
{% if package.type == package.type.GAME %}
|
{% if package.type == package.type.GAME %}
|
||||||
<h2>{{ _("Content") }}</h2>
|
<h2>{{ _("Content") }}</h2>
|
||||||
<a href="{{ package.getURL('packages.game_hub') }}" class="btn btn-lg btn-primary">
|
<a href="{{ package.get_url('packages.game_hub') }}" class="btn btn-lg btn-primary">
|
||||||
{{ _("View content for game") }}
|
{{ _("View content for game") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -348,7 +348,7 @@
|
|||||||
{{ self.download_btn() }}
|
{{ self.download_btn() }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") and package.update_config and package.update_config.outdated_at %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") and package.update_config and package.update_config.outdated_at %}
|
||||||
{% set config = package.update_config %}
|
{% set config = package.update_config %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
<p class="mt-0 my-1">
|
<p class="mt-0 my-1">
|
||||||
@ -366,7 +366,7 @@
|
|||||||
<i class="fas fa-plus mr-1"></i>
|
<i class="fas fa-plus mr-1"></i>
|
||||||
{{ _("Release") }}
|
{{ _("Release") }}
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-warning" href="{{ package.getURL("packages.update_config") }}">
|
<a class="btn btn-warning" href="{{ package.get_url("packages.update_config") }}">
|
||||||
<i class="fas fa-cog mr-1"></i>
|
<i class="fas fa-cog mr-1"></i>
|
||||||
{{ _("Update settings") }}
|
{{ _("Update settings") }}
|
||||||
</a>
|
</a>
|
||||||
@ -391,7 +391,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if package.type == package.type.GAME %}
|
{% if package.type == package.type.GAME %}
|
||||||
<a href="{{ package.getURL('packages.game_hub') }}" class="btn btn-lg btn-block mb-4 btn-primary">
|
<a href="{{ package.get_url('packages.game_hub') }}" class="btn btn-lg btn-block mb-4 btn-primary">
|
||||||
{{ _("View content for game") }}
|
{{ _("View content for game") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -401,10 +401,10 @@
|
|||||||
<dl>
|
<dl>
|
||||||
<dt>{{ _("Required") }}</dt>
|
<dt>{{ _("Required") }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{% for dep in package.getSortedHardDependencies() %}
|
{% for dep in package.get_sorted_hard_dependencies() %}
|
||||||
{%- if dep.package %}
|
{%- if dep.package %}
|
||||||
<a class="badge badge-primary"
|
<a class="badge badge-primary"
|
||||||
href="{{ dep.package.getURL("packages.view") }}">
|
href="{{ dep.package.get_url("packages.view") }}">
|
||||||
{{ _("%(title)s by %(display_name)s",
|
{{ _("%(title)s by %(display_name)s",
|
||||||
title=dep.package.title, display_name=dep.package.author.display_name) }}
|
title=dep.package.title, display_name=dep.package.author.display_name) }}
|
||||||
</a>
|
</a>
|
||||||
@ -421,14 +421,14 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
{% set optional_deps=package.getSortedOptionalDependencies() %}
|
{% set optional_deps=package.get_sorted_optional_dependencies() %}
|
||||||
{% if optional_deps %}
|
{% if optional_deps %}
|
||||||
<dt>{{ _("Optional") }}</dt>
|
<dt>{{ _("Optional") }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{% for dep in optional_deps %}
|
{% for dep in optional_deps %}
|
||||||
{%- if dep.package %}
|
{%- if dep.package %}
|
||||||
<a class="badge badge-secondary"
|
<a class="badge badge-secondary"
|
||||||
href="{{ dep.package.getURL("packages.view") }}">
|
href="{{ dep.package.get_url("packages.view") }}">
|
||||||
{{ _("%(title)s by %(display_name)s",
|
{{ _("%(title)s by %(display_name)s",
|
||||||
title=dep.package.title, display_name=dep.package.author.display_name) }}
|
title=dep.package.title, display_name=dep.package.author.display_name) }}
|
||||||
{% elif dep.meta_package %}
|
{% elif dep.meta_package %}
|
||||||
@ -451,8 +451,8 @@
|
|||||||
{% set show_unsupported = package.supports_all_games or supported_games == [] %}
|
{% set show_unsupported = package.supports_all_games or supported_games == [] %}
|
||||||
{% if supported_games or unsupported_games or package.type == package.type.MOD %}
|
{% if supported_games or unsupported_games or package.type == package.type.MOD %}
|
||||||
<h3>
|
<h3>
|
||||||
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
|
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
|
||||||
<a href="{{ package.getURL('packages.game_support') }}" class="btn btn-secondary btn-sm float-right">
|
<a href="{{ package.get_url('packages.game_support') }}" class="btn btn-secondary btn-sm float-right">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -473,7 +473,7 @@
|
|||||||
<div style="max-height: 300px; overflow: hidden auto;" class="mb-3">
|
<div style="max-height: 300px; overflow: hidden auto;" class="mb-3">
|
||||||
{% for support in supported_games %}
|
{% for support in supported_games %}
|
||||||
<a class="badge badge-secondary"
|
<a class="badge badge-secondary"
|
||||||
href="{{ support.game.getURL('packages.view') }}">
|
href="{{ support.game.get_url('packages.view') }}">
|
||||||
{{ _("%(title)s by %(display_name)s",
|
{{ _("%(title)s by %(display_name)s",
|
||||||
title=support.game.title, display_name=support.game.author.display_name) }}
|
title=support.game.title, display_name=support.game.author.display_name) }}
|
||||||
</a>
|
</a>
|
||||||
@ -483,14 +483,14 @@
|
|||||||
<p>
|
<p>
|
||||||
{{ _("No specific game required") }}
|
{{ _("No specific game required") }}
|
||||||
</p>
|
</p>
|
||||||
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
|
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
<p>
|
<p>
|
||||||
{{ _("Is the above correct?") }}
|
{{ _("Is the above correct?") }}
|
||||||
{{ _("You need to either confirm this or tell ContentDB about supported games") }}
|
{{ _("You need to either confirm this or tell ContentDB about supported games") }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<a class="btn btn-sm btn-warning" href="{{ package.getURL('packages.game_support') }}">
|
<a class="btn btn-sm btn-warning" href="{{ package.get_url('packages.game_support') }}">
|
||||||
Update
|
Update
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -504,7 +504,7 @@
|
|||||||
<div style="max-height: 300px; overflow: hidden auto;">
|
<div style="max-height: 300px; overflow: hidden auto;">
|
||||||
{% for support in unsupported_games %}
|
{% for support in unsupported_games %}
|
||||||
<a class="badge badge-danger"
|
<a class="badge badge-danger"
|
||||||
href="{{ support.game.getURL('packages.view') }}">
|
href="{{ support.game.get_url('packages.view') }}">
|
||||||
<i class="fas fa-times mr-1"></i>
|
<i class="fas fa-times mr-1"></i>
|
||||||
{{ _("%(title)s by %(display_name)s",
|
{{ _("%(title)s by %(display_name)s",
|
||||||
title=support.game.title, display_name=support.game.author.display_name) }}
|
title=support.game.title, display_name=support.game.author.display_name) }}
|
||||||
@ -520,10 +520,10 @@
|
|||||||
{{ _("Supported games are determined by an algorithm, and may not be correct.") }}
|
{{ _("Supported games are determined by an algorithm, and may not be correct.") }}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif package.checkPerm(current_user, "EDIT_PACKAGE") %}
|
{% elif package.check_perm(current_user, "EDIT_PACKAGE") %}
|
||||||
<p class="alert alert-warning">
|
<p class="alert alert-warning">
|
||||||
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
|
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
|
||||||
<a href="{{ package.getURL('packages.game_support') }}" class="btn btn-warning btn-sm float-right">
|
<a href="{{ package.get_url('packages.game_support') }}" class="btn btn-warning btn-sm float-right">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -570,7 +570,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if current_user in package.maintainers and current_user != package.author %}
|
{% if current_user in package.maintainers and current_user != package.author %}
|
||||||
<form class="mt-2" method="post" action="{{ package.getURL("packages.remove_self_maintainers") }}">
|
<form class="mt-2" method="post" action="{{ package.get_url("packages.remove_self_maintainers") }}">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<input class="btn btn-sm btn-link p-0" type="submit" value="{{ _('Remove myself') }}" />
|
<input class="btn btn-sm btn-link p-0" type="submit" value="{{ _('Remove myself') }}" />
|
||||||
</form>
|
</form>
|
||||||
@ -586,25 +586,25 @@
|
|||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<h3>
|
<h3>
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
<a class="btn btn-primary btn-sm float-right" href="{{ package.getURL("packages.create_release") }}"><i class="fas fa-plus"></i></a>
|
<a class="btn btn-primary btn-sm float-right" href="{{ package.get_url("packages.create_release") }}"><i class="fas fa-plus"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ _("Releases") }}
|
{{ _("Releases") }}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% from "macros/releases.html" import render_releases, render_releases_download %}
|
{% from "macros/releases.html" import render_releases, render_releases_download %}
|
||||||
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
{{ render_releases(releases, package, current_user) }}
|
{{ render_releases(releases, package, current_user) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ render_releases_download(releases, package, current_user) }}
|
{{ render_releases_download(releases, package, current_user) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="list-group-item list-group-item-action text-center py-1 text-muted" href="{{ package.getURL("packages.list_releases") }}">
|
<a class="list-group-item list-group-item-action text-center py-1 text-muted" href="{{ package.get_url("packages.list_releases") }}">
|
||||||
{{ _("More") }}
|
{{ _("More") }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3>
|
<h3>
|
||||||
{% if package.approved and package.checkPerm(current_user, "CREATE_THREAD") %}
|
{% if package.approved and package.check_perm(current_user, "CREATE_THREAD") %}
|
||||||
<div class="btn-group float-right">
|
<div class="btn-group float-right">
|
||||||
<a class="btn btn-primary btn-sm mx-1" href="{{ url_for('threads.new', pid=package.id) }}"><i class="fas fa-plus"></i></a>
|
<a class="btn btn-primary btn-sm mx-1" href="{{ url_for('threads.new', pid=package.id) }}"><i class="fas fa-plus"></i></a>
|
||||||
</div>
|
</div>
|
||||||
@ -623,11 +623,11 @@
|
|||||||
{{ _("Report") }}
|
{{ _("Report") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if package.checkPerm(current_user, "EDIT_PACKAGE") or package.checkPerm(current_user, "APPROVE_NEW") %}
|
{% if package.check_perm(current_user, "EDIT_PACKAGE") or package.check_perm(current_user, "APPROVE_NEW") %}
|
||||||
{% if package.approved and current_user != package.author %}
|
{% if package.approved and current_user != package.author %}
|
||||||
|
|
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ package.getURL('packages.audit') }}">
|
<a href="{{ package.get_url('packages.audit') }}">
|
||||||
{{ _("See audit log") }}
|
{{ _("See audit log") }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>{{ _("Deleting is permanent") }}</p>
|
<p>{{ _("Deleting is permanent") }}</p>
|
||||||
|
|
||||||
<a class="btn btn-secondary mr-3" href="{{ thread.getViewURL() }}">{{ _("Cancel") }}</a>
|
<a class="btn btn-secondary mr-3" href="{{ thread.get_view_url() }}">{{ _("Cancel") }}</a>
|
||||||
<input type="submit" value="{{ _('Delete') }}" class="btn btn-danger" />
|
<input type="submit" value="{{ _('Delete') }}" class="btn btn-danger" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p>{{ _("Deleting is permanent") }}</p>
|
<p>{{ _("Deleting is permanent") }}</p>
|
||||||
|
|
||||||
<a class="btn btn-secondary mr-3" href="{{ thread.getViewURL() }}">{{ _("Cancel") }}</a>
|
<a class="btn btn-secondary mr-3" href="{{ thread.get_view_url() }}">{{ _("Cancel") }}</a>
|
||||||
<input type="submit" value="{{ _('Delete') }}" class="btn btn-danger" />
|
<input type="submit" value="{{ _('Delete') }}" class="btn btn-danger" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<div class="row mt-0 mb-4 comments mx-0">
|
<div class="row mt-0 mb-4 comments mx-0">
|
||||||
<div class="col-md-1 p-1">
|
<div class="col-md-1 p-1">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ current_user.getProfilePicURL() }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ current_user.get_profile_pic_url() }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<li class="row my-2 mx-0">
|
<li class="row my-2 mx-0">
|
||||||
<div class="col-md-1 p-1">
|
<div class="col-md-1 p-1">
|
||||||
<a href="{{ url_for('users.profile', username=r.author.username) }}">
|
<a href="{{ url_for('users.profile', username=r.author.username) }}">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ r.author.getProfilePicURL() }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ r.author.get_profile_pic_url() }}">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col pr-0">
|
<div class="col pr-0">
|
||||||
@ -37,12 +37,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if r == r.thread.first_reply %}
|
{% if r == r.thread.first_reply %}
|
||||||
<a class="badge badge-primary" href="{{ r.thread.getViewURL() }}">
|
<a class="badge badge-primary" href="{{ r.thread.get_view_url() }}">
|
||||||
{{ r.thread.title }}
|
{{ r.thread.title }}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<i class="fas fa-reply mr-2"></i>
|
<i class="fas fa-reply mr-2"></i>
|
||||||
<a class="badge badge-dark" href="{{ r.thread.getViewURL() }}">
|
<a class="badge badge-dark" href="{{ r.thread.get_view_url() }}">
|
||||||
{{ _("Reply to <b>%(title)s</b>", title=r.thread.title) }}
|
{{ _("Reply to <b>%(title)s</b>", title=r.thread.title) }}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -22,32 +22,32 @@
|
|||||||
{%- endblock %}
|
{%- endblock %}
|
||||||
|
|
||||||
{% block headextra %}
|
{% block headextra %}
|
||||||
<meta name="og:image" content="{{ thread.author.getProfilePicURL() }}"/>
|
<meta name="og:image" content="{{ thread.author.get_profile_pic_url() }}"/>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if current_user.is_authenticated %}
|
{% if current_user.is_authenticated %}
|
||||||
{% if current_user in thread.watchers %}
|
{% if current_user in thread.watchers %}
|
||||||
<form method="post" action="{{ thread.getUnsubscribeURL() }}" class="float-right">
|
<form method="post" action="{{ thread.get_unsubscribe_url() }}" class="float-right">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<input type="submit" class="btn btn-primary" value="{{ _('Unsubscribe') }}" />
|
<input type="submit" class="btn btn-primary" value="{{ _('Unsubscribe') }}" />
|
||||||
</form>
|
</form>
|
||||||
{% else %}
|
{% else %}
|
||||||
<form method="post" action="{{ thread.getSubscribeURL() }}" class="float-right">
|
<form method="post" action="{{ thread.get_subscribe_url() }}" class="float-right">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<input type="submit" class="btn btn-primary" value="{{ _('Subscribe') }}" />
|
<input type="submit" class="btn btn-primary" value="{{ _('Subscribe') }}" />
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if thread.checkPerm(current_user, "DELETE_THREAD") %}
|
{% if thread.check_perm(current_user, "DELETE_THREAD") %}
|
||||||
<a href="{{ url_for('threads.delete_thread', id=thread.id) }}" class="float-right mr-2 btn btn-danger">{{ _('Delete') }}</a>
|
<a href="{{ url_for('threads.delete_thread', id=thread.id) }}" class="float-right mr-2 btn btn-danger">{{ _('Delete') }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if thread.review and thread.review.checkPerm(current_user, "DELETE_REVIEW") and current_user.username != thread.review.author.username %}
|
{% if thread.review and thread.review.check_perm(current_user, "DELETE_REVIEW") and current_user.username != thread.review.author.username %}
|
||||||
<form method="post" action="{{ thread.review.getDeleteURL() }}" class="float-right mr-2">
|
<form method="post" action="{{ thread.review.get_delete_url() }}" class="float-right mr-2">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
<input type="submit" class="btn btn-danger" value="{{ _('Convert to Thread') }}" />
|
<input type="submit" class="btn btn-danger" value="{{ _('Convert to Thread') }}" />
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if thread.checkPerm(current_user, "LOCK_THREAD") %}
|
{% if thread.check_perm(current_user, "LOCK_THREAD") %}
|
||||||
{% if thread.locked %}
|
{% if thread.locked %}
|
||||||
<form method="post" action="{{ url_for('threads.set_lock', id=thread.id, lock=0) }}" class="float-right mr-2">
|
<form method="post" action="{{ url_for('threads.set_lock', id=thread.id, lock=0) }}" class="float-right mr-2">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
@ -64,7 +64,7 @@
|
|||||||
|
|
||||||
{% if current_user == thread.author and thread.review %}
|
{% if current_user == thread.author and thread.review %}
|
||||||
<a class="btn btn-primary ml-1 float-right mr-2"
|
<a class="btn btn-primary ml-1 float-right mr-2"
|
||||||
href="{{ thread.review.package.getURL("packages.review") }}">
|
href="{{ thread.review.package.get_url("packages.review") }}">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
{{ _("Edit Review") }}
|
{{ _("Edit Review") }}
|
||||||
</a>
|
</a>
|
||||||
@ -85,7 +85,7 @@
|
|||||||
|
|
||||||
{% if thread.package %}
|
{% if thread.package %}
|
||||||
<p>
|
<p>
|
||||||
{{ _("Package") }}: <a href="{{ thread.package.getURL('packages.view') }}">{{ thread.package.title }}</a>
|
{{ _("Package") }}: <a href="{{ thread.package.get_url('packages.view') }}">{{ thread.package.title }}</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -103,7 +103,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{% for viewer in thread.get_visible_to() %}
|
{% for viewer in thread.get_visible_to() %}
|
||||||
<a href="{{ url_for('users.profile', username=viewer.username) }}" title="{{ viewer.display_name }}">
|
<a href="{{ url_for('users.profile', username=viewer.username) }}" title="{{ viewer.display_name }}">
|
||||||
<img style="max-height: 2em;" src="{{ viewer.getProfilePicURL() }}" alt="{{ viewer.display_name }}" />
|
<img style="max-height: 2em;" src="{{ viewer.get_profile_pic_url() }}" alt="{{ viewer.display_name }}" />
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<a href="{{ url_for('users.list_all') }}" title="{{ _('Plus approvers and editors') }}">
|
<a href="{{ url_for('users.list_all') }}" title="{{ _('Plus approvers and editors') }}">
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<ul class="card-body d-flex p-0 flex-row flex-wrap justify-content-start align-content-start p-4">
|
<ul class="card-body d-flex p-0 flex-row flex-wrap justify-content-start align-content-start p-4">
|
||||||
{% for s in screenshots %}
|
{% for s in screenshots %}
|
||||||
<li class="packagetile flex-fill"><a href="{{ s.getEditURL() }}"
|
<li class="packagetile flex-fill"><a href="{{ s.get_edit_url() }}"
|
||||||
style="background-image: url({{ s.getThumbnailURL(3) }});">
|
style="background-image: url({{ s.get_thumb_url(3) }});">
|
||||||
<div class="packagegridscrub"></div>
|
<div class="packagegridscrub"></div>
|
||||||
<div class="packagegridinfo">
|
<div class="packagegridinfo">
|
||||||
<h3>
|
<h3>
|
||||||
@ -46,7 +46,7 @@
|
|||||||
<h3 class="card-header">{{ _("Packages") }}</h3>
|
<h3 class="card-header">{{ _("Packages") }}</h3>
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
{% for p in packages %}
|
{% for p in packages %}
|
||||||
<a href="{{ p.getURL("packages.view") }}" class="list-group-item list-group-item-action">
|
<a href="{{ p.get_url("packages.view") }}" class="list-group-item list-group-item-action">
|
||||||
<span class="float-right" title="Created {{ p.created_at | datetime }}">
|
<span class="float-right" title="Created {{ p.created_at | datetime }}">
|
||||||
<small>
|
<small>
|
||||||
{{ p.created_at | timedelta }} ago
|
{{ p.created_at | timedelta }} ago
|
||||||
@ -79,9 +79,9 @@
|
|||||||
{% if r.task_id %}
|
{% if r.task_id %}
|
||||||
<span class="mr-2 badge badge-warning">{{ _("Importing") }}</span>
|
<span class="mr-2 badge badge-warning">{{ _("Importing") }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ r.getEditURL() }}">{{ r.title }}</a>
|
<a href="{{ r.get_edit_url() }}">{{ r.title }}</a>
|
||||||
on
|
on
|
||||||
<a href="{{ r.package.getURL("packages.view") }}">
|
<a href="{{ r.package.get_url("packages.view") }}">
|
||||||
{{ _("%(title)s by %(display_name)s",
|
{{ _("%(title)s by %(display_name)s",
|
||||||
title=r.package.title, display_name=r.package.author.display_name) }}
|
title=r.package.title, display_name=r.package.author.display_name) }}
|
||||||
</a>
|
</a>
|
||||||
@ -107,7 +107,7 @@
|
|||||||
<h3 class="card-header">{{ _("License Needed") }}</h3>
|
<h3 class="card-header">{{ _("License Needed") }}</h3>
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
{% for p in license_needed %}
|
{% for p in license_needed %}
|
||||||
<a href="{{ p.getURL("packages.view") }}" class="list-group-item list-group-item-action">
|
<a href="{{ p.get_url("packages.view") }}" class="list-group-item list-group-item-action">
|
||||||
<span class="float-right" title="Created {{ p.created_at | datetime }}">
|
<span class="float-right" title="Created {{ p.created_at | datetime }}">
|
||||||
<small>
|
<small>
|
||||||
{{ p.created_at | timedelta }} ago
|
{{ p.created_at | timedelta }} ago
|
||||||
@ -164,7 +164,7 @@
|
|||||||
<h3 class="card-header">WIP Packages</h3>
|
<h3 class="card-header">WIP Packages</h3>
|
||||||
<div class="list-group list-group-flush" style="max-height: 300px; overflow: hidden auto;">
|
<div class="list-group list-group-flush" style="max-height: 300px; overflow: hidden auto;">
|
||||||
{% for p in wip_packages %}
|
{% for p in wip_packages %}
|
||||||
<a href="{{ p.getURL("packages.view") }}" class="list-group-item list-group-item-action">
|
<a href="{{ p.get_url("packages.view") }}" class="list-group-item list-group-item-action">
|
||||||
<span class="float-right" title="Created {{ p.created_at | datetime }}">
|
<span class="float-right" title="Created {{ p.created_at | datetime }}">
|
||||||
<small>
|
<small>
|
||||||
{{ p.created_at | timedelta }} ago
|
{{ p.created_at | timedelta }} ago
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -41,7 +41,7 @@
|
|||||||
{% if supported_games %}
|
{% if supported_games %}
|
||||||
{% for support in supported_games %}
|
{% for support in supported_games %}
|
||||||
<a class="badge badge-secondary"
|
<a class="badge badge-secondary"
|
||||||
href="{{ support.game.getURL('packages.view') }}">
|
href="{{ support.game.get_url('packages.view') }}">
|
||||||
{{ _("%(title)s by %(display_name)s",
|
{{ _("%(title)s by %(display_name)s",
|
||||||
title=support.game.title, display_name=support.game.author.display_name) }}
|
title=support.game.title, display_name=support.game.author.display_name) }}
|
||||||
</a>
|
</a>
|
||||||
@ -53,8 +53,8 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<a class="btn btn-sm btn-primary" href="{{ package.getURL('packages.game_support') }}">Game Support</a>
|
<a class="btn btn-sm btn-primary" href="{{ package.get_url('packages.game_support') }}">Game Support</a>
|
||||||
<a class="btn btn-sm btn-secondary" href="{{ package.getURL('packages.view') }}">Package</a>
|
<a class="btn btn-sm btn-secondary" href="{{ package.get_url('packages.view') }}">Package</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,15 +42,15 @@
|
|||||||
{% for package in packages %}
|
{% for package in packages %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ package.getURL("packages.view") }}">
|
<a href="{{ package.get_url("packages.view") }}">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
by {{ package.author.display_name }}
|
by {{ package.author.display_name }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
|
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
|
||||||
<a class="btn btn-link btn-sm py-0" href="{{ package.getURL("packages.create_edit") }}">
|
<a class="btn btn-link btn-sm py-0" href="{{ package.get_url("packages.create_edit") }}">
|
||||||
<i class="fas fa-pen"></i>
|
<i class="fas fa-pen"></i>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -18,13 +18,13 @@
|
|||||||
<h2>{{ _("Unapproved Packages Needing Action") }}</h2>
|
<h2>{{ _("Unapproved Packages Needing Action") }}</h2>
|
||||||
<div class="list-group mt-3 mb-5">
|
<div class="list-group mt-3 mb-5">
|
||||||
{% for package in unapproved_packages %}
|
{% for package in unapproved_packages %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ package.getURL("packages.view") }}">
|
<a class="list-group-item list-group-item-action" href="{{ package.get_url("packages.view") }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-2 text-muted">
|
<div class="col-sm-2 text-muted">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -80,11 +80,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="list-group mt-3 mb-5">
|
<div class="list-group mt-3 mb-5">
|
||||||
{% for package in missing_game_support %}
|
{% for package in missing_game_support %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ package.getURL('packages.game_support') }}">
|
<a class="list-group-item list-group-item-action" href="{{ package.get_url('packages.game_support') }}">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -100,11 +100,11 @@
|
|||||||
<h2 id="missing-screenshots">{{ _("Missing Screenshots") }}</h2>
|
<h2 id="missing-screenshots">{{ _("Missing Screenshots") }}</h2>
|
||||||
<div class="list-group mt-3 mb-5">
|
<div class="list-group mt-3 mb-5">
|
||||||
{% for package in packages_with_no_screenshots %}
|
{% for package in packages_with_no_screenshots %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ package.getURL('packages.screenshots') }}">
|
<a class="list-group-item list-group-item-action" href="{{ package.get_url('packages.screenshots') }}">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -138,13 +138,13 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="list-group mt-3 mb-5">
|
<div class="list-group mt-3 mb-5">
|
||||||
{% for package in packages_with_small_screenshots %}
|
{% for package in packages_with_small_screenshots %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ package.getURL('packages.screenshots') }}">
|
<a class="list-group-item list-group-item-action" href="{{ package.get_url('packages.screenshots') }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-3 text-muted" style="min-width: 200px;">
|
<div class="col-sm-3 text-muted" style="min-width: 200px;">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
@ -183,11 +183,11 @@
|
|||||||
</p>
|
</p>
|
||||||
<div class="list-group mt-3 mb-5">
|
<div class="list-group mt-3 mb-5">
|
||||||
{% for package in needs_tags %}
|
{% for package in needs_tags %}
|
||||||
<a class="list-group-item list-group-item-action" href="{{ package.getURL("packages.view") }}">
|
<a class="list-group-item list-group-item-action" href="{{ package.get_url("packages.view") }}">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
style="max-height: 22px; max-width: 22px;"
|
style="max-height: 22px; max-width: 22px;"
|
||||||
src="{{ package.getThumbnailOrPlaceholder() }}" />
|
src="{{ package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<span class="pl-2">
|
<span class="pl-2">
|
||||||
{{ package.title }}
|
{{ package.title }}
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<a class="list-group-item list-group-item-action" href="{{ url_for('users.profile', username=user.username) }}">
|
<a class="list-group-item list-group-item-action" href="{{ url_for('users.profile', username=user.username) }}">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-2 {{ user.rank }}"
|
<div class="col-sm-2 {{ user.rank }}"
|
||||||
title="{{ _('Rank: %(rank)s.', rank=user.rank.getTitle()) }}">
|
title="{{ _('Rank: %(rank)s.', rank=user.rank.get_title()) }}">
|
||||||
{% if user.rank == user.rank.ADMIN %}
|
{% if user.rank == user.rank.ADMIN %}
|
||||||
<i class="fas fa-user-cog mr-2"></i>
|
<i class="fas fa-user-cog mr-2"></i>
|
||||||
{% elif user.rank == user.rank.MODERATOR %}
|
{% elif user.rank == user.rank.MODERATOR %}
|
||||||
@ -46,7 +46,7 @@
|
|||||||
<i class="fas fa-user mr-2"></i>
|
<i class="fas fa-user mr-2"></i>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ user.rank.getTitle() }}
|
{{ user.rank.get_title() }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="col-sm {{ user.rank }}">
|
<span class="col-sm {{ user.rank }}">
|
||||||
|
@ -15,14 +15,14 @@
|
|||||||
<form action="" method="POST" class="form" role="form">
|
<form action="" method="POST" class="form" role="form">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
{% if user.checkPerm(current_user, "CHANGE_USERNAMES") %}
|
{% if user.check_perm(current_user, "CHANGE_USERNAMES") %}
|
||||||
{{ render_field(form.username, tabindex=230) }}
|
{{ render_field(form.username, tabindex=230) }}
|
||||||
{{ render_field(form.display_name, tabindex=230) }}
|
{{ render_field(form.display_name, tabindex=230) }}
|
||||||
{{ render_field(form.forums_username, tabindex=230) }}
|
{{ render_field(form.forums_username, tabindex=230) }}
|
||||||
{{ render_field_prefix(form.github_username, tabindex=230) }}
|
{{ render_field_prefix(form.github_username, tabindex=230) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if user.checkPerm(current_user, "CHANGE_RANK") %}
|
{% if user.check_perm(current_user, "CHANGE_RANK") %}
|
||||||
{{ render_field(form.rank, tabindex=250) }}
|
{{ render_field(form.rank, tabindex=250) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<article class="row mb-5">
|
<article class="row mb-5">
|
||||||
<div class="col-auto image mx-0">
|
<div class="col-auto image mx-0">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ user.getProfilePicURL() }}" alt="{{ _('Profile picture') }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ user.get_profile_pic_url() }}" alt="{{ _('Profile picture') }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{% if user.can_see_edit_profile(current_user) %}
|
{% if user.can_see_edit_profile(current_user) %}
|
||||||
@ -57,7 +57,7 @@
|
|||||||
<span class="btn">
|
<span class="btn">
|
||||||
<i class="fas fa-user"></i>
|
<i class="fas fa-user"></i>
|
||||||
<span class="count">
|
<span class="count">
|
||||||
{{ user.rank.getTitle() }}
|
{{ user.rank.get_title() }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -195,7 +195,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if current_user == user or user.checkPerm(current_user, "CHANGE_AUTHOR") %}
|
{% if current_user == user or user.check_perm(current_user, "CHANGE_AUTHOR") %}
|
||||||
<a class="float-right btn btn-sm btn-primary"
|
<a class="float-right btn btn-sm btn-primary"
|
||||||
href="{{ url_for('packages.create_edit', author=user.username) }}">
|
href="{{ url_for('packages.create_edit', author=user.username) }}">
|
||||||
<i class="fas fa-plus mr-1"></i>
|
<i class="fas fa-plus mr-1"></i>
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
{% elif user.email %}
|
{% elif user.email %}
|
||||||
<a href="https://en.gravatar.com/">
|
<a href="https://en.gravatar.com/">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ user.getProfilePicURL() }}">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ user.get_profile_pic_url() }}">
|
||||||
{% if user.forums_username or user.email %}
|
{% if user.forums_username or user.email %}
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -42,11 +42,11 @@
|
|||||||
<form action="" method="POST" class="form" role="form">
|
<form action="" method="POST" class="form" role="form">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
{% if user.checkPerm(current_user, "CHANGE_DISPLAY_NAME") %}
|
{% if user.check_perm(current_user, "CHANGE_DISPLAY_NAME") %}
|
||||||
{{ render_field(form.display_name, tabindex=230, hint=_("Pretending to be another user is grounds for a permanent ban")) }}
|
{{ render_field(form.display_name, tabindex=230, hint=_("Pretending to be another user is grounds for a permanent ban")) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if user.checkPerm(current_user, "CHANGE_PROFILE_URLS") %}
|
{% if user.check_perm(current_user, "CHANGE_PROFILE_URLS") %}
|
||||||
{{ render_field(form.website_url, tabindex=232) }}
|
{{ render_field(form.website_url, tabindex=232) }}
|
||||||
{{ render_field(form.donate_url, tabindex=233) }}
|
{{ render_field(form.donate_url, tabindex=233) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<a class="list-group-item list-group-item-action" href="{{ url_for('users.profile', username=user.username) }}">
|
<a class="list-group-item list-group-item-action" href="{{ url_for('users.profile', username=user.username) }}">
|
||||||
<span class="row m-0 p-0">
|
<span class="row m-0 p-0">
|
||||||
<span class="col-auto m-0 p-0">
|
<span class="col-auto m-0 p-0">
|
||||||
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ user.getProfilePicURL() }}" alt="Profile picture" style="max-height: 20px;">
|
<img class="img-fluid user-photo img-thumbnail img-thumbnail-1" src="{{ user.get_profile_pic_url() }}" alt="Profile picture" style="max-height: 20px;">
|
||||||
</span>
|
</span>
|
||||||
<span class="col m-0 p-0 pl-2">
|
<span class="col m-0 p-0 pl-2">
|
||||||
{{ user.display_name }}
|
{{ user.display_name }}
|
||||||
|
@ -47,13 +47,13 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% for type in types %}
|
{% for type in types %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ type.getTitle() }}</td>
|
<td>{{ type.get_title() }}</td>
|
||||||
<td>{{ type.get_description() }}</td>
|
<td>{{ type.get_description() }}</td>
|
||||||
<td style="text-align: center;">
|
<td style="text-align: center;">
|
||||||
{{ render_checkbox_field(form["pref_" + type.toName()]) }}
|
{{ render_checkbox_field(form["pref_" + type.to_name()]) }}
|
||||||
</td>
|
</td>
|
||||||
<td style="text-align: center;">
|
<td style="text-align: center;">
|
||||||
{{ render_checkbox_field(form["pref_" + type.toName() + "_digest"]) }}
|
{{ render_checkbox_field(form["pref_" + type.to_name() + "_digest"]) }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
<div class="col-sm-2 text-muted">
|
<div class="col-sm-2 text-muted">
|
||||||
<img
|
<img
|
||||||
class="img-fluid"
|
class="img-fluid"
|
||||||
src="{{ match.package.getThumbnailOrPlaceholder() }}" />
|
src="{{ match.package.get_thumb_or_placeholder() }}" />
|
||||||
|
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<a href="{{ match.package.getURL('packages.view') }}">
|
<a href="{{ match.package.get_url('packages.view') }}">
|
||||||
{{ match.package.title }}
|
{{ match.package.title }}
|
||||||
</a>
|
</a>
|
||||||
by {{ match.package.author.display_name }}
|
by {{ match.package.author.display_name }}
|
||||||
@ -33,7 +33,7 @@
|
|||||||
{{ match.lines.split("\n") | select | list | count }} match(es)
|
{{ match.lines.split("\n") | select | list | count }} match(es)
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<a class="mt-4 btn btn-secondary" href="{{ match.package.getDownloadRelease().getDownloadURL() }}">
|
<a class="mt-4 btn btn-secondary" href="{{ match.package.get_download_release().get_download_url() }}">
|
||||||
Download
|
Download
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -133,7 +133,7 @@ def post_bot_message(package: Package, title: str, message: str):
|
|||||||
db.session.add(reply)
|
db.session.add(reply)
|
||||||
|
|
||||||
addNotification(thread.watchers, system_user, NotificationType.BOT,
|
addNotification(thread.watchers, system_user, NotificationType.BOT,
|
||||||
title, thread.getViewURL(), thread.package)
|
title, thread.get_view_url(), thread.package)
|
||||||
|
|
||||||
thread.replies.append(reply)
|
thread.replies.append(reply)
|
||||||
|
|
||||||
|
@ -55,12 +55,12 @@ You can also use a file search. For example, to find the package edit endpoint,
|
|||||||
## Users and Permissions
|
## Users and Permissions
|
||||||
|
|
||||||
Many routes need to check whether a user can do a particular thing. Rather than hard coding this,
|
Many routes need to check whether a user can do a particular thing. Rather than hard coding this,
|
||||||
models tend to have a `checkPerm` function which takes a user and a `Permission`.
|
models tend to have a `check_perm` function which takes a user and a `Permission`.
|
||||||
|
|
||||||
A permission may be something like `Permission.EDIT_PACKAGE` or `Permission.DELETE_THREAD`.
|
A permission may be something like `Permission.EDIT_PACKAGE` or `Permission.DELETE_THREAD`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
if not package.checkPerm(current_user, Permission.EDIT_PACKAGE):
|
if not package.check_perm(current_user, Permission.EDIT_PACKAGE):
|
||||||
abort(403)
|
abort(403)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user