Use consistent naming scheme for methods/functions

This commit is contained in:
rubenwardy 2023-06-18 21:56:19 +01:00
parent e0b25054dc
commit 8585357942
84 changed files with 629 additions and 639 deletions

@ -106,10 +106,10 @@ def restore():
package.state = target
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()
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
deleted_packages = Package.query \
.filter(Package.state == PackageState.DELETED) \

@ -45,7 +45,7 @@ def audit():
@login_required
def audit_view(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)
return render_template("admin/audit_view.html", entry=entry)

@ -60,7 +60,7 @@ def create_edit_tag(name=None):
if tag is None:
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)
form = TagForm( obj=tag)

@ -69,7 +69,7 @@ def packages():
query = qb.buildPackageQuery()
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())
if "engine_version" in request.args or "protocol_version" in request.args:
@ -93,7 +93,7 @@ def packages():
@is_package_page
@cors_allowed
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/")
@ -119,7 +119,7 @@ def edit_package(token, package):
def resolve_package_deps(out, package, only_hard, depth=1):
id = package.getId()
id = package.get_id()
if id in out:
return
@ -135,12 +135,12 @@ def resolve_package_deps(out, package, only_hard, depth=1):
if dep.package:
name = dep.package.name
fulfilled_by = [ dep.package.getId() ]
fulfilled_by = [ dep.package.get_id() ]
resolve_package_deps(out, dep.package, only_hard, depth)
elif dep.meta_package:
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:
most_likely = next((pkg for pkg in dep.meta_package.packages \
@ -175,7 +175,7 @@ def package_dependencies(package):
def topics():
qb = QueryBuilder(request.args)
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"])
@ -187,13 +187,13 @@ def topic_set_discard():
error(400, "Missing topic ID or discard bool")
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")
topic.discarded = discard == "true"
db.session.commit()
return jsonify(topic.getAsDictionary())
return jsonify(topic.as_dict())
@bp.route("/api/whoami/")
@ -232,14 +232,14 @@ def list_all_releases():
query = query.join(Package)
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/")
@is_package_page
@cors_allowed
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"])
@ -251,7 +251,7 @@ def create_release(token, package):
if not token:
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")
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:
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"])
@ -309,7 +309,7 @@ def delete_release(token: APIToken, package: Package, id: int):
if not token.canOperateOnPackage(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")
db.session.delete(release)
@ -323,7 +323,7 @@ def delete_release(token: APIToken, package: Package, id: int):
@cors_allowed
def list_screenshots(package):
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"])
@ -335,7 +335,7 @@ def create_screenshot(token: APIToken, package: Package):
if not token:
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")
data = request.form
@ -357,7 +357,7 @@ def screenshot(package, id):
if ss is None or ss.package != package:
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"])
@ -373,7 +373,7 @@ def delete_screenshot(token: APIToken, package: Package, id: int):
if not token:
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")
if not token.canOperateOnPackage(package):
@ -398,7 +398,7 @@ def order_screenshots(token: APIToken, package: Package):
if not token:
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")
if not token.canOperateOnPackage(package):
@ -420,7 +420,7 @@ def set_cover_image(token: APIToken, package: Package):
if not token:
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")
if not token.canOperateOnPackage(package):
@ -438,7 +438,7 @@ def set_cover_image(token: APIToken, package: Package):
@cors_allowed
def list_reviews(package):
reviews = package.reviews
return jsonify([review.getAsDictionary() for review in reviews])
return jsonify([review.as_dict() for review in 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,
"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)
query = qb.buildPackageQuery()
pkgs = [package.getScoreDict() for package in query.all()]
pkgs = [package.as_score_dict() for package in query.all()]
return jsonify(pkgs)
@bp.route("/api/tags/")
@cors_allowed
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/")
@cors_allowed
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/")
@ -549,7 +549,7 @@ def homepage():
downloads = 0 if not downloads_result or not downloads_result[0] else downloads_result[0]
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({
"count": count,
@ -574,7 +574,7 @@ def welcome_v1():
.limit(5).all()
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({
"featured": map_packages(featured),
@ -591,10 +591,10 @@ def versions():
if rel is None:
error(404, "No releases found")
return jsonify(rel.getAsDictionary())
return jsonify(rel.as_dict())
return jsonify([rel.getAsDictionary() \
for rel in MinetestRelease.query.all() if rel.getActual() is not None])
return jsonify([rel.as_dict() \
for rel in MinetestRelease.query.all() if rel.get_actual() is not None])
@bp.route("/api/dependencies/")
@ -605,7 +605,7 @@ def all_deps():
def format_pkg(pkg: Package):
return {
"type": pkg.type.toName(),
"type": pkg.type.to_name(),
"author": pkg.author.username,
"name": pkg.name,
"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({
"success": True,
"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({
"success": True,
"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({
"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({
"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:
abort(404)
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
abort(403)
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:
abort(404)
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
abort(403)
is_new = id is None
@ -108,7 +108,7 @@ def reset_token(username, id):
if user is None:
abort(404)
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
abort(403)
token = APIToken.query.get(id)
@ -134,7 +134,7 @@ def delete_token(username, id):
if user is None:
abort(404)
if not user.checkPerm(current_user, Permission.CREATE_TOKEN):
if not user.check_perm(current_user, Permission.CREATE_TOKEN):
abort(403)
is_new = id is None

@ -123,7 +123,7 @@ def webhook():
if actual_token is None:
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")
#

@ -43,7 +43,7 @@ def webhook_impl():
if token is None:
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")
#

@ -23,49 +23,49 @@ bp = Blueprint("packages", __name__)
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 []
retval = [
{
"id": "edit",
"title": gettext("Edit Details"),
"url": package.getURL("packages.create_edit")
"url": package.get_url("packages.create_edit")
},
{
"id": "releases",
"title": gettext("Releases"),
"url": package.getURL("packages.list_releases")
"url": package.get_url("packages.list_releases")
},
{
"id": "screenshots",
"title": gettext("Screenshots"),
"url": package.getURL("packages.screenshots")
"url": package.get_url("packages.screenshots")
},
{
"id": "maintainers",
"title": gettext("Maintainers"),
"url": package.getURL("packages.edit_maintainers")
"url": package.get_url("packages.edit_maintainers")
},
{
"id": "audit",
"title": gettext("Audit Log"),
"url": package.getURL("packages.audit")
"url": package.get_url("packages.audit")
},
{
"id": "stats",
"title": gettext("Statistics"),
"url": package.getURL("packages.statistics")
"url": package.get_url("packages.statistics")
},
{
"id": "share",
"title": gettext("Share and Badges"),
"url": package.getURL("packages.share")
"url": package.get_url("packages.share")
},
{
"id": "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, {
"id": "game_support",
"title": gettext("Supported Games"),
"url": package.getURL("packages.game_support")
"url": package.get_url("packages.game_support")
})
return retval

@ -68,7 +68,7 @@ def list_all():
if qb.lucky:
package = query.first()
if package:
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
topic = qb.buildTopicQuery().first()
if qb.search and topic:
@ -108,7 +108,7 @@ def list_all():
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)
else:
return package.releases.filter_by(approved=True).limit(5)
@ -117,12 +117,12 @@ def getReleases(package):
@bp.route("/packages/<author>/<name>/")
@is_package_page
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
show_similar = not package.approved and (
current_user in package.maintainers or
package.checkPerm(current_user, Permission.APPROVE_NEW))
package.check_perm(current_user, Permission.APPROVE_NEW))
conflicting_modnames = None
if show_similar and package.type != PackageType.TXP:
@ -153,7 +153,7 @@ def view(package):
releases = getReleases(package)
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
topic_error = None
@ -209,7 +209,7 @@ def shield(package, type):
@bp.route("/packages/<author>/<name>/download/")
@is_package_page
def download(package):
release = package.getDownloadRelease()
release = package.get_download_release()
if release is None:
if "application/zip" in request.accept_mimetypes and \
@ -217,9 +217,9 @@ def download(package):
return "", 204
else:
flash(gettext("No download available."), "danger")
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
else:
return redirect(release.getDownloadURL())
return redirect(release.get_download_url())
def makeLabel(obj):
@ -269,7 +269,7 @@ def handle_create_edit(package: typing.Optional[Package], form: PackageForm, aut
"danger")
else:
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")
return None
@ -301,16 +301,16 @@ def handle_create_edit(package: typing.Optional[Package], form: PackageForm, aut
if wasNew:
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:
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):
next_url = url_for("flatpage", path="help/wtfpl", r=next_url)
elif wasNew:
next_url = package.getURL("packages.setup_releases")
next_url = package.get_url("packages.setup_releases")
return redirect(next_url)
except LogicError as e:
@ -333,7 +333,7 @@ def create_edit(author=None, name=None):
flash(gettext("Unable to find that user"), "danger")
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")
return redirect(url_for("packages.create_edit"))
@ -341,8 +341,8 @@ def create_edit(author=None, name=None):
package = getPackageByInfo(author, name)
if package is None:
abort(404)
if not package.checkPerm(current_user, Permission.EDIT_PACKAGE):
return redirect(package.getURL("packages.view"))
if not package.check_perm(current_user, Permission.EDIT_PACKAGE):
return redirect(package.get_url("packages.view"))
author = package.author
@ -389,9 +389,9 @@ def move_to_state(package):
if state is None:
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")
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
package.state = state
msg = "Marked {} as {}".format(package.title, state.value)
@ -399,8 +399,8 @@ def move_to_state(package):
if state == PackageState.APPROVED:
if not package.approved_at:
post_discord_webhook.delay(package.author.username,
"New package {}".format(package.getURL("packages.view", absolute=True)), False,
package.title, package.short_desc, package.getThumbnailURL(2, True))
"New package {}".format(package.get_url("packages.view", absolute=True)), False,
package.title, package.short_desc, package.get_thumb_url(2, True))
package.approved_at = datetime.datetime.now()
screenshots = PackageScreenshot.query.filter_by(package=package, approved=False).all()
@ -410,23 +410,23 @@ def move_to_state(package):
msg = "Approved {}".format(package.title)
elif state == PackageState.READY_FOR_REVIEW:
post_discord_webhook.delay(package.author.username,
"Ready for Review: {}".format(package.getURL("packages.view", absolute=True)), True,
package.title, package.short_desc, package.getThumbnailURL(2, True))
"Ready for Review: {}".format(package.get_url("packages.view", absolute=True)), 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
addAuditLog(severity, current_user, msg, package.getURL("packages.view"), package)
addAuditLog(severity, current_user, msg, package.get_url("packages.view"), package)
db.session.commit()
if package.state == PackageState.CHANGES_NEEDED:
flash(gettext("Please comment what changes are needed in the approval thread"), "warning")
if package.review_thread:
return redirect(package.review_thread.getViewURL())
return redirect(package.review_thread.get_view_url())
else:
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"])
@ -440,9 +440,9 @@ def remove(package):
reason = request.form.get("reason") or "?"
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")
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
package.state = PackageState.DELETED
@ -456,21 +456,21 @@ def remove(package):
return redirect(url)
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")
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
package.state = PackageState.WIP
msg = "Unapproved {}, reason={}".format(package.title, reason)
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_APPROVAL, msg, package.getURL("packages.view"), package)
addAuditLog(AuditSeverity.EDITOR, current_user, 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.get_url("packages.view"), package)
db.session.commit()
flash(gettext("Unapproved package"), "success")
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
else:
abort(400)
@ -485,9 +485,9 @@ class PackageMaintainersForm(FlaskForm):
@login_required
@is_package_page
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")
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
form = PackageMaintainersForm(formdata=request.form)
if request.method == "GET":
@ -504,12 +504,12 @@ def edit_maintainers(package):
if thread:
thread.watchers.append(user)
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:
if user != package.author and not user in users:
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.extend(users)
@ -517,13 +517,13 @@ def edit_maintainers(package):
package.maintainers.append(package.author)
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
addAuditLog(severity, current_user, msg, package.getURL("packages.view"), package)
addAuditLog(severity, current_user, msg, package.get_url("packages.view"), package)
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()
@ -545,19 +545,19 @@ def remove_self_maintainers(package):
package.maintainers.remove(current_user)
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()
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
@bp.route("/packages/<author>/<name>/audit/")
@login_required
@is_package_page
def audit(package):
if not (package.checkPerm(current_user, Permission.EDIT_PACKAGE) or
package.checkPerm(current_user, Permission.APPROVE_NEW)):
if not (package.check_perm(current_user, Permission.EDIT_PACKAGE) or
package.check_perm(current_user, Permission.APPROVE_NEW)):
abort(403)
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)
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)
@ -655,8 +655,8 @@ def game_support(package):
if package.type != PackageType.MOD and package.type != PackageType.TXP:
abort(404)
can_edit = package.checkPerm(current_user, Permission.EDIT_PACKAGE)
if not (can_edit or package.checkPerm(current_user, Permission.APPROVE_NEW)):
can_edit = package.check_perm(current_user, Permission.EDIT_PACKAGE)
if not (can_edit or package.check_perm(current_user, Permission.APPROVE_NEW)):
abort(403)
force_game_detection = package.supported_games.filter(and_(
@ -694,7 +694,7 @@ def game_support(package):
except LogicError as e:
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
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
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()

@ -76,8 +76,8 @@ class EditPackageReleaseForm(FlaskForm):
@login_required
@is_package_page
def create_release(package):
if not package.checkPerm(current_user, Permission.MAKE_RELEASE):
return redirect(package.getURL("packages.view"))
if not package.check_perm(current_user, Permission.MAKE_RELEASE):
return redirect(package.get_url("packages.view"))
# Initial form class from post data and default data
form = CreatePackageReleaseForm()
@ -94,11 +94,11 @@ def create_release(package):
try:
if form["uploadOpt"].data == "vcs":
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:
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())
return redirect(url_for("tasks.check", id=rel.task_id, r=rel.getEditURL()))
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.get_edit_url()))
except LogicError as e:
flash(e.message, "danger")
@ -151,10 +151,10 @@ def edit_release(package, id):
if release is None or release.package != package:
abort(404)
canEdit = package.checkPerm(current_user, Permission.MAKE_RELEASE)
canApprove = release.checkPerm(current_user, Permission.APPROVE_RELEASE)
canEdit = package.check_perm(current_user, Permission.MAKE_RELEASE)
canApprove = release.check_perm(current_user, Permission.APPROVE_RELEASE)
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
form = EditPackageReleaseForm(formdata=request.form, obj=release)
@ -166,10 +166,10 @@ def edit_release(package, id):
if form.validate_on_submit():
if canEdit:
release.title = form["title"].data
release.min_rel = form["min_rel"].data.getActual()
release.max_rel = form["max_rel"].data.getActual()
release.min_rel = form["min_rel"].data.get_actual()
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.task_id = form["task_id"].data
if release.task_id is not None:
@ -181,7 +181,7 @@ def edit_release(package, id):
release.approved = False
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)
@ -202,8 +202,8 @@ class BulkReleaseForm(FlaskForm):
@login_required
@is_package_page
def bulk_change_release(package):
if not package.checkPerm(current_user, Permission.MAKE_RELEASE):
return redirect(package.getURL("packages.view"))
if not package.check_perm(current_user, Permission.MAKE_RELEASE):
return redirect(package.get_url("packages.view"))
# Initial form class from post data and default data
form = BulkReleaseForm()
@ -215,13 +215,13 @@ def bulk_change_release(package):
for release in package.releases.all():
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):
release.max_rel = form["max_rel"].data.getActual()
release.max_rel = form["max_rel"].data.get_actual()
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)
@ -234,13 +234,13 @@ def delete_release(package, id):
if release is None or release.package != package:
abort(404)
if not release.checkPerm(current_user, Permission.DELETE_RELEASE):
return redirect(package.getURL("packages.list_releases"))
if not release.check_perm(current_user, Permission.DELETE_RELEASE):
return redirect(package.get_url("packages.list_releases"))
db.session.delete(release)
db.session.commit()
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
class PackageUpdateConfigFrom(FlaskForm):
@ -288,12 +288,12 @@ def set_update_config(package, form):
@login_required
@is_package_page
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)
if not package.repo:
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)
if request.method == "GET":
@ -317,9 +317,9 @@ def update_config(package):
if not form.disable.data and package.releases.count() == 0:
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)
@ -328,11 +328,11 @@ def update_config(package):
@login_required
@is_package_page
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)
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)

@ -54,13 +54,13 @@ class ReviewForm(FlaskForm):
def review(package):
if current_user in package.maintainers:
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:
abort(404)
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:
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
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")
else:
was_new = False
@ -114,7 +114,7 @@ def review(package):
db.session.commit()
package.recalcScore()
package.recalculate_score()
if was_new:
notif_msg = "New review '{}'".format(form.title.data)
@ -128,11 +128,11 @@ def review(package):
if was_new:
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()
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
return render_template("packages/review_create_edit.html",
form=form, package=package, review=review)
@ -148,7 +148,7 @@ def delete_review(package, reviewer):
if review is None or review.package != package:
abort(404)
if not review.checkPerm(current_user, Permission.DELETE_REVIEW):
if not review.check_perm(current_user, Permission.DELETE_REVIEW):
abort(403)
thread = review.thread
@ -164,18 +164,18 @@ def delete_review(package, reviewer):
msg = "Converted review by {} to thread".format(review.author.display_name)
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)
addNotification(package.maintainers, current_user, NotificationType.OTHER, notif_msg, url_for("threads.view", id=thread.id), package)
db.session.delete(review)
package.recalcScore()
package.recalculate_score()
db.session.commit()
return redirect(thread.getViewURL())
return redirect(thread.get_view_url())
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):
return redirect(next_url)
else:
return redirect(review.thread.getViewURL())
return redirect(review.thread.get_view_url())
@bp.route("/packages/<author>/<name>/review-votes/")
@ -228,7 +228,7 @@ def review_vote(package, review_id):
def review_votes(package):
user_biases = {}
for review in package.reviews:
review_sign = review.asWeight()
review_sign = review.as_weight()
for vote in review.votes:
user_biases[vote.user.username] = user_biases.get(vote.user.username, [0, 0])
vote_sign = 1 if vote.is_positive else -1

@ -50,8 +50,8 @@ class EditPackageScreenshotsForm(FlaskForm):
@login_required
@is_package_page
def screenshots(package):
if not package.checkPerm(current_user, Permission.ADD_SCREENSHOTS):
return redirect(package.getURL("packages.view"))
if not package.check_perm(current_user, Permission.ADD_SCREENSHOTS):
return redirect(package.get_url("packages.view"))
form = EditPackageScreenshotsForm(obj=package)
form.cover_image.query = package.screenshots
@ -61,7 +61,7 @@ def screenshots(package):
if order:
try:
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:
flash(e.message, "danger")
@ -77,15 +77,15 @@ def screenshots(package):
@login_required
@is_package_page
def create_screenshot(package):
if not package.checkPerm(current_user, Permission.ADD_SCREENSHOTS):
return redirect(package.getURL("packages.view"))
if not package.check_perm(current_user, Permission.ADD_SCREENSHOTS):
return redirect(package.get_url("packages.view"))
# Initial form class from post data and default data
form = CreateScreenshotForm()
if form.validate_on_submit():
try:
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:
flash(e.message, "danger")
@ -100,10 +100,10 @@ def edit_screenshot(package, id):
if screenshot is None or screenshot.package != package:
abort(404)
canEdit = package.checkPerm(current_user, Permission.ADD_SCREENSHOTS)
canApprove = package.checkPerm(current_user, Permission.APPROVE_SCREENSHOT)
canEdit = package.check_perm(current_user, Permission.ADD_SCREENSHOTS)
canApprove = package.check_perm(current_user, Permission.APPROVE_SCREENSHOT)
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
form = EditScreenshotForm(obj=screenshot)
@ -119,7 +119,7 @@ def edit_screenshot(package, id):
screenshot.approved = wasApproved
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)
@ -132,7 +132,7 @@ def delete_screenshot(package, id):
if screenshot is None or screenshot.package != package:
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")
return redirect(url_for("homepage.home"))
@ -143,4 +143,4 @@ def delete_screenshot(package, id):
db.session.delete(screenshot)
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
def subscribe(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)
if current_user in thread.watchers:
@ -70,14 +70,14 @@ def subscribe(id):
thread.watchers.append(current_user)
db.session.commit()
return redirect(thread.getViewURL())
return redirect(thread.get_view_url())
@bp.route("/threads/<int:id>/unsubscribe/", methods=["POST"])
@login_required
def unsubscribe(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)
if current_user in thread.watchers:
@ -87,14 +87,14 @@ def unsubscribe(id):
else:
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"])
@login_required
def set_lock(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)
thread.locked = isYes(request.args.get("lock"))
@ -109,19 +109,19 @@ def set_lock(id):
msg = "Unlocked thread '{}'".format(thread.title)
flash(gettext("Unlocked thread"), "success")
addNotification(thread.watchers, current_user, NotificationType.OTHER, msg, thread.getViewURL(), thread.package)
addAuditLog(AuditSeverity.MODERATION, current_user, 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.get_view_url(), thread.package)
db.session.commit()
return redirect(thread.getViewURL())
return redirect(thread.get_view_url())
@bp.route("/threads/<int:id>/delete/", methods=["GET", "POST"])
@login_required
def delete_thread(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)
if request.method == "GET":
@ -157,21 +157,21 @@ def delete_reply(id):
if thread.first_reply == reply:
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)
if request.method == "GET":
return render_template("threads/delete_reply.html", thread=thread, reply=reply)
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.commit()
return redirect(thread.getViewURL())
return redirect(thread.get_view_url())
class CommentForm(FlaskForm):
@ -194,7 +194,7 @@ def edit_reply(id):
if reply is None or reply.thread != thread:
abort(404)
if not reply.checkPerm(current_user, Permission.EDIT_REPLY):
if not reply.check_perm(current_user, Permission.EDIT_REPLY):
abort(403)
form = CommentForm(formdata=request.form, obj=reply)
@ -205,14 +205,14 @@ def edit_reply(id):
else:
msg = "Edited reply by {}".format(reply.author.display_name)
severity = AuditSeverity.NORMAL if current_user == reply.author else AuditSeverity.MODERATION
addNotification(reply.author, current_user, NotificationType.OTHER, msg, thread.getViewURL(), thread.package)
addAuditLog(severity, current_user, msg, thread.getViewURL(), thread.package, reply.comment)
addNotification(reply.author, current_user, NotificationType.OTHER, msg, thread.get_view_url(), thread.package)
addAuditLog(severity, current_user, msg, thread.get_view_url(), thread.package, reply.comment)
reply.comment = comment
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)
@ -220,20 +220,20 @@ def edit_reply(id):
@bp.route("/threads/<int:id>/", methods=["GET", "POST"])
def view(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)
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
if form and form.validate_on_submit() and request.form.get("title") is None:
comment = form.comment.data
if not current_user.canCommentRL():
if not current_user.can_comment_ratelimit():
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")
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)
addNotification(mentioned, current_user, NotificationType.THREAD_REPLY,
msg, thread.getViewURL(), thread.package)
msg, thread.get_view_url(), thread.package)
thread.watchers.append(mentioned)
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():
approvers = User.query.filter(User.rank >= UserRank.APPROVER).all()
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,
"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()
return redirect(thread.getViewURL())
return redirect(thread.get_view_url())
return render_template("threads/view.html", thread=thread, form=form)
@ -300,7 +300,7 @@ def new():
is_review_thread = package and not package.approved
# 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")
return redirect(url_for("homepage.home"))
@ -308,13 +308,13 @@ def new():
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
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")
if package:
return redirect(package.getURL("packages.view"))
return redirect(package.get_url("packages.view"))
else:
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)
addNotification(mentioned, current_user, NotificationType.NEW_THREAD,
msg, thread.getViewURL(), thread.package)
msg, thread.get_view_url(), thread.package)
thread.watchers.append(mentioned)
notif_msg = "New thread '{}'".format(thread.title)
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()
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:
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()
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)

@ -106,7 +106,7 @@ def apply_all_updates(username):
.order_by(db.asc(Package.title)).all()
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
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)
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg,
rel.getURL("packages.create_edit"), package)
addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.getURL("packages.view"), package)
rel.get_url("packages.create_edit"), package)
addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.get_url("packages.view"), package)
db.session.commit()
return redirect(url_for("todo.view_user", username=username))
@ -174,7 +174,7 @@ def confirm_supports_all_games(username=None):
db.session.merge(package)
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()

@ -216,7 +216,7 @@ def profile(username):
if not user:
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)
maintained_packages = user.maintained_packages.filter_by(state=PackageState.APPROVED)
else:

@ -59,7 +59,7 @@ def handle_profile_edit(form: UserProfileForm, user: User, username: str):
url_for("users.profile", username=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:
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),
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 \
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")
@ -124,7 +124,7 @@ def make_settings_form():
}
for notificationType in NotificationType:
key = "pref_" + notificationType.toName()
key = "pref_" + notificationType.to_name()
attrs[key] = BooleanField("")
attrs[key + "_digest"] = BooleanField("")
@ -135,15 +135,15 @@ SettingsForm = make_settings_form()
def handle_email_notifications(user, prefs: UserNotificationPreferences, is_new, form):
for notificationType in NotificationType:
field_email = getattr(form, "pref_" + notificationType.toName()).data
field_digest = getattr(form, "pref_" + notificationType.toName() + "_digest").data or field_email
field_email = getattr(form, "pref_" + notificationType.to_name()).data
field_digest = getattr(form, "pref_" + notificationType.to_name() + "_digest").data or field_email
prefs.set_can_email(notificationType, field_email)
prefs.set_can_digest(notificationType, field_digest)
if is_new:
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
if newEmail and newEmail != user.email and newEmail.strip() != "":
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:
abort(404)
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
if not user.check_perm(current_user, Permission.CHANGE_EMAIL):
abort(403)
is_new = False
@ -195,8 +195,8 @@ def email_notifications(username=None):
types = []
for notificationType in NotificationType:
types.append(notificationType)
data["pref_" + notificationType.toName()] = prefs.get_can_email(notificationType)
data["pref_" + notificationType.toName() + "_digest"] = prefs.get_can_digest(notificationType)
data["pref_" + notificationType.to_name()] = prefs.get_can_email(notificationType)
data["pref_" + notificationType.to_name() + "_digest"] = prefs.get_can_digest(notificationType)
data["email"] = user.email
@ -285,7 +285,7 @@ def modtools(username):
if not user:
abort(404)
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
if not user.check_perm(current_user, Permission.CHANGE_EMAIL):
abort(403)
form = ModToolsForm(obj=user)
@ -295,7 +295,7 @@ def modtools(username):
url_for("users.profile", username=username))
# 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:
for package in user.packages:
alias = PackageAlias(user.username, package.name)
@ -308,12 +308,12 @@ def modtools(username):
user.forums_username = nonEmptyOrNone(form.forums_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
if current_user.rank.atLeast(newRank):
if newRank != user.rank:
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,
url_for("users.profile", username=username))
else:
@ -333,7 +333,7 @@ def modtools_set_email(username):
if not user:
abort(404)
if not user.checkPerm(current_user, Permission.CHANGE_EMAIL):
if not user.check_perm(current_user, Permission.CHANGE_EMAIL):
abort(403)
user.email = request.form["email"]
@ -364,7 +364,7 @@ def modtools_ban(username):
if not user:
abort(404)
if not user.checkPerm(current_user, Permission.CHANGE_RANK):
if not user.check_perm(current_user, Permission.CHANGE_RANK):
abort(403)
message = request.form["message"]
@ -394,7 +394,7 @@ def modtools_unban(username):
if not user:
abort(404)
if not user.checkPerm(current_user, Permission.CHANGE_RANK):
if not user.check_perm(current_user, Permission.CHANGE_RANK):
abort(403)
if user.ban:

@ -16,7 +16,7 @@
import sys
from typing import List, Dict, Optional, Iterable
from typing import List, Dict
import sqlalchemy.orm
@ -102,7 +102,7 @@ class GameSupportResolver:
print(f"Resolving for {key}", file=sys.stderr)
history = history.copy()
history.append(package.getId())
history.append(package.get_id())
if package.type == PackageType.GAME:
return {package.id}
@ -135,7 +135,7 @@ class GameSupportResolver:
self.resolved_packages[key] = 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():
retval = self.resolve(package, [])
for game_id in retval:

@ -109,7 +109,7 @@ def get_package_overview_for_user(user: Optional[User], start_date: datetime.dat
if user:
package_title_by_id[package.id] = package.title
else:
package_title_by_id[package.id] = package.getId()
package_title_by_id[package.id] = package.get_id()
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
return retval
missing_deps = package.getMissingHardDependenciesQuery().all()
missing_deps = package.get_missing_hard_dependencies_query().all()
if len(missing_deps) > 0:
retval.append(("danger", lazy_gettext(
"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,
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"))
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"))
before_dict = None
if not was_new:
before_dict = package.getAsDictionary("/")
before_dict = package.as_dict("/")
for alias, to in ALIASES.items():
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"]:
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"))
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)
if not was_new:
after_dict = package.getAsDictionary("/")
after_dict = package.as_dict("/")
diff = diff_dictionaries(before_dict, after_dict)
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 + "]"
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()

@ -28,7 +28,7 @@ from app.utils import AuditSeverity, addAuditLog, nonEmptyOrNone
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"))
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)
else:
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()
@ -89,7 +89,7 @@ def do_create_zip_release(user: User, package: Package, title: str, file,
msg = "Created release {}".format(rel.title)
else:
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()

@ -26,7 +26,7 @@ def do_create_screenshot(user: User, package: Package, title: str, file, is_cove
ss.package = package
ss.title = title or "Untitled"
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.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:
msg = "Created screenshot {} ({})".format(ss.title, reason)
addNotification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.getURL("packages.view"), package)
addAuditLog(AuditSeverity.NORMAL, user, 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.get_url("packages.view"), package)
db.session.commit()

@ -63,12 +63,12 @@ class AuditSeverity(enum.Enum):
def __str__(self):
return self.name
def getTitle(self):
def get_title(self):
return self.name.replace("_", " ").title()
@classmethod
def choices(cls):
return [(choice, choice.getTitle()) for choice in cls]
return [(choice, choice.get_title()) for choice in cls]
@classmethod
def coerce(cls, item):
@ -106,14 +106,14 @@ class AuditLogEntry(db.Model):
self.package = package
self.description = description
def checkPerm(self, user, perm):
def check_perm(self, user, perm):
if not user.is_authenticated:
return False
if type(perm) == str:
perm = Permission[perm]
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:
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/")
def getAsDictionary(self):
def as_dict(self):
return {
"author": self.author.username,
"name": self.name,
"type": self.type.toName(),
"type": self.type.to_name(),
"title": self.title,
"id": self.topic_id,
"link": self.link,
@ -171,14 +171,14 @@ class ForumTopic(db.Model):
"created_at": self.created_at.isoformat(),
}
def checkPerm(self, user, perm):
def check_perm(self, user, perm):
if not user.is_authenticated:
return False
if type(perm) == str:
perm = Permission[perm]
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:
return self.author == user or user.rank.atLeast(UserRank.EDITOR)

@ -17,7 +17,6 @@
import datetime
import enum
import typing
from flask import url_for
from flask_babel import lazy_gettext
@ -55,7 +54,7 @@ class PackageType(enum.Enum):
GAME = "Game"
TXP = "Texture Pack"
def toName(self):
def to_name(self):
return self.name.lower()
def __str__(self):
@ -104,7 +103,7 @@ class PackageDevState(enum.Enum):
DEPRECATED = "Deprecated"
LOOKING_FOR_MAINTAINER = "Looking for Maintainer"
def toName(self):
def to_name(self):
return self.name.lower()
def __str__(self):
@ -161,7 +160,7 @@ class PackageState(enum.Enum):
APPROVED = "Approved"
DELETED = "Deleted"
def toName(self):
def to_name(self):
return self.name.lower()
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()
def getId(self):
def get_id(self):
return "{}/{}".format(self.author.username, self.name)
def getIsFOSS(self):
return self.license.is_foss and self.media_license.is_foss
def getSortedDependencies(self, is_hard=None):
def get_sorted_dependencies(self, is_hard=None):
query = self.dependencies
if is_hard is not None:
query = query.filter_by(optional=not is_hard)
deps = query.all()
deps.sort(key = lambda x: x.getName())
deps.sort(key=lambda x: x.getName())
return deps
def getSortedHardDependencies(self):
return self.getSortedDependencies(True)
def get_sorted_hard_dependencies(self):
return self.get_sorted_dependencies(True)
def getSortedOptionalDependencies(self):
return self.getSortedDependencies(False)
def get_sorted_optional_dependencies(self):
return self.get_sorted_dependencies(False)
def get_sorted_game_support(self):
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 \
self.supported_games.filter(PackageGameSupport.confidence > 1).count() > 0
def getAsDictionaryKey(self):
def as_key_dict(self):
return {
"name": self.name,
"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):
tnurl = self.getThumbnailURL(1)
def as_short_dict(self, base_url, version=None, release_id=None, no_load=False):
tnurl = self.get_thumb_url(1)
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
short_desc = self.short_desc
@ -565,10 +561,10 @@ class Package(db.Model):
"title": self.title,
"author": self.author.username,
"short_description": short_desc,
"type": self.type.toName(),
"type": self.type.to_name(),
"release": release_id,
"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"]:
@ -576,9 +572,9 @@ class Package(db.Model):
return ret
def getAsDictionary(self, base_url, version=None):
tnurl = self.getThumbnailURL(1)
release = self.getDownloadRelease(version=version)
def as_dict(self, base_url, version=None):
tnurl = self.get_thumb_url(1)
release = self.get_download_release(version=version)
return {
"author": self.author.username,
"maintainers": [x.username for x in self.maintainers],
@ -590,7 +586,7 @@ class Package(db.Model):
"title": self.title,
"short_description": self.short_desc,
"long_description": self.desc,
"type": self.type.toName(),
"type": self.type.to_name(),
"created_at": self.created_at.isoformat(),
"license": self.license.name,
@ -610,7 +606,7 @@ class Package(db.Model):
"thumbnail": (base_url + tnurl) if tnurl is not None else None,
"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,
"score": round(self.score * 10) / 10,
@ -620,86 +616,86 @@ class Package(db.Model):
{
"supports": support.supports,
"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()
]
}
def getThumbnailOrPlaceholder(self, level=2):
return self.getThumbnailURL(level) or "/static/placeholder.png"
def get_thumb_or_placeholder(self, level=2):
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
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:
from app.utils import abs_url
return abs_url(url)
else:
return url
def getCoverImageURL(self):
def get_cover_image_url(self):
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:
from app.utils import abs_url_for
return abs_url_for(endpoint, author=self.author.username, name=self.name, **kwargs)
else:
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
return abs_url_for("packages.shield",
author=self.author.username, name=self.name, type=type)
def makeShield(self, type):
def make_shield(self, type):
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:
state = PackageState[state]
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",
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:
if rel.approved and (version is None or
((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 None
def checkPerm(self, user, perm):
def check_perm(self, user, perm):
if not user.is_authenticated:
return False
if type(perm) == str:
perm = Permission[perm]
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
isMaintainer = isOwner or user.rank.atLeast(UserRank.EDITOR) or user in self.maintainers
isApprover = user.rank.atLeast(UserRank.APPROVER)
is_owner = user == self.author
is_maintainer = is_owner or user.rank.atLeast(UserRank.EDITOR) or user in self.maintainers
is_approver = user.rank.atLeast(UserRank.APPROVER)
if perm == Permission.CREATE_THREAD:
return user.rank.atLeast(UserRank.NEW_MEMBER)
# Members can edit their own packages, and editors can edit any packages
elif perm == Permission.MAKE_RELEASE or perm == Permission.ADD_SCREENSHOTS:
return isMaintainer
return is_maintainer
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:
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
elif perm == Permission.CHANGE_NAME:
@ -707,17 +703,17 @@ class Package(db.Model):
# Editors can change authors and approve new packages
elif perm == Permission.APPROVE_NEW or perm == Permission.CHANGE_AUTHOR:
return isApprover
return is_approver
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)
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:
return isOwner or user.rank.atLeast(UserRank.APPROVER)
return is_owner or user.rank.atLeast(UserRank.APPROVER)
elif perm == Permission.CHANGE_RELEASE_URL:
return user.rank.atLeast(UserRank.MODERATOR)
@ -725,65 +721,64 @@ class Package(db.Model):
else:
raise Exception("Permission {} is not related to packages".format(perm.name))
def getMissingHardDependenciesQuery(self):
def get_missing_hard_dependencies_query(self):
return MetaPackage.query \
.filter(~ MetaPackage.packages.any(state=PackageState.APPROVED)) \
.filter(MetaPackage.dependencies.any(optional=False, depender=self)) \
.order_by(db.asc(MetaPackage.name))
def getMissingHardDependencies(self):
return [mp.name for mp in self.getMissingHardDependenciesQuery().all()]
def get_missing_hard_dependencies(self):
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:
return False
if type(state) == str:
state = PackageState[state]
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]:
return False
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
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
if state == PackageState.APPROVED and ("Other" in self.license.name or "Other" in self.media_license.name):
return False
if self.getMissingHardDependenciesQuery().count() > 0:
if self.get_missing_hard_dependencies_query().count() > 0:
return False
needsScreenshot = \
(self.type == self.type.GAME or self.type == self.type.TXP) and \
self.screenshots.count() == 0
needs_screenshot = \
(self.type == self.type.GAME or self.type == self.type.TXP) and 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:
return self.checkPerm(user, Permission.APPROVE_NEW)
return self.check_perm(user, Permission.APPROVE_NEW)
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))
return True
def getNextStates(self, user):
def get_next_states(self, user):
states = []
for state in PackageState:
if self.canMoveToState(user, state):
if self.can_move_to_state(user, state):
states.append(state)
return states
def getScoreDict(self):
def as_score_dict(self):
return {
"author": self.author.username,
"name": self.name,
@ -793,16 +788,16 @@ class Package(db.Model):
"downloads": self.downloads
}
def recalcScore(self):
review_scores = [ 100 * r.asWeight() for r in self.reviews ]
def recalculate_score(self):
review_scores = [ 100 * r.as_weight() for r in self.reviews ]
self.score = self.score_downloads + sum(review_scores)
class MetaPackage(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True, nullable=False)
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True, nullable=False)
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_]+$'")
@ -866,7 +861,7 @@ class ContentWarning(db.Model):
regex = re.compile("[^a-z_]")
self.name = regex.sub("", self.title.lower().replace(" ", "_"))
def getAsDictionary(self):
def as_dict(self):
description = self.description if self.description != "" else None
return { "name": self.name, "title": self.title, "description": description }
@ -892,7 +887,7 @@ class Tag(db.Model):
regex = re.compile("[^a-z_]")
self.name = regex.sub("", self.title.lower().replace(" ", "_"))
def getAsDictionary(self):
def as_dict(self):
description = self.description if self.description != "" else None
return {
"name": self.name,
@ -912,10 +907,10 @@ class MinetestRelease(db.Model):
self.name = name
self.protocol = protocol
def getActual(self):
def get_actual(self):
return None if self.name == "None" else self
def getAsDictionary(self):
def as_dict(self):
return {
"name": self.name,
"protocol_version": self.protocol,
@ -972,7 +967,7 @@ class PackageRelease(db.Model):
def file_path(self):
return self.url.replace("/uploads/", app.config["UPLOAD_DIR"])
def getAsDictionary(self):
def as_dict(self):
return {
"id": self.id,
"title": self.title,
@ -980,11 +975,11 @@ class PackageRelease(db.Model):
"release_date": self.releaseDate.isoformat(),
"commit": self.commit_hash,
"downloads": self.downloads,
"min_minetest_version": self.min_rel and self.min_rel.getAsDictionary(),
"max_minetest_version": self.max_rel and self.max_rel.getAsDictionary(),
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
"max_minetest_version": self.max_rel and self.max_rel.as_dict(),
}
def getLongAsDictionary(self):
def as_long_dict(self):
return {
"id": self.id,
"title": self.title,
@ -992,24 +987,24 @@ class PackageRelease(db.Model):
"release_date": self.releaseDate.isoformat(),
"commit": self.commit_hash,
"downloads": self.downloads,
"min_minetest_version": self.min_rel and self.min_rel.getAsDictionary(),
"max_minetest_version": self.max_rel and self.max_rel.getAsDictionary(),
"package": self.package.getAsDictionaryKey()
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
"max_minetest_version": self.max_rel and self.max_rel.as_dict(),
"package": self.package.as_key_dict()
}
def getEditURL(self):
def get_edit_url(self):
return url_for("packages.edit_release",
author=self.package.author.username,
name=self.package.name,
id=self.id)
def getDeleteURL(self):
def get_delete_url(self):
return url_for("packages.delete_release",
author=self.package.author.username,
name=self.package.name,
id=self.id)
def getDownloadURL(self):
def get_download_url(self):
return url_for("packages.download_release",
author=self.package.author.username,
name=self.package.name,
@ -1018,11 +1013,11 @@ class PackageRelease(db.Model):
def __init__(self):
self.releaseDate = datetime.datetime.now()
def getDownloadFileName(self):
def get_download_filename(self):
return f"{self.package.name}_{self.id}.zip"
def approve(self, user):
if not self.checkPerm(user, Permission.APPROVE_RELEASE):
if not self.check_perm(user, Permission.APPROVE_RELEASE):
return False
if self.approved:
@ -1038,22 +1033,22 @@ class PackageRelease(db.Model):
return True
def checkPerm(self, user, perm):
def check_perm(self, user, perm):
if not user.is_authenticated:
return False
if type(perm) == str:
perm = Permission[perm]
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 user.rank.atLeast(UserRank.ADMIN):
return True
if not (isMaintainer or user.rank.atLeast(UserRank.EDITOR)):
if not (is_maintainer or user.rank.atLeast(UserRank.EDITOR)):
return False
if not self.package.approved or self.task_id is not None:
@ -1066,7 +1061,7 @@ class PackageRelease(db.Model):
return count > 0
elif perm == Permission.APPROVE_RELEASE:
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))
else:
raise Exception("Permission {} is not related to releases".format(perm.name))
@ -1103,22 +1098,22 @@ class PackageScreenshot(db.Model):
def file_path(self):
return self.url.replace("/uploads/", app.config["UPLOAD_DIR"])
def getEditURL(self):
def get_edit_url(self):
return url_for("packages.edit_screenshot",
author=self.package.author.username,
name=self.package.name,
id=self.id)
def getDeleteURL(self):
def get_delete_url(self):
return url_for("packages.delete_screenshot",
author=self.package.author.username,
name=self.package.name,
id=self.id)
def getThumbnailURL(self, level=2):
def get_thumb_url(self, level=2):
return self.url.replace("/uploads/", "/thumbnails/{:d}/".format(level))
def getAsDictionary(self, base_url=""):
def as_dict(self, base_url=""):
return {
"id": self.id,
"order": self.order,
@ -1136,7 +1131,7 @@ class PackageUpdateTrigger(enum.Enum):
COMMIT = "New Commit"
TAG = "New Tag"
def toName(self):
def to_name(self):
return self.name.lower()
def __str__(self):
@ -1199,7 +1194,7 @@ class PackageUpdateConfig(db.Model):
return self.last_tag or self.last_commit
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):
@ -1215,11 +1210,11 @@ class PackageAlias(db.Model):
self.author = author
self.name = name
def getEditURL(self):
def get_edit_url(self):
return url_for("packages.alias_create_edit", author=self.package.author.username,
name=self.package.name, alias_id=self.id)
def getAsDictionary(self):
def as_dict(self):
return f"{self.author}/{self.name}"

@ -66,27 +66,27 @@ class Thread(db.Model):
else:
return comment
def getViewURL(self, absolute=False):
def get_view_url(self, absolute=False):
if absolute:
from ..utils import abs_url_for
return abs_url_for("threads.view", id=self.id)
else:
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)
def getUnsubscribeURL(self):
def get_unsubscribe_url(self):
return url_for("threads.unsubscribe", id=self.id)
def checkPerm(self, user, perm):
def check_perm(self, user, perm):
if not user.is_authenticated:
return perm == Permission.SEE_THREAD and not self.private
if type(perm) == str:
perm = Permission[perm]
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)
if self.package:
@ -145,16 +145,16 @@ class ThreadReply(db.Model):
created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
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:
return False
if type(perm) == str:
perm = Permission[perm]
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:
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)
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()
ret = {
"is_positive": self.rating > 3,
@ -209,19 +209,19 @@ class PackageReview(db.Model):
"comment": self.thread.first_reply.comment,
}
if include_package:
ret["package"] = self.package.getAsDictionaryKey()
ret["package"] = self.package.as_key_dict()
return ret
def asWeight(self):
def as_weight(self):
"""
From (1, 5) to (-1 to 1)
"""
return (self.rating - 3.0) / 2.0
def getEditURL(self):
return self.package.getURL("packages.review")
def get_edit_url(self):
return self.package.get_url("packages.review")
def getDeleteURL(self):
def get_delete_url(self):
return url_for("packages.delete_review",
author=self.package.author.username,
name=self.package.name,
@ -238,14 +238,14 @@ class PackageReview(db.Model):
(pos, neg, _) = self.get_totals()
self.score = 3 * (pos - neg) + 1
def checkPerm(self, user, perm):
def check_perm(self, user, perm):
if not user.is_authenticated:
return False
if type(perm) == str:
perm = Permission[perm]
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:
return user == self.author or user.rank.atLeast(UserRank.MODERATOR)

@ -41,10 +41,10 @@ class UserRank(enum.Enum):
def atLeast(self, min):
return self.value >= min.value
def getTitle(self):
def get_title(self):
return self.name.replace("_", " ").title()
def toName(self):
def to_name(self):
return self.name.lower()
def __str__(self):
@ -52,7 +52,7 @@ class UserRank(enum.Enum):
@classmethod
def choices(cls):
return [(choice, choice.getTitle()) for choice in cls]
return [(choice, choice.get_title()) for choice in cls]
@classmethod
def coerce(cls, item):
@ -93,7 +93,7 @@ class Permission(enum.Enum):
VIEW_AUDIT_DESCRIPTION = "VIEW_AUDIT_DESCRIPTION"
# 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):
if not user.is_authenticated:
return False
@ -108,10 +108,10 @@ class Permission(enum.Enum):
return user.rank.atLeast(UserRank.EDITOR)
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
def checkPerm(user, perm):
def check_perm(user, perm):
if type(perm) == str:
perm = Permission[perm]
elif type(perm) != Permission:
@ -213,14 +213,10 @@ class User(db.Model, UserMixin):
self.password = password
self.rank = UserRank.NOT_JOINED
def canAccessTodoList(self):
return Permission.APPROVE_NEW.check(self) or \
Permission.APPROVE_RELEASE.check(self)
def can_access_todo_list(self):
return Permission.APPROVE_NEW.check(self) or Permission.APPROVE_RELEASE.check(self)
def isClaimed(self):
return self.rank.atLeast(UserRank.NEW_MEMBER)
def getProfilePicURL(self):
def get_profile_pic_url(self):
if self.profile_pic:
return self.profile_pic
elif self.rank == UserRank.BOT:
@ -228,14 +224,14 @@ class User(db.Model, UserMixin):
else:
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:
return False
if type(perm) == str:
perm = Permission[perm]
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
if perm == Permission.CHANGE_AUTHOR:
@ -256,7 +252,7 @@ class User(db.Model, UserMixin):
else:
raise Exception("Permission {} is not related to users".format(perm.name))
def canCommentRL(self):
def can_comment_ratelimit(self):
from app.models import ThreadReply
factor = 1
@ -279,7 +275,7 @@ class User(db.Model, UserMixin):
return True
def canOpenThreadRL(self):
def can_open_thread_ratelimit(self):
from app.models import Thread
factor = 1
@ -291,10 +287,10 @@ class User(db.Model, UserMixin):
factor = 2
hour_ago = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
return Thread.query.filter_by(author=self) \
.filter(Thread.created_at > hour_ago).count() < 2 * factor
return Thread.query.filter_by(author=self)\
.filter(Thread.created_at > hour_ago).count() < 2 * factor
def canReviewRL(self):
def can_review_ratelimit(self):
from app.models import PackageReview
factor = 1
@ -310,8 +306,7 @@ class User(db.Model, UserMixin):
hour_ago = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
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):
if other is None:
@ -324,9 +319,9 @@ class User(db.Model, UserMixin):
return self.id == other.id
def can_see_edit_profile(self, current_user):
return self.checkPerm(current_user, Permission.CHANGE_USERNAMES) or \
self.checkPerm(current_user, Permission.CHANGE_EMAIL) or \
self.checkPerm(current_user, Permission.CHANGE_RANK)
return self.check_perm(current_user, Permission.CHANGE_USERNAMES) or \
self.check_perm(current_user, Permission.CHANGE_EMAIL) or \
self.check_perm(current_user, Permission.CHANGE_RANK)
def can_delete(self):
from app.models import ForumTopic
@ -392,10 +387,10 @@ class NotificationType(enum.Enum):
OTHER = 0
def getTitle(self):
def get_title(self):
return self.name.replace("_", " ").title()
def toName(self):
def to_name(self):
return self.name.lower()
def get_description(self):
@ -430,7 +425,7 @@ class NotificationType(enum.Enum):
@classmethod
def choices(cls):
return [(choice, choice.getTitle()) for choice in cls]
return [(choice, choice.get_title()) for choice in cls]
@classmethod
def coerce(cls, item):
@ -512,21 +507,21 @@ class UserNotificationPreferences(db.Model):
self.pref_other = 0
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):
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):
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):
if self.get_can_email(notification_type):
return
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):

@ -128,7 +128,7 @@ class QueryBuilder:
def toJson(package: Package):
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]

@ -173,7 +173,7 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
db.session.rollback()
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)
if "Fails validation" not in release.title:
@ -309,7 +309,7 @@ def check_update_config_impl(package):
db.session.add(rel)
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()
@ -367,7 +367,7 @@ def check_update_config(self, package_id):
.strip()
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)

@ -24,6 +24,6 @@ def updatePackageScores():
db.session.commit()
for package in Package.query.all():
package.recalcScore()
package.recalculate_score()
db.session.commit()

@ -36,7 +36,7 @@ def post_discord_webhook(username: Optional[str], content: str, is_queue: bool,
json["username"] = username
user = User.query.filter_by(username=username).first()
if user:
json["avatar_url"] = user.getProfilePicURL().replace("/./", "/")
json["avatar_url"] = user.get_profile_pic_url().replace("/./", "/")
if json["avatar_url"].startswith("/"):
json["avatar_url"] = app.config["BASE_URL"] + json["avatar_url"]

@ -39,7 +39,7 @@ def search_in_releases(query: str, file_filter: str):
continue
elif exit_code == 0:
results.append({
"package": package.getAsDictionaryKey(),
"package": package.as_key_dict(),
"lines": handle.stdout.read(),
})
@ -48,7 +48,7 @@ def search_in_releases(query: str, file_filter: str):
# Create new
while len(running) < 1 and len(packages) > 0:
package = packages.pop()
release: Optional[PackageRelease] = package.getDownloadRelease()
release: Optional[PackageRelease] = package.get_download_release()
if release:
handle = Popen(["zipgrep", query, release.file_path, file_filter], stdout=PIPE, encoding="UTF-8")
running.append([package, handle])

@ -20,7 +20,7 @@ def inject_debug():
@app.context_processor
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,
check_global_perm=check_global_perm, get_headings=get_headings, url_current=url_current)
@ -28,7 +28,7 @@ def inject_functions():
@app.context_processor
def inject_todo():
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 += PackageRelease.query.filter_by(approved=False, task_id=None).count()

@ -21,11 +21,11 @@
<li class="list-group-item">
<div class="row">
<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
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -38,7 +38,7 @@
</div>
<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") }}
</a>
<a href="{{ package.donate_url_actual }}" class="btn btn-sm btn-primary" rel="nofollow">

@ -34,5 +34,5 @@
{{ _("Unsubscribe") }}
</a> <br>
{{ _("This is a '%(type)s' notification.", type=notification.type.getTitle()) }}
{{ _("This is a '%(type)s' notification.", type=notification.type.get_title()) }}
{% endblock %}

@ -33,10 +33,10 @@
</ol>
<div class="carousel-inner">
{% 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) %}
<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">
<img class="embed-responsive-item" src="{{ cover_image }}"
alt="{{ _('%(title)s by %(author)s', title=package.title, author=package.author.display_name) }}">

@ -2,7 +2,7 @@
<div class="list-group mt-3">
{% for entry in log %}
<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) }}">
{% else %}
href="{{ entry.url }}">
@ -10,7 +10,7 @@
<div class="row {% if entry.severity == entry.severity.NORMAL %}text-muted{% endif %}">
<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 %}
<i class="fas fa-exclamation-triangle" style="color: yellow;"></i>
{% elif entry.severity == entry.severity.EDITOR %}
@ -25,7 +25,7 @@
<img
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
style="max-height: 22px;"
src="{{ entry.causer.getProfilePicURL() }}" />
src="{{ entry.causer.get_profile_pic_url() }}" />
<span class="pl-2">{{ entry.causer.username }}</span>
{% else %}
@ -50,7 +50,7 @@
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ entry.package.getThumbnailOrPlaceholder() }}" />
src="{{ entry.package.get_thumb_or_placeholder() }}" />
</div>
{% endif %}

@ -5,8 +5,8 @@
{{ _("State") }}: <strong>{{ package.state.value }}</strong>
</span>
{% for state in package.getNextStates(current_user) %}
<form class="col-auto" method="post" action="{{ package.getSetStateURL(state) }}">
{% for state in package.get_next_states(current_user) %}
<form class="col-auto" method="post" action="{{ package.get_set_state_url(state) }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input class="btn btn-sm btn-primary" type="submit" value="{{ state.verb() }}" />
</form>
@ -16,13 +16,13 @@
{% set level = "warning" %}
{% if package.releases.filter_by(task_id=None).count() == 0 %}
{% set message %}
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
{% 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") }}
</a>
{% 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") }}
</a>
{% endif %}
@ -40,8 +40,8 @@
{% 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.") %}
{% elif package.getMissingHardDependenciesQuery().count() > 0 %}
{% set deps = package.getMissingHardDependencies() | join(", ") %}
{% elif package.get_missing_hard_dependencies_query().count() > 0 %}
{% 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) %}
{% elif topic_error_lvl == "danger" %}
@ -58,15 +58,15 @@
{% endif %}
{% 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.") }}
{% 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.") }}
{% else %}
{{ _("Please wait for the package to be approved.") }}
{% endif %}
{% 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.") }}
{% else %}
{{ _("This package can be submitted for approval when ready.") }}
@ -95,7 +95,7 @@
{% if conflicting_modnames %}
<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
</a>
{% if conflicting_modnames | length > 4 %}
@ -106,7 +106,7 @@
</div>
{% 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">
<a class="float-right btn btn-sm btn-secondary" href="{{ url_for('threads.new', pid=package.id, title='Package approval comments') }}">
{{ _("Open Thread") }}

@ -1,6 +1,6 @@
{% macro render_pkgtile(package, show_author) -%}
<li class="packagetile flex-fill"><a href="{{ package.getURL("packages.view") }}"
style="background-image: url({{ package.getThumbnailOrPlaceholder(2) }});">
<li class="packagetile flex-fill"><a href="{{ package.get_url("packages.view") }}"
style="background-image: url({{ package.get_thumb_or_placeholder(2) }});">
<div class="packagegridscrub"></div>
<div class="packagegridinfo">
<h3>

@ -1,6 +1,6 @@
{% macro render_releases_edit(releases, package) %}
{% 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 }}
<span class="text-muted ml-1">
{% if rel.min_rel and rel.max_rel %}
@ -26,8 +26,8 @@
{% macro render_releases_download(releases, package, current_user) %}
{% for rel in releases %}
{% if rel.approved or package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE") %}
<a class="list-group-item list-group-item-action" href="{{ rel.getDownloadURL() }}">
{% 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.get_download_url() }}">
{{ rel.title }}
<span class="text-muted ml-1">
{% if rel.min_rel and rel.max_rel %}
@ -55,8 +55,8 @@
{% macro render_releases(releases, package, current_user) -%}
{% for rel in releases %}
<div class="list-group-item">
<a class="btn btn-sm btn-primary float-right" href="{{ rel.getEditURL() }}">
{% if not rel.task_id and not rel.approved and rel.checkPerm(current_user, "APPROVE_RELEASE") %}
<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.check_perm(current_user, "APPROVE_RELEASE") %}
{{ _("Edit / Approve") }}
{% else %}
{{ _("Edit") }}
@ -65,7 +65,7 @@
{% 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 }}
</a>
@ -88,8 +88,8 @@
{{ _("created %(date)s", date=rel.releaseDate | date) }}.
</small>
{% if (package.checkPerm(current_user, "MAKE_RELEASE") or rel.checkPerm(current_user, "APPROVE_RELEASE")) and rel.task_id %}
<a href="{{ url_for('tasks.check', id=rel.task_id, r=package.getURL("packages.view")) }}">
{% 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.get_url("packages.view")) }}">
{{ _("Importing...") }}
</a>
{% elif not rel.approved %}

@ -27,7 +27,7 @@
<a id="{{ review_anchor }}"></a>
<div class="col-md-1 p-1">
<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>
</div>
<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">
{% if current_user == review.author %}
<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>
</a>
{% endif %}
@ -71,7 +71,7 @@
<div class="btn-toolbar mt-2 mb-0">
{% 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="<b>" | safe + review.package.title + "</b>" | safe,
author=review.package.author.display_name) }}
@ -105,7 +105,7 @@
<div class="card-header">
{{ _("Review") }}
</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() }}" />
<p>
{{ _("Do you recommend this %(type)s?", type=package.type.text | lower) }}
@ -148,7 +148,7 @@
<div class="card-header">
{{ _("Review") }}
</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() }}" />
<p>
{{ _("Do you recommend this %(type)s?", type=package.type.text | lower) }}

@ -21,7 +21,7 @@
</a>
<div class="dropdown-divider"></div>
{% 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 }}
</a>
{% endfor %}

@ -4,7 +4,7 @@
<li class="row my-2 mx-0">
<div class="col-md-1 p-1">
<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>
</div>
<div class="col pr-0">
@ -28,7 +28,7 @@
{% endif %}
{% if r.author.rank == r.author.rank.BOT %}
<span class="badge badge-dark">
{{ r.author.rank.getTitle() }}
{{ r.author.rank.get_title() }}
</span>
{% endif %}
@ -39,7 +39,7 @@
</div>
<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"
href="{{ url_for('threads.delete_reply', id=thread.id, reply=r.id) }}">
<i class="fas fa-trash"></i>
@ -55,10 +55,10 @@
{% if current_user == thread.author and thread.review and thread.first_reply == r %}
<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>
</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"
href="{{ url_for('threads.edit_reply', id=thread.id, reply=r.id) }}">
<i class="fas fa-pen"></i>
@ -68,7 +68,7 @@
{{ r.comment | markdown }}
{% 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 %}
</div>
</div>
@ -81,7 +81,7 @@
<li class="row my-2 mx-0 align-items-center">
<div class="col-md-1 p-1">
<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>
</div>
<div class="col-auto">
@ -137,7 +137,7 @@
<div class="row mt-0 mb-4 comments mx-0">
<div class="col-md-1 p-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 class="col pr-0">
<div class="card">
@ -146,12 +146,12 @@
<a name="reply"></a>
</div>
{% if not current_user.canCommentRL() %}
{% if not current_user.can_comment_ratelimit() %}
<div class="card-body">
<textarea class="form-control" readonly disabled>{{ _("Please wait before commenting again.") }}</textarea><br />
<input class="btn btn-primary" type="submit" disabled value="Comment" />
</div>
{% elif not thread.checkPerm(current_user, "COMMENT_THREAD") %}
{% elif not thread.check_perm(current_user, "COMMENT_THREAD") %}
<div class="card-body">
{% if thread.locked %}
<textarea class="form-control" readonly disabled>{{ _("This thread has been locked.") }}</textarea><br />
@ -266,7 +266,7 @@
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ t.package.getThumbnailOrPlaceholder() }}" /><br />
src="{{ t.package.get_thumb_or_placeholder() }}" /><br />
<span class="pl-2">
{{ t.package.title }}

@ -4,11 +4,11 @@
{% set config = package.update_config %}
<li class="list-group-item">
<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
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -29,7 +29,7 @@
<div class="col-sm-auto">
{% 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() }}">
<i class="fas fa-plus mr-1"></i>
{{ _("Release") }}
@ -42,8 +42,8 @@
{{ _("Repo") }}
</a>
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
<a class="btn btn-sm btn-secondary" href="{{ package.getURL("packages.update_config") }}">
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
<a class="btn btn-sm btn-secondary" href="{{ package.get_url("packages.update_config") }}">
<i class="fas fa-cog mr-1"></i>
{{ _("Update settings") }}
</a>
@ -60,13 +60,13 @@
{% macro render_mtsupport_packages(packages, current_user, show_config=False) -%}
<div class="list-group mt-3">
{% 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="col-sm-auto text-muted" style="min-width: 200px;">
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -74,7 +74,7 @@
</div>
<div class="col-sm">
{% set release = package.getDownloadRelease() %}
{% set release = package.get_download_release() %}
{% if release %}
{{ release.min_rel.name }} - {{ release.max_rel.name }}
{% endif %}

@ -23,13 +23,13 @@
<td>{{ topic.name or ""}}</td>
<td>{{ topic.created_at | date }}</td>
<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"
href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.getRepoURL(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
{{ _("Create") }}
</a>
{% 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 }}>
{% if topic.discarded %}
{{ _("Show") }}
@ -59,7 +59,7 @@
{% if show_author %}
by <a href="{{ url_for('users.profile', username=topic.author.username) }}">{{ topic.author.display_name }}</a>
{% 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) }}">
{{ _("Create") }}

@ -36,7 +36,7 @@
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ n.package.getThumbnailOrPlaceholder() }}" />
src="{{ n.package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ n.package.title }}
@ -53,7 +53,7 @@
<img
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
style="max-height: 22px;"
src="{{ n.causer.getProfilePicURL() }}" />
src="{{ n.causer.get_profile_pic_url() }}" />
</div>
</div>
</a>
@ -74,7 +74,7 @@
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ n.package.getThumbnailOrPlaceholder() }}" />
src="{{ n.package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ n.package.title }}
@ -91,7 +91,7 @@
<img
class="img-fluid user-photo img-thumbnail img-thumbnail-1"
style="max-height: 22px;"
src="{{ n.causer.getProfilePicURL() }}" />
src="{{ n.causer.get_profile_pic_url() }}" />
</div>
</div>
</a>

@ -5,11 +5,11 @@
{% endblock %}
{% block link %}
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
{% endblock %}
{% 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") }}
</a>

@ -5,18 +5,18 @@
{% endblock %}
{% block link %}
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
{% endblock %}
{% 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") }}
</a>
<h1>{{ _("Aliases for %(title)s by %(author)s", title=self.link(), author=package.author.display_name) }}</h1>
<div class="list-group">
{% for alias in package.aliases %}
<a class="list-group-item list-group-item-action" href="{{ alias.getEditURL() }}">
<a class="list-group-item list-group-item-action" href="{{ alias.get_edit_url() }}">
{{ alias.author }} / {{ alias.name }}
</a>
{% else %}

@ -68,7 +68,7 @@
<div class="row">
{{ render_field(form.type, class_="pkg_meta col-sm-2") }}
{{ 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",
readonly=True, hint=_("Please open a thread to request a name change")) }}
{% else %}

@ -10,8 +10,8 @@
{% endblock %}
{% block headextra %}
{% if package.getThumbnailURL(3, True) %}
<meta name="og:image" content="{{ package.getThumbnailURL(3, True) }}"/>
{% if package.get_thumb_url(3, True) %}
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
{% endif %}
{% endblock %}
@ -21,40 +21,40 @@
<h1 class="mb-5">
{{ _("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) }}
</a>
</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") }}
</a>
<h2 class="my-3">{{ _("Recently Added") }}</h2>
{{ 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") }}
</a>
<h2 class="my-3">{{ _("Recently Updated") }}</h2>
{{ 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") }}
</a>
<h2 class="my-3">{{ _("Top Mods") }}</h2>
{{ 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") }}
</a>
<h2 class="my-3">{{ _("Top Texture Packs") }}</h2>
{{ 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") }}
</a>
<h2 class="my-3">{{ _("Highest Reviewed") }}</h2>

@ -36,7 +36,7 @@
{% for support in package.get_sorted_game_support() %}
<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">
<span class="col-5">
{{ _("%(title)s by %(display_name)s",

@ -9,8 +9,8 @@
{% endblock %}
{% block headextra %}
{% if package.getThumbnailURL(3, True) -%}
<meta name="og:image" content="{{ package.getThumbnailURL(3, True) }}"/>
{% if package.get_thumb_url(3, True) -%}
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
{%- endif %}
{% endblock %}

@ -6,11 +6,11 @@
<div class="row">
<div class="col-md-3 mb-4">
<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="col-auto m-0 p-0">
<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 class="col m-0 p-0 pl-2">
{{ package.title }}

@ -11,13 +11,13 @@
<form method="POST" action="">
{{ form.hidden_tag() }}
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
{{ render_field(form.title) }}
{% else %}
{{ _("Title") }}: {{ release.title }}
{% endif %}
{% if package.checkPerm(current_user, "CHANGE_RELEASE_URL") %}
{% if package.check_perm(current_user, "CHANGE_RELEASE_URL") %}
{{ render_field(form.url) }}
{% else %}
{{ _("URL") }}: <a href="{{ release.url }}">{{ release.url }}</a><br />
@ -29,14 +29,14 @@
{% if release.task_id %}
{{ _("Importing...") }}
<a href="{{ url_for('tasks.check', id=release.task_id, r=release.getEditURL()) }}">{{ _("view task") }}</a><br />
{% if package.checkPerm(current_user, "CHANGE_RELEASE_URL") %}
<a href="{{ url_for('tasks.check', id=release.task_id, r=release.get_edit_url()) }}">{{ _("view task") }}</a><br />
{% if package.check_perm(current_user, "CHANGE_RELEASE_URL") %}
{{ render_field(form.task_id) }}
{% endif %}
<br />
{% else %}
{% if release.checkPerm(current_user, "APPROVE_RELEASE") %}
{% if release.check_perm(current_user, "APPROVE_RELEASE") %}
{{ render_checkbox_field(form.approved, class_="my-3") }}
{% else %}
{{ _("Approved") }}: {{ release.approved }}
@ -69,8 +69,8 @@
<h2 class="mt-5">{{ _("Delete Release") }}</h2>
{% if release.checkPerm(current_user, "DELETE_RELEASE") %}
<form method="POST" action="{{ release.getDeleteURL() }}" class="alert alert-secondary mb-5">
{% if release.check_perm(current_user, "DELETE_RELEASE") %}
<form method="POST" action="{{ release.get_delete_url() }}" class="alert alert-secondary mb-5">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input class="btn btn-sm btn-danger float-right" type="submit" value="{{ _('Delete') }}">
<b>{{ _("This is permanent.") }}</b>

@ -9,7 +9,7 @@
{% if package.update_config %}
<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 %}
{{ _("You have automatic releases enabled.") }}
{% else %}
@ -20,12 +20,12 @@
{% else %}
<p class="alert alert-info mb-4">
{% 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>
{{ _("You can create releases automatically when you push commits or tags to your repository.") }}
{% 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>
{{ _("Using Git would allow you to create releases automatically when you push code or tags.") }}

@ -5,7 +5,7 @@
{% endblock %}
{% 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") }}
</a>
<h1>{{ self.title() }}</h1>
@ -30,13 +30,13 @@
<div class="col-md-6 mt-5">
<h3 class="mt-0">{{ _("Automatically (Recommended)") }}</h3>
<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") }}
</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") }}
</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") }}#}
{# </a>#}
</p>
@ -45,10 +45,10 @@
<div class="col-md-6 mt-5">
<h3 class="mt-0">{{ _("Manually") }}</h3>
<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") }}
</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") }}
</a>
</p>
@ -65,13 +65,13 @@
</p>
<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") }}
</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") }}
</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") }}
</a>
</p>

@ -5,26 +5,26 @@
{% endblock %}
{% block content %}
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
<p class="float-right">
{% 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>
{{ _("Update settings") }}
</a>
{% 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>
{{ _("Set up automatic releases") }}
</a>
{% 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>
{{ _("Bulk update") }}
</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>
{{ _("Create") }}
</a>
@ -35,7 +35,7 @@
<div class="list-group">
{% 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) }}
{% else %}
{{ render_releases_download(package.releases, package, current_user) }}

@ -31,7 +31,7 @@ Remove {{ package.title }}
</small>
</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" />

@ -5,7 +5,7 @@
{% endblock %}
{% block link %}
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
{% endblock %}
{% block content %}
@ -22,7 +22,7 @@
{{ form.hidden_tag() }}
<div class="row mt-0 mb-4 comments mx-0">
<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 class="col">
<div class="card">
@ -50,7 +50,7 @@
</form>
{% 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 class="btn btn-sm btn-danger float-right" type="submit" value="{{ _('Delete') }}">
<b>{{ _("Delete review.") }}</b>

@ -5,7 +5,7 @@
{% endblock %}
{% block link %}
<a href="{{ package.getURL("packages.view") }}">{{ package.title }}</a>
<a href="{{ package.get_url("packages.view") }}">{{ package.title }}</a>
{% endblock %}
@ -61,7 +61,7 @@
{% else %}
<i class="fas fa-minus mr-2"></i>
{% endif %}
<a href="{{ review.thread.getViewURL() }}">
<a href="{{ review.thread.get_view_url() }}">
{{ review.thread.title }}
</a> by {{ review.author.display_name }}
</th>

@ -14,7 +14,7 @@
{{ render_field(form.title) }}
{% if package.checkPerm(current_user, "APPROVE_SCREENSHOT") %}
{% if package.check_perm(current_user, "APPROVE_SCREENSHOT") %}
{{ render_checkbox_field(form.approved) }}
{% else %}
<p>{{ _("Approved") }}: {{ screenshot.approved }}</p>
@ -24,7 +24,7 @@
</form>
<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>
</div>
{% endblock %}

@ -5,8 +5,8 @@
{% endblock %}
{% block content %}
{% if package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
<a href="{{ package.getURL('packages.create_screenshot') }}" class="btn btn-primary float-right">
{% if package.check_perm(current_user, "ADD_SCREENSHOTS") %}
<a href="{{ package.get_url('packages.create_screenshot') }}" class="btn btn-primary float-right">
<i class="fas fa-plus mr-1"></i>
{{ _("Add Image") }}
</a>
@ -16,14 +16,14 @@
<ul class="list-group sortable">
{% set screenshots = package.screenshots.all() %}
{% 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 }}">
<div class="row">
<div class="col-auto text-muted pr-2">
<i class="fas fa-bars"></i>
</div>
<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 class="col">
{{ ss.title }}
@ -52,9 +52,9 @@
{% endif %}
</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() }}" />
<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>
</a>
<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.") }}
</p>
<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">
<p>
<span class="title">{{ package.title }}</span> by {{ package.author.username }}

@ -13,23 +13,23 @@
{{ _("Review link") }}:
</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>
<p>
{{ package.makeShield("title") | markdown }}
{{ package.make_shield("title") | markdown }}
</p>
<p>
<pre><code>{{ package.makeShield("title") }}</code></pre>
<pre><code>{{ package.make_shield("title") }}</code></pre>
</p>
<p>
{{ package.makeShield("downloads") | markdown }}
{{ package.make_shield("downloads") | markdown }}
</p>
<p>
<pre><code>{{ package.makeShield("downloads") }}</code></pre>
<pre><code>{{ package.make_shield("downloads") }}</code></pre>
</p>
{% endblock %}

@ -5,7 +5,7 @@
{% endblock %}
{% 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>
{% if packages_modnames %}
@ -18,7 +18,7 @@
<ul>
{% for pkg in packages %}
<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) }}
</a>
[{{ pkg.type.text }}]

@ -13,7 +13,7 @@
{% block content %}
<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>
{{ _("Download (.csv)") }}
</a>
@ -21,5 +21,5 @@
{{ render_package_selector(package.author, package=package) }}
</div>
<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 %}

@ -1,5 +1,5 @@
{% set query=package.name %}
{% set release = package.getDownloadRelease() %}
{% set release = package.get_download_release() %}
{% extends "base.html" %}
@ -12,8 +12,8 @@
{% endblock %}
{% block headextra %}
{% if package.getThumbnailURL(3, True) -%}
<meta name="og:image" content="{{ package.getThumbnailURL(3, True) }}"/>
{% if package.get_thumb_url(3, True) -%}
<meta name="og:image" content="{{ package.get_thumb_url(3, True) }}"/>
{%- endif %}
{% endblock %}
@ -31,8 +31,8 @@
{% block download_btn %}
{% if release %}
<a class="btn btn-block btn-download" rel="nofollow" download="{{ release.getDownloadFileName() }}"
href="{{ release.getDownloadURL() }}">
<a class="btn btn-block btn-download" rel="nofollow" download="{{ release.get_download_filename() }}"
href="{{ release.get_download_url() }}">
<div>
{{ _("Download") }}
</div>
@ -90,7 +90,7 @@
{% from "macros/package_approval.html" import render_banners %}
{{ 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 %}&#x1f512;{% endif %} {{ review_thread.title }}</h2>
{% if review_thread.private %}
<p><i>
@ -105,7 +105,7 @@
</section>
{% endif %}
{% set cover_image = package.getCoverImageURL() %}
{% set cover_image = package.get_cover_image_url() %}
<header class="jumbotron pb-3"
style="background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.7)), url('{{ cover_image }}');
background-size: cover;
@ -113,20 +113,20 @@
background-position: center;">
<div class="container">
<div class="btn-group float-right mb-4">
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
<a class="btn btn-primary" href="{{ package.getURL('packages.create_edit') }}">
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
<a class="btn btn-primary" href="{{ package.get_url('packages.create_edit') }}">
<i class="fas fa-pen mr-1"></i>
{{ _("Edit") }}
</a>
{% endif %}
{% if package.checkPerm(current_user, "MAKE_RELEASE") %}
<a class="btn btn-primary" href="{{ package.getURL('packages.create_release') }}">
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
<a class="btn btn-primary" href="{{ package.get_url('packages.create_release') }}">
<i class="fas fa-plus mr-1"></i>
{{ _("Release") }}
</a>
{% endif %}
{% if package.checkPerm(current_user, "DELETE_PACKAGE") or package.checkPerm(current_user, "UNAPPROVE_PACKAGE") %}
<a class="btn btn-danger" href="{{ package.getURL('packages.remove') }}">
{% if package.check_perm(current_user, "DELETE_PACKAGE") or package.check_perm(current_user, "UNAPPROVE_PACKAGE") %}
<a class="btn btn-danger" href="{{ package.get_url('packages.remove') }}">
<i class="fas fa-trash mr-1"></i>
{{ _("Remove") }}
</a>
@ -179,14 +179,14 @@
<div class="info-row row" style="margin-top: 2rem;">
<div class="btn-group-horizontal col">
<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">
{{ package.author.display_name }}
</span>
</a>
{% if release %}
<a class="btn" rel="nofollow" href="{{ release.getDownloadURL() }}" title="{{ _('Downloads') }}"
download="{{ release.getDownloadFileName() }}">
<a class="btn" rel="nofollow" href="{{ release.get_download_url() }}" title="{{ _('Downloads') }}"
download="{{ release.get_download_filename() }}">
<i class="fas fa-download"></i>
<span class="count">{{ package.downloads }}</span>
</a>
@ -229,7 +229,7 @@
<span class="count">{{ _("Issue Tracker") }}</span>
</a>
{% 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>
<span class="count">{{ _("Statistics") }}</span>
</a>
@ -247,14 +247,14 @@
<div class="col-md-9" style="padding-right: 45px;">
{% set screenshots = package.screenshots.all() %}
{% if package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
<a href="{{ package.getURL('packages.screenshots') }}" class="btn btn-primary float-right">
{% if package.check_perm(current_user, "ADD_SCREENSHOTS") %}
<a href="{{ package.get_url('packages.screenshots') }}" class="btn btn-primary float-right">
<i class="fas fa-images mr-1"></i>
{{ _("Edit") }}
</a>
{% 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">
{% if package.video_url %}
<li>
@ -267,12 +267,12 @@
</li>
{% endif %}
{% if screenshots or package.checkPerm(current_user, "ADD_SCREENSHOTS") %}
{% if screenshots or package.check_perm(current_user, "ADD_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>
<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 %}
<span class="badge bg-dark badge-tr">{{ _("Awaiting review") }}</span>
{% endif %}
@ -281,7 +281,7 @@
{% endif %}
{% else %}
<li>
<a href="{{ package.getURL('packages.create_screenshot') }}">
<a href="{{ package.get_url('packages.create_screenshot') }}">
<i class="fas fa-plus screenshot-add"></i>
</a>
</li>
@ -303,7 +303,7 @@
{% if current_user.is_authenticated %}
{% if has_review %}
<p>
<a class="btn btn-primary" href="{{ package.getURL("packages.review") }}">
<a class="btn btn-primary" href="{{ package.get_url("packages.review") }}">
{{ _("Edit Review") }}
</a>
</p>
@ -324,7 +324,7 @@
{% endif %}
{% 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 %}
{{ render_reviews(package.reviews, current_user) }}
@ -337,7 +337,7 @@
{% if package.type == package.type.GAME %}
<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") }}
</a>
{% endif %}
@ -348,7 +348,7 @@
{{ self.download_btn() }}
</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 %}
<div class="alert alert-warning">
<p class="mt-0 my-1">
@ -366,7 +366,7 @@
<i class="fas fa-plus mr-1"></i>
{{ _("Release") }}
</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>
{{ _("Update settings") }}
</a>
@ -391,7 +391,7 @@
{% endif %}
{% 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") }}
</a>
{% endif %}
@ -401,10 +401,10 @@
<dl>
<dt>{{ _("Required") }}</dt>
<dd>
{% for dep in package.getSortedHardDependencies() %}
{% for dep in package.get_sorted_hard_dependencies() %}
{%- if dep.package %}
<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=dep.package.title, display_name=dep.package.author.display_name) }}
</a>
@ -421,14 +421,14 @@
{% endfor %}
</dd>
{% set optional_deps=package.getSortedOptionalDependencies() %}
{% set optional_deps=package.get_sorted_optional_dependencies() %}
{% if optional_deps %}
<dt>{{ _("Optional") }}</dt>
<dd>
{% for dep in optional_deps %}
{%- if dep.package %}
<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=dep.package.title, display_name=dep.package.author.display_name) }}
{% elif dep.meta_package %}
@ -451,8 +451,8 @@
{% set show_unsupported = package.supports_all_games or supported_games == [] %}
{% if supported_games or unsupported_games or package.type == package.type.MOD %}
<h3>
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
<a href="{{ package.getURL('packages.game_support') }}" class="btn btn-secondary btn-sm float-right">
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
<a href="{{ package.get_url('packages.game_support') }}" class="btn btn-secondary btn-sm float-right">
<i class="fas fa-pen"></i>
</a>
{% endif %}
@ -473,7 +473,7 @@
<div style="max-height: 300px; overflow: hidden auto;" class="mb-3">
{% for support in supported_games %}
<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=support.game.title, display_name=support.game.author.display_name) }}
</a>
@ -483,14 +483,14 @@
<p>
{{ _("No specific game required") }}
</p>
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
<div class="alert alert-warning">
<p>
{{ _("Is the above correct?") }}
{{ _("You need to either confirm this or tell ContentDB about supported games") }}
</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
</a>
</div>
@ -504,7 +504,7 @@
<div style="max-height: 300px; overflow: hidden auto;">
{% for support in unsupported_games %}
<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>
{{ _("%(title)s by %(display_name)s",
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.") }}
</p>
{% endif %}
{% elif package.checkPerm(current_user, "EDIT_PACKAGE") %}
{% elif package.check_perm(current_user, "EDIT_PACKAGE") %}
<p class="alert alert-warning">
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
<a href="{{ package.getURL('packages.game_support') }}" class="btn btn-warning btn-sm float-right">
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
<a href="{{ package.get_url('packages.game_support') }}" class="btn btn-warning btn-sm float-right">
<i class="fas fa-pen"></i>
</a>
{% endif %}
@ -570,7 +570,7 @@
{% endfor %}
{% 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 class="btn btn-sm btn-link p-0" type="submit" value="{{ _('Remove myself') }}" />
</form>
@ -586,25 +586,25 @@
</dl>
<h3>
{% if package.checkPerm(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>
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
<a class="btn btn-primary btn-sm float-right" href="{{ package.get_url("packages.create_release") }}"><i class="fas fa-plus"></i></a>
{% endif %}
{{ _("Releases") }}
</h3>
<div class="list-group">
{% 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) }}
{% else %}
{{ render_releases_download(releases, package, current_user) }}
{% 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") }}
</a>
</div>
<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">
<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>
@ -623,11 +623,11 @@
{{ _("Report") }}
</a>
{% 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 %}
|
{% endif %}
<a href="{{ package.getURL('packages.audit') }}">
<a href="{{ package.get_url('packages.audit') }}">
{{ _("See audit log") }}
</a>
{% endif %}

@ -15,7 +15,7 @@
<div class="card-body">
<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" />
</div>
</form>

@ -15,7 +15,7 @@
<div class="card-body">
<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" />
</div>
</form>

@ -20,7 +20,7 @@
<div class="row mt-0 mb-4 comments mx-0">
<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 class="col">
<div class="card">

@ -18,7 +18,7 @@
<li class="row my-2 mx-0">
<div class="col-md-1 p-1">
<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>
</div>
<div class="col pr-0">
@ -37,12 +37,12 @@
{% endif %}
{% 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 }}
</a>
{% else %}
<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) }}
</a>
{% endif %}

@ -22,32 +22,32 @@
{%- endblock %}
{% block headextra %}
<meta name="og:image" content="{{ thread.author.getProfilePicURL() }}"/>
<meta name="og:image" content="{{ thread.author.get_profile_pic_url() }}"/>
{% endblock %}
{% block content %}
{% if current_user.is_authenticated %}
{% 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="submit" class="btn btn-primary" value="{{ _('Unsubscribe') }}" />
</form>
{% 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="submit" class="btn btn-primary" value="{{ _('Subscribe') }}" />
</form>
{% 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>
{% endif %}
{% if thread.review and thread.review.checkPerm(current_user, "DELETE_REVIEW") and current_user.username != thread.review.author.username %}
<form method="post" action="{{ thread.review.getDeleteURL() }}" class="float-right mr-2">
{% 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.get_delete_url() }}" class="float-right mr-2">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="submit" class="btn btn-danger" value="{{ _('Convert to Thread') }}" />
</form>
{% endif %}
{% if thread.checkPerm(current_user, "LOCK_THREAD") %}
{% if thread.check_perm(current_user, "LOCK_THREAD") %}
{% if thread.locked %}
<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() }}" />
@ -64,7 +64,7 @@
{% if current_user == thread.author and thread.review %}
<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>
{{ _("Edit Review") }}
</a>
@ -85,7 +85,7 @@
{% if thread.package %}
<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>
{% endif %}
@ -103,7 +103,7 @@
</span>
{% for viewer in thread.get_visible_to() %}
<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>
{% endfor %}
<a href="{{ url_for('users.list_all') }}" title="{{ _('Plus approvers and editors') }}">

@ -17,8 +17,8 @@
</h3>
<ul class="card-body d-flex p-0 flex-row flex-wrap justify-content-start align-content-start p-4">
{% for s in screenshots %}
<li class="packagetile flex-fill"><a href="{{ s.getEditURL() }}"
style="background-image: url({{ s.getThumbnailURL(3) }});">
<li class="packagetile flex-fill"><a href="{{ s.get_edit_url() }}"
style="background-image: url({{ s.get_thumb_url(3) }});">
<div class="packagegridscrub"></div>
<div class="packagegridinfo">
<h3>
@ -46,7 +46,7 @@
<h3 class="card-header">{{ _("Packages") }}</h3>
<div class="list-group list-group-flush">
{% 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 }}">
<small>
{{ p.created_at | timedelta }} ago
@ -79,9 +79,9 @@
{% if r.task_id %}
<span class="mr-2 badge badge-warning">{{ _("Importing") }}</span>
{% endif %}
<a href="{{ r.getEditURL() }}">{{ r.title }}</a>
<a href="{{ r.get_edit_url() }}">{{ r.title }}</a>
on
<a href="{{ r.package.getURL("packages.view") }}">
<a href="{{ r.package.get_url("packages.view") }}">
{{ _("%(title)s by %(display_name)s",
title=r.package.title, display_name=r.package.author.display_name) }}
</a>
@ -107,7 +107,7 @@
<h3 class="card-header">{{ _("License Needed") }}</h3>
<div class="list-group list-group-flush">
{% 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 }}">
<small>
{{ p.created_at | timedelta }} ago
@ -164,7 +164,7 @@
<h3 class="card-header">WIP Packages</h3>
<div class="list-group list-group-flush" style="max-height: 300px; overflow: hidden auto;">
{% 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 }}">
<small>
{{ p.created_at | timedelta }} ago

@ -22,7 +22,7 @@
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -41,7 +41,7 @@
{% if supported_games %}
{% for support in supported_games %}
<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=support.game.title, display_name=support.game.author.display_name) }}
</a>
@ -53,8 +53,8 @@
{% endif %}
</div>
<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-secondary" href="{{ package.getURL('packages.view') }}">Package</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.get_url('packages.view') }}">Package</a>
</div>
</div>
</div>

@ -42,15 +42,15 @@
{% for package in packages %}
<tr>
<td>
<a href="{{ package.getURL("packages.view") }}">
<a href="{{ package.get_url("packages.view") }}">
{{ package.title }}
</a>
by {{ package.author.display_name }}
</td>
<td class="text-center">
{% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
<a class="btn btn-link btn-sm py-0" href="{{ package.getURL("packages.create_edit") }}">
{% if package.check_perm(current_user, "EDIT_PACKAGE") %}
<a class="btn btn-link btn-sm py-0" href="{{ package.get_url("packages.create_edit") }}">
<i class="fas fa-pen"></i>
</a>
{% endif %}

@ -18,13 +18,13 @@
<h2>{{ _("Unapproved Packages Needing Action") }}</h2>
<div class="list-group mt-3 mb-5">
{% 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="col-sm-2 text-muted">
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -80,11 +80,11 @@
{% endif %}
<div class="list-group mt-3 mb-5">
{% 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
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -100,11 +100,11 @@
<h2 id="missing-screenshots">{{ _("Missing Screenshots") }}</h2>
<div class="list-group mt-3 mb-5">
{% 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
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -138,13 +138,13 @@
{% endif %}
<div class="list-group mt-3 mb-5">
{% 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="col-sm-3 text-muted" style="min-width: 200px;">
<img
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}
@ -183,11 +183,11 @@
</p>
<div class="list-group mt-3 mb-5">
{% 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
class="img-fluid"
style="max-height: 22px; max-width: 22px;"
src="{{ package.getThumbnailOrPlaceholder() }}" />
src="{{ package.get_thumb_or_placeholder() }}" />
<span class="pl-2">
{{ package.title }}

@ -31,7 +31,7 @@
<a class="list-group-item list-group-item-action" href="{{ url_for('users.profile', username=user.username) }}">
<div class="row">
<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 %}
<i class="fas fa-user-cog mr-2"></i>
{% elif user.rank == user.rank.MODERATOR %}
@ -46,7 +46,7 @@
<i class="fas fa-user mr-2"></i>
{% endif %}
{{ user.rank.getTitle() }}
{{ user.rank.get_title() }}
</div>
<span class="col-sm {{ user.rank }}">

@ -15,14 +15,14 @@
<form action="" method="POST" class="form" role="form">
{{ 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.display_name, tabindex=230) }}
{{ render_field(form.forums_username, tabindex=230) }}
{{ render_field_prefix(form.github_username, tabindex=230) }}
{% endif %}
{% if user.checkPerm(current_user, "CHANGE_RANK") %}
{% if user.check_perm(current_user, "CHANGE_RANK") %}
{{ render_field(form.rank, tabindex=250) }}
{% endif %}

@ -8,7 +8,7 @@
<article class="row mb-5">
<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 class="col">
{% if user.can_see_edit_profile(current_user) %}
@ -57,7 +57,7 @@
<span class="btn">
<i class="fas fa-user"></i>
<span class="count">
{{ user.rank.getTitle() }}
{{ user.rank.get_title() }}
</span>
</span>
@ -195,7 +195,7 @@
</div>
{% 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"
href="{{ url_for('packages.create_edit', author=user.username) }}">
<i class="fas fa-plus mr-1"></i>

@ -15,7 +15,7 @@
{% elif user.email %}
<a href="https://en.gravatar.com/">
{% 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 %}
</a>
{% endif %}
@ -42,11 +42,11 @@
<form action="" method="POST" class="form" role="form">
{{ 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")) }}
{% 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.donate_url, tabindex=233) }}
{% endif %}

@ -7,7 +7,7 @@
<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="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 class="col m-0 p-0 pl-2">
{{ user.display_name }}

@ -47,13 +47,13 @@
</tr>
{% for type in types %}
<tr>
<td>{{ type.getTitle() }}</td>
<td>{{ type.get_title() }}</td>
<td>{{ type.get_description() }}</td>
<td style="text-align: center;">
{{ render_checkbox_field(form["pref_" + type.toName()]) }}
{{ render_checkbox_field(form["pref_" + type.to_name()]) }}
</td>
<td style="text-align: center;">
{{ render_checkbox_field(form["pref_" + type.toName() + "_digest"]) }}
{{ render_checkbox_field(form["pref_" + type.to_name() + "_digest"]) }}
</td>
</tr>
{% endfor %}

@ -20,10 +20,10 @@
<div class="col-sm-2 text-muted">
<img
class="img-fluid"
src="{{ match.package.getThumbnailOrPlaceholder() }}" />
src="{{ match.package.get_thumb_or_placeholder() }}" />
<div class="mt-2">
<a href="{{ match.package.getURL('packages.view') }}">
<a href="{{ match.package.get_url('packages.view') }}">
{{ match.package.title }}
</a>
by {{ match.package.author.display_name }}
@ -33,7 +33,7 @@
{{ match.lines.split("\n") | select | list | count }} match(es)
</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
</a>
</div>

@ -133,7 +133,7 @@ def post_bot_message(package: Package, title: str, message: str):
db.session.add(reply)
addNotification(thread.watchers, system_user, NotificationType.BOT,
title, thread.getViewURL(), thread.package)
title, thread.get_view_url(), thread.package)
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
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`.
```bash
if not package.checkPerm(current_user, Permission.EDIT_PACKAGE):
if not package.check_perm(current_user, Permission.EDIT_PACKAGE):
abort(403)
```