mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 22:12:24 +01:00
Use snake_case for method names
This commit is contained in:
parent
16f93b3e13
commit
45ed12ddf0
@ -129,13 +129,13 @@ def check_for_ban():
|
||||
models.db.session.commit()
|
||||
|
||||
|
||||
from .utils import clearNotifications, is_safe_url, create_session
|
||||
from .utils import clear_notifications, is_safe_url, create_session
|
||||
|
||||
|
||||
@app.before_request
|
||||
def check_for_notifications():
|
||||
if current_user.is_authenticated:
|
||||
clearNotifications(request.path)
|
||||
clear_notifications(request.path)
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
|
@ -25,9 +25,9 @@ from sqlalchemy import or_, and_
|
||||
from app.models import PackageRelease, db, Package, PackageState, PackageScreenshot, MetaPackage, User, \
|
||||
NotificationType, PackageUpdateConfig, License, UserRank, PackageType
|
||||
from app.tasks.emails import send_pending_digests
|
||||
from app.tasks.forumtasks import importTopicList, checkAllForumAccounts
|
||||
from app.tasks.importtasks import importRepoScreenshot, checkZipRelease, check_for_updates, updateAllGameSupport
|
||||
from app.utils import addNotification, get_system_user
|
||||
from app.tasks.forumtasks import import_topic_list, check_all_forum_accounts
|
||||
from app.tasks.importtasks import import_repo_screenshot, check_zip_release, check_for_updates, update_all_game_support
|
||||
from app.utils import add_notification, get_system_user
|
||||
|
||||
actions = {}
|
||||
|
||||
@ -54,13 +54,13 @@ def del_stuck_releases():
|
||||
|
||||
@action("Import forum topic list")
|
||||
def import_topic_list():
|
||||
task = importTopicList.delay()
|
||||
task = import_topic_list.delay()
|
||||
return redirect(url_for("tasks.check", id=task.id, r=url_for("todo.topics")))
|
||||
|
||||
|
||||
@action("Check all forum accounts")
|
||||
def check_all_forum_accounts():
|
||||
task = checkAllForumAccounts.delay()
|
||||
task = check_all_forum_accounts.delay()
|
||||
return redirect(url_for("tasks.check", id=task.id, r=url_for("admin.admin_page")))
|
||||
|
||||
|
||||
@ -142,9 +142,9 @@ def remind_wip():
|
||||
packages_list = _package_list(packages)
|
||||
havent = "haven't" if len(packages) > 1 else "hasn't"
|
||||
|
||||
addNotification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
add_notification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
f"Did you forget? {packages_list} {havent} been submitted for review yet",
|
||||
url_for('todo.view_user', username=user.username))
|
||||
url_for('todo.view_user', username=user.username))
|
||||
db.session.commit()
|
||||
|
||||
|
||||
@ -162,9 +162,9 @@ def remind_outdated():
|
||||
packages = [pkg[0] for pkg in packages]
|
||||
packages_list = _package_list(packages)
|
||||
|
||||
addNotification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
add_notification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
f"The following packages may be outdated: {packages_list}",
|
||||
url_for('todo.view_user', username=user.username))
|
||||
url_for('todo.view_user', username=user.username))
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -241,9 +241,9 @@ def remind_video_url():
|
||||
packages = [pkg[0] for pkg in packages]
|
||||
packages_list = _package_list(packages)
|
||||
|
||||
addNotification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
add_notification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
f"You should add a video to {packages_list}",
|
||||
url_for('users.profile', username=user.username))
|
||||
url_for('users.profile', username=user.username))
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -270,9 +270,9 @@ def remind_missing_game_support():
|
||||
packages = [pkg[0] for pkg in packages]
|
||||
packages_list = _package_list(packages)
|
||||
|
||||
addNotification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
add_notification(user, system_user, NotificationType.PACKAGE_APPROVAL,
|
||||
f"You need to confirm whether the following packages support all games: {packages_list}",
|
||||
url_for('todo.all_game_support', username=user.username))
|
||||
url_for('todo.all_game_support', username=user.username))
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -280,7 +280,7 @@ def remind_missing_game_support():
|
||||
@action("Detect game support")
|
||||
def detect_game_support():
|
||||
task_id = uuid()
|
||||
updateAllGameSupport.apply_async((), task_id=task_id)
|
||||
update_all_game_support.apply_async((), task_id=task_id)
|
||||
return redirect(url_for("tasks.check", id=task_id, r=url_for("admin.admin_page")))
|
||||
|
||||
|
||||
@ -308,7 +308,7 @@ def check_releases():
|
||||
|
||||
tasks = []
|
||||
for release in releases:
|
||||
tasks.append(checkZipRelease.s(release.id, release.file_path))
|
||||
tasks.append(check_zip_release.s(release.id, release.file_path))
|
||||
|
||||
result = group(tasks).apply_async()
|
||||
|
||||
@ -325,7 +325,7 @@ def reimport_packages():
|
||||
for package in Package.query.filter(Package.state != PackageState.DELETED).all():
|
||||
release = package.releases.first()
|
||||
if release:
|
||||
tasks.append(checkZipRelease.s(release.id, release.file_path))
|
||||
tasks.append(check_zip_release.s(release.id, release.file_path))
|
||||
|
||||
result = group(tasks).apply_async()
|
||||
|
||||
@ -344,6 +344,6 @@ def import_screenshots():
|
||||
.filter(PackageScreenshot.id == None) \
|
||||
.all()
|
||||
for package in packages:
|
||||
importRepoScreenshot.delay(package.id)
|
||||
import_repo_screenshot.delay(package.id)
|
||||
|
||||
return redirect(url_for("admin.admin_page"))
|
||||
|
@ -19,7 +19,7 @@ from flask_login import current_user, login_user
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField
|
||||
from wtforms.validators import InputRequired, Length
|
||||
from app.utils import rank_required, addAuditLog, addNotification, get_system_user
|
||||
from app.utils import rank_required, add_audit_log, add_notification, get_system_user
|
||||
from . import bp
|
||||
from .actions import actions
|
||||
from app.models import UserRank, Package, db, PackageState, User, AuditSeverity, NotificationType
|
||||
@ -75,11 +75,11 @@ class SendNotificationForm(FlaskForm):
|
||||
def send_bulk_notification():
|
||||
form = SendNotificationForm(request.form)
|
||||
if form.validate_on_submit():
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user,
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user,
|
||||
"Sent bulk notification", url_for("admin.admin_page"), None, form.title.data)
|
||||
|
||||
users = User.query.filter(User.rank >= UserRank.NEW_MEMBER).all()
|
||||
addNotification(users, get_system_user(), NotificationType.OTHER, form.title.data, form.url.data, None)
|
||||
add_notification(users, get_system_user(), NotificationType.OTHER, form.title.data, form.url.data, None)
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for("admin.admin_page"))
|
||||
@ -105,8 +105,8 @@ def restore():
|
||||
else:
|
||||
package.state = target
|
||||
|
||||
addAuditLog(AuditSeverity.EDITOR, current_user, f"Restored package to state {target.value}",
|
||||
package.get_url("packages.view"), package)
|
||||
add_audit_log(AuditSeverity.EDITOR, current_user, f"Restored package to state {target.value}",
|
||||
package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
return redirect(package.get_url("packages.view"))
|
||||
|
@ -22,7 +22,7 @@ from wtforms.validators import InputRequired, Length
|
||||
|
||||
from app.markdown import render_markdown
|
||||
from app.tasks.emails import send_user_email, send_bulk_email as task_send_bulk
|
||||
from app.utils import rank_required, addAuditLog
|
||||
from app.utils import rank_required, add_audit_log
|
||||
from . import bp
|
||||
from app.models import UserRank, User, AuditSeverity
|
||||
|
||||
@ -49,7 +49,7 @@ def send_single_email():
|
||||
|
||||
form = SendEmailForm(request.form)
|
||||
if form.validate_on_submit():
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user,
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user,
|
||||
"Sent email to {}".format(user.display_name), url_for("users.profile", username=username))
|
||||
|
||||
text = form.text.data
|
||||
@ -65,7 +65,7 @@ def send_single_email():
|
||||
def send_bulk_email():
|
||||
form = SendEmailForm(request.form)
|
||||
if form.validate_on_submit():
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user,
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user,
|
||||
"Sent bulk email", url_for("admin.admin_page"), None, form.text.data)
|
||||
|
||||
text = form.text.data
|
||||
|
@ -21,7 +21,7 @@ from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, BooleanField, SubmitField, URLField
|
||||
from wtforms.validators import InputRequired, Length, Optional
|
||||
|
||||
from app.utils import rank_required, nonEmptyOrNone, addAuditLog
|
||||
from app.utils import rank_required, nonempty_or_none, add_audit_log
|
||||
from . import bp
|
||||
from app.models import UserRank, License, db, AuditSeverity
|
||||
|
||||
@ -35,7 +35,7 @@ def license_list():
|
||||
class LicenseForm(FlaskForm):
|
||||
name = StringField("Name", [InputRequired(), Length(3, 100)])
|
||||
is_foss = BooleanField("Is FOSS")
|
||||
url = URLField("URL", [Optional()], filters=[nonEmptyOrNone])
|
||||
url = URLField("URL", [Optional()], filters=[nonempty_or_none])
|
||||
submit = SubmitField("Save")
|
||||
|
||||
|
||||
@ -58,13 +58,13 @@ def create_edit_license(name=None):
|
||||
db.session.add(license)
|
||||
flash("Created license " + form.name.data, "success")
|
||||
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, f"Created license {license.name}",
|
||||
url_for("admin.license_list"))
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, f"Created license {license.name}",
|
||||
url_for("admin.license_list"))
|
||||
else:
|
||||
flash("Updated license " + form.name.data, "success")
|
||||
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, f"Edited license {license.name}",
|
||||
url_for("admin.license_list"))
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, f"Edited license {license.name}",
|
||||
url_for("admin.license_list"))
|
||||
|
||||
form.populate_obj(license)
|
||||
db.session.commit()
|
||||
|
@ -23,7 +23,7 @@ from wtforms.validators import InputRequired, Length, Optional, Regexp
|
||||
|
||||
from . import bp
|
||||
from app.models import Permission, Tag, db, AuditSeverity
|
||||
from app.utils import addAuditLog
|
||||
from app.utils import add_audit_log
|
||||
|
||||
|
||||
@bp.route("/tags/")
|
||||
@ -72,13 +72,13 @@ def create_edit_tag(name=None):
|
||||
tag.is_protected = form.is_protected.data
|
||||
db.session.add(tag)
|
||||
|
||||
addAuditLog(AuditSeverity.EDITOR, current_user, f"Created tag {tag.name}",
|
||||
url_for("admin.create_edit_tag", name=tag.name))
|
||||
add_audit_log(AuditSeverity.EDITOR, current_user, f"Created tag {tag.name}",
|
||||
url_for("admin.create_edit_tag", name=tag.name))
|
||||
else:
|
||||
form.populate_obj(tag)
|
||||
|
||||
addAuditLog(AuditSeverity.EDITOR, current_user, f"Edited tag {tag.name}",
|
||||
url_for("admin.create_edit_tag", name=tag.name))
|
||||
add_audit_log(AuditSeverity.EDITOR, current_user, f"Edited tag {tag.name}",
|
||||
url_for("admin.create_edit_tag", name=tag.name))
|
||||
|
||||
db.session.commit()
|
||||
|
||||
|
@ -21,7 +21,7 @@ from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, IntegerField, SubmitField
|
||||
from wtforms.validators import InputRequired, Length
|
||||
|
||||
from app.utils import rank_required, addAuditLog
|
||||
from app.utils import rank_required, add_audit_log
|
||||
from . import bp
|
||||
from app.models import UserRank, MinetestRelease, db, AuditSeverity
|
||||
|
||||
@ -56,13 +56,13 @@ def create_edit_version(name=None):
|
||||
db.session.add(version)
|
||||
flash("Created version " + form.name.data, "success")
|
||||
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, f"Created version {version.name}",
|
||||
url_for("admin.license_list"))
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, f"Created version {version.name}",
|
||||
url_for("admin.license_list"))
|
||||
else:
|
||||
flash("Updated version " + form.name.data, "success")
|
||||
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, f"Edited version {version.name}",
|
||||
url_for("admin.version_list"))
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, f"Edited version {version.name}",
|
||||
url_for("admin.version_list"))
|
||||
|
||||
form.populate_obj(version)
|
||||
db.session.commit()
|
||||
|
@ -30,7 +30,7 @@ from app.markdown import render_markdown
|
||||
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, \
|
||||
MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread
|
||||
from app.querybuilder import QueryBuilder
|
||||
from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, isYes, get_request_date
|
||||
from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, is_yes, get_request_date
|
||||
from . import bp
|
||||
from .auth import is_api_authd
|
||||
from .support import error, api_create_vcs_release, api_create_zip_release, api_create_screenshot, \
|
||||
@ -66,19 +66,19 @@ def cached(max_age: int):
|
||||
@cached(300)
|
||||
def packages():
|
||||
qb = QueryBuilder(request.args)
|
||||
query = qb.buildPackageQuery()
|
||||
query = qb.build_package_query()
|
||||
|
||||
if request.args.get("fmt") == "keys":
|
||||
return jsonify([pkg.as_key_dict() for pkg in query.all()])
|
||||
|
||||
pkgs = qb.convertToDictionary(query.all())
|
||||
pkgs = qb.convert_to_dictionary(query.all())
|
||||
if "engine_version" in request.args or "protocol_version" in request.args:
|
||||
pkgs = [pkg for pkg in pkgs if pkg.get("release")]
|
||||
|
||||
# Promote featured packages
|
||||
if "sort" not in request.args and "order" not in request.args and "q" not in request.args:
|
||||
featured_lut = set()
|
||||
featured = qb.convertToDictionary(query.filter(Package.tags.any(name="featured")).all())
|
||||
featured = qb.convert_to_dictionary(query.filter(Package.tags.any(name="featured")).all())
|
||||
for pkg in featured:
|
||||
featured_lut.add(f"{pkg['author']}/{pkg['name']}")
|
||||
pkg["short_description"] = "Featured. " + pkg["short_description"]
|
||||
@ -101,7 +101,7 @@ def package_view(package):
|
||||
@cors_allowed
|
||||
def package_hypertext(package):
|
||||
formspec_version = request.args["formspec_version"]
|
||||
include_images = isYes(request.args.get("include_images", "true"))
|
||||
include_images = is_yes(request.args.get("include_images", "true"))
|
||||
html = render_markdown(package.desc)
|
||||
return jsonify(html_to_minetest(html, formspec_version, include_images))
|
||||
|
||||
@ -174,7 +174,7 @@ def package_dependencies(package):
|
||||
@cors_allowed
|
||||
def topics():
|
||||
qb = QueryBuilder(request.args)
|
||||
query = qb.buildTopicQuery(show_added=True)
|
||||
query = qb.build_topic_query(show_added=True)
|
||||
return jsonify([t.as_dict() for t in query.all()])
|
||||
|
||||
|
||||
@ -346,7 +346,7 @@ def create_screenshot(token: APIToken, package: Package):
|
||||
if file is None:
|
||||
error(400, "Missing 'file' in multipart body")
|
||||
|
||||
return api_create_screenshot(token, package, data["title"], file, isYes(data.get("is_cover_image")))
|
||||
return api_create_screenshot(token, package, data["title"], file, is_yes(data.get("is_cover_image")))
|
||||
|
||||
|
||||
@bp.route("/api/packages/<author>/<name>/screenshots/<int:id>/")
|
||||
@ -454,7 +454,7 @@ def list_all_reviews():
|
||||
query = query.filter(PackageReview.author.has(User.username == request.args.get("author")))
|
||||
|
||||
if request.args.get("is_positive"):
|
||||
if isYes(request.args.get("is_positive")):
|
||||
if is_yes(request.args.get("is_positive")):
|
||||
query = query.filter(PackageReview.rating > 3)
|
||||
else:
|
||||
query = query.filter(PackageReview.rating <= 3)
|
||||
@ -499,7 +499,7 @@ def all_package_stats():
|
||||
@cached(300)
|
||||
def package_scores():
|
||||
qb = QueryBuilder(request.args)
|
||||
query = qb.buildPackageQuery()
|
||||
query = qb.build_package_query()
|
||||
|
||||
pkgs = [package.as_score_dict() for package in query.all()]
|
||||
return jsonify(pkgs)
|
||||
@ -601,7 +601,7 @@ def versions():
|
||||
@cors_allowed
|
||||
def all_deps():
|
||||
qb = QueryBuilder(request.args)
|
||||
query = qb.buildPackageQuery()
|
||||
query = qb.build_package_query()
|
||||
|
||||
def format_pkg(pkg: Package):
|
||||
return {
|
||||
|
@ -24,7 +24,7 @@ from wtforms.validators import InputRequired, Length
|
||||
from wtforms_sqlalchemy.fields import QuerySelectField
|
||||
|
||||
from app.models import db, User, APIToken, Permission
|
||||
from app.utils import randomString
|
||||
from app.utils import random_string
|
||||
from . import bp
|
||||
from ..users.settings import get_setting_tabs
|
||||
|
||||
@ -87,7 +87,7 @@ def create_edit_token(username, id=None):
|
||||
token = APIToken()
|
||||
db.session.add(token)
|
||||
token.owner = user
|
||||
token.access_token = randomString(32)
|
||||
token.access_token = random_string(32)
|
||||
|
||||
form.populate_obj(token)
|
||||
db.session.commit()
|
||||
@ -117,7 +117,7 @@ def reset_token(username, id):
|
||||
elif token.owner != user:
|
||||
abort(403)
|
||||
|
||||
token.access_token = randomString(32)
|
||||
token.access_token = random_string(32)
|
||||
|
||||
db.session.commit() # save
|
||||
|
||||
|
@ -24,7 +24,7 @@ from flask_login import current_user
|
||||
from sqlalchemy import func, or_, and_
|
||||
from app import github, csrf
|
||||
from app.models import db, User, APIToken, Package, Permission, AuditSeverity, PackageState
|
||||
from app.utils import abs_url_for, addAuditLog, login_user_set_active
|
||||
from app.utils import abs_url_for, add_audit_log, login_user_set_active
|
||||
from app.blueprints.api.support import error, api_create_vcs_release
|
||||
import hmac, requests
|
||||
|
||||
@ -76,8 +76,8 @@ def callback(oauth_token):
|
||||
flash(gettext("Authorization failed [err=gh-login-failed]"), "danger")
|
||||
return redirect(url_for("users.login"))
|
||||
|
||||
addAuditLog(AuditSeverity.USER, userByGithub, "Logged in using GitHub OAuth",
|
||||
url_for("users.profile", username=userByGithub.username))
|
||||
add_audit_log(AuditSeverity.USER, userByGithub, "Logged in using GitHub OAuth",
|
||||
url_for("users.profile", username=userByGithub.username))
|
||||
db.session.commit()
|
||||
return ret
|
||||
|
||||
|
@ -34,7 +34,7 @@ from app.logic.LogicError import LogicError
|
||||
from app.logic.packages import do_edit_package
|
||||
from app.querybuilder import QueryBuilder
|
||||
from app.rediscache import has_key, set_key
|
||||
from app.tasks.importtasks import importRepoScreenshot, checkZipRelease
|
||||
from app.tasks.importtasks import import_repo_screenshot, check_zip_release
|
||||
from app.tasks.webhooktasks import post_discord_webhook
|
||||
from app.logic.game_support import GameSupportResolver
|
||||
|
||||
@ -43,14 +43,14 @@ from app.models import Package, Tag, db, User, Tags, PackageState, Permission, P
|
||||
Dependency, Thread, UserRank, PackageReview, PackageDevState, ContentWarning, License, AuditSeverity, \
|
||||
PackageScreenshot, NotificationType, AuditLogEntry, PackageAlias, PackageProvides, PackageGameSupport, \
|
||||
PackageDailyStats
|
||||
from app.utils import is_user_bot, get_int_or_abort, is_package_page, abs_url_for, addAuditLog, getPackageByInfo, \
|
||||
addNotification, get_system_user, rank_required, get_games_from_csv, get_daterange_options
|
||||
from app.utils import is_user_bot, get_int_or_abort, is_package_page, abs_url_for, add_audit_log, get_package_by_info, \
|
||||
add_notification, get_system_user, rank_required, get_games_from_csv, get_daterange_options
|
||||
|
||||
|
||||
@bp.route("/packages/")
|
||||
def list_all():
|
||||
qb = QueryBuilder(request.args)
|
||||
query = qb.buildPackageQuery()
|
||||
query = qb.build_package_query()
|
||||
title = qb.title
|
||||
|
||||
query = query.options(
|
||||
@ -78,7 +78,7 @@ def list_all():
|
||||
if package:
|
||||
return redirect(package.get_url("packages.view"))
|
||||
|
||||
topic = qb.buildTopicQuery().first()
|
||||
topic = qb.build_topic_query().first()
|
||||
if qb.search and topic:
|
||||
return redirect("https://forum.minetest.net/viewtopic.php?t=" + str(topic.topic_id))
|
||||
|
||||
@ -100,12 +100,12 @@ def list_all():
|
||||
topics = None
|
||||
if qb.search and not query.has_next:
|
||||
qb.show_discarded = True
|
||||
topics = qb.buildTopicQuery().all()
|
||||
topics = qb.build_topic_query().all()
|
||||
|
||||
tags_query = db.session.query(func.count(Tags.c.tag_id), Tag) \
|
||||
.select_from(Tag).join(Tags).join(Package).filter(Package.state==PackageState.APPROVED) \
|
||||
.group_by(Tag.id).order_by(db.asc(Tag.title))
|
||||
tags = qb.filterPackageQuery(tags_query).all()
|
||||
tags = qb.filter_package_query(tags_query).all()
|
||||
|
||||
selected_tags = set(qb.tags)
|
||||
|
||||
@ -115,7 +115,7 @@ def list_all():
|
||||
authors=authors, packages_count=query.total, topics=topics, noindex=qb.noindex)
|
||||
|
||||
|
||||
def getReleases(package):
|
||||
def get_releases(package):
|
||||
if package.check_perm(current_user, Permission.MAKE_RELEASE):
|
||||
return package.releases.limit(5)
|
||||
else:
|
||||
@ -158,7 +158,7 @@ def view(package):
|
||||
Dependency.meta_package_id.in_([p.id for p in package.provides]))) \
|
||||
.order_by(db.desc(Package.score)).limit(6).all()
|
||||
|
||||
releases = getReleases(package)
|
||||
releases = get_releases(package)
|
||||
|
||||
review_thread = package.review_thread
|
||||
if review_thread is not None and not review_thread.check_perm(current_user, Permission.SEE_THREAD):
|
||||
@ -185,7 +185,7 @@ def view(package):
|
||||
threads = Thread.query.filter_by(package_id=package.id, review_id=None)
|
||||
if not current_user.is_authenticated:
|
||||
threads = threads.filter_by(private=False)
|
||||
elif not current_user.rank.atLeast(UserRank.APPROVER) and not current_user == package.author:
|
||||
elif not current_user.rank.at_least(UserRank.APPROVER) and not current_user == package.author:
|
||||
threads = threads.filter(or_(Thread.private == False, Thread.author == current_user))
|
||||
|
||||
has_review = current_user.is_authenticated and \
|
||||
@ -310,10 +310,10 @@ 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.get_url("packages.view"), package)
|
||||
add_audit_log(AuditSeverity.NORMAL, current_user, msg, package.get_url("packages.view"), package)
|
||||
|
||||
if wasNew and package.repo is not None:
|
||||
importRepoScreenshot.delay(package.id)
|
||||
import_repo_screenshot.delay(package.id)
|
||||
|
||||
next_url = package.get_url("packages.view")
|
||||
if wasNew and ("WTFPL" in package.license.name or "WTFPL" in package.media_license.name):
|
||||
@ -347,7 +347,7 @@ def create_edit(author=None, name=None):
|
||||
return redirect(url_for("packages.create_edit"))
|
||||
|
||||
else:
|
||||
package = getPackageByInfo(author, name)
|
||||
package = get_package_by_info(author, name)
|
||||
if package is None:
|
||||
abort(404)
|
||||
if not package.check_perm(current_user, Permission.EDIT_PACKAGE):
|
||||
@ -422,9 +422,9 @@ def move_to_state(package):
|
||||
"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.get_url("packages.view"), package)
|
||||
add_notification(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.get_url("packages.view"), package)
|
||||
add_audit_log(severity, current_user, msg, package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -457,8 +457,8 @@ def remove(package):
|
||||
|
||||
url = url_for("users.profile", username=package.author.username)
|
||||
msg = "Deleted {}, reason={}".format(package.title, reason)
|
||||
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg, url, package)
|
||||
addAuditLog(AuditSeverity.EDITOR, current_user, msg, url, package)
|
||||
add_notification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg, url, package)
|
||||
add_audit_log(AuditSeverity.EDITOR, current_user, msg, url, package)
|
||||
db.session.commit()
|
||||
|
||||
flash(gettext("Deleted package"), "success")
|
||||
@ -472,8 +472,8 @@ def remove(package):
|
||||
package.state = PackageState.WIP
|
||||
|
||||
msg = "Unapproved {}, reason={}".format(package.title, reason)
|
||||
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)
|
||||
add_notification(package.maintainers, current_user, NotificationType.PACKAGE_APPROVAL, msg, package.get_url("packages.view"), package)
|
||||
add_audit_log(AuditSeverity.EDITOR, current_user, msg, package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -512,12 +512,12 @@ def edit_maintainers(package):
|
||||
if not user in package.maintainers:
|
||||
if thread:
|
||||
thread.watchers.append(user)
|
||||
addNotification(user, current_user, NotificationType.MAINTAINER,
|
||||
add_notification(user, current_user, NotificationType.MAINTAINER,
|
||||
"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,
|
||||
add_notification(user, current_user, NotificationType.MAINTAINER,
|
||||
"Removed you as a maintainer of {}".format(package.title), package.get_url("packages.view"), package)
|
||||
|
||||
package.maintainers.clear()
|
||||
@ -526,9 +526,9 @@ def edit_maintainers(package):
|
||||
package.maintainers.append(package.author)
|
||||
|
||||
msg = "Edited {} maintainers".format(package.title)
|
||||
addNotification(package.author, current_user, NotificationType.MAINTAINER, msg, package.get_url("packages.view"), package)
|
||||
add_notification(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.get_url("packages.view"), package)
|
||||
add_audit_log(severity, current_user, msg, package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -553,7 +553,7 @@ def remove_self_maintainers(package):
|
||||
else:
|
||||
package.maintainers.remove(current_user)
|
||||
|
||||
addNotification(package.author, current_user, NotificationType.MAINTAINER,
|
||||
add_notification(package.author, current_user, NotificationType.MAINTAINER,
|
||||
"Removed themself as a maintainer of {}".format(package.title), package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
@ -715,7 +715,7 @@ def game_support(package):
|
||||
|
||||
package.supports_all_games = form.supports_all_games.data
|
||||
|
||||
addAuditLog(AuditSeverity.NORMAL, current_user, "Edited game support", package.get_url("packages.game_support"), package)
|
||||
add_audit_log(AuditSeverity.NORMAL, current_user, "Edited game support", package.get_url("packages.game_support"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -723,7 +723,7 @@ def game_support(package):
|
||||
release = package.releases.first()
|
||||
if release:
|
||||
task_id = uuid()
|
||||
checkZipRelease.apply_async((release.id, release.file_path), task_id=task_id)
|
||||
check_zip_release.apply_async((release.id, release.file_path), task_id=task_id)
|
||||
next_url = url_for("tasks.check", id=task_id, r=next_url)
|
||||
|
||||
return redirect(next_url)
|
||||
|
@ -27,7 +27,7 @@ from app.models import Package, db, User, PackageState, Permission, UserRank, Pa
|
||||
PackageRelease, PackageUpdateTrigger, PackageUpdateConfig
|
||||
from app.rediscache import has_key, set_key, make_download_key
|
||||
from app.tasks.importtasks import check_update_config
|
||||
from app.utils import is_user_bot, is_package_page, nonEmptyOrNone
|
||||
from app.utils import is_user_bot, is_package_page, nonempty_or_none
|
||||
from . import bp, get_package_tabs
|
||||
|
||||
|
||||
@ -263,7 +263,7 @@ def set_update_config(package, form):
|
||||
db.session.add(package.update_config)
|
||||
|
||||
form.populate_obj(package.update_config)
|
||||
package.update_config.ref = nonEmptyOrNone(form.ref.data)
|
||||
package.update_config.ref = nonempty_or_none(form.ref.data)
|
||||
package.update_config.make_release = form.action.data == "make_release"
|
||||
|
||||
if package.update_config.trigger == PackageUpdateTrigger.COMMIT:
|
||||
@ -349,7 +349,7 @@ def bulk_update_config(username=None):
|
||||
if not user:
|
||||
abort(404)
|
||||
|
||||
if current_user != user and not current_user.rank.atLeast(UserRank.EDITOR):
|
||||
if current_user != user and not current_user.rank.at_least(UserRank.EDITOR):
|
||||
abort(403)
|
||||
|
||||
form = PackageUpdateConfigFrom()
|
||||
|
@ -26,8 +26,8 @@ from wtforms.validators import InputRequired, Length
|
||||
from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank, \
|
||||
Permission, AuditSeverity, PackageState
|
||||
from app.tasks.webhooktasks import post_discord_webhook
|
||||
from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required, \
|
||||
addAuditLog, has_blocked_domains
|
||||
from app.utils import is_package_page, add_notification, get_int_or_abort, is_yes, is_safe_url, rank_required, \
|
||||
add_audit_log, has_blocked_domains
|
||||
from . import bp
|
||||
|
||||
|
||||
@ -123,8 +123,8 @@ def review(package):
|
||||
notif_msg = "Updated review '{}'".format(form.title.data)
|
||||
type = NotificationType.OTHER
|
||||
|
||||
addNotification(package.maintainers, current_user, type, notif_msg,
|
||||
url_for("threads.view", id=thread.id), package)
|
||||
add_notification(package.maintainers, current_user, type, notif_msg,
|
||||
url_for("threads.view", id=thread.id), package)
|
||||
|
||||
if was_new:
|
||||
post_discord_webhook.delay(thread.author.username,
|
||||
@ -163,11 +163,11 @@ def delete_review(package, reviewer):
|
||||
thread.review = None
|
||||
|
||||
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.get_view_url(), thread.package)
|
||||
add_audit_log(AuditSeverity.MODERATION if current_user.username != reviewer else AuditSeverity.NORMAL,
|
||||
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)
|
||||
add_notification(package.maintainers, current_user, NotificationType.OTHER, notif_msg, url_for("threads.view", id=thread.id), package)
|
||||
|
||||
db.session.delete(review)
|
||||
|
||||
@ -191,7 +191,7 @@ def handle_review_vote(package: Package, review_id: int):
|
||||
flash(gettext("You can't vote on your own reviews!"), "danger")
|
||||
return
|
||||
|
||||
is_positive = isYes(request.form["is_positive"])
|
||||
is_positive = is_yes(request.form["is_positive"])
|
||||
|
||||
vote = PackageReviewVote.query.filter_by(review=review, user=current_user).first()
|
||||
if vote is None:
|
||||
|
@ -25,7 +25,7 @@ from wtforms.validators import InputRequired, Length
|
||||
from app.models import User, UserRank
|
||||
from app.tasks.emails import send_user_email
|
||||
from app.tasks.webhooktasks import post_discord_webhook
|
||||
from app.utils import isNo, abs_url_samesite
|
||||
from app.utils import is_no, abs_url_samesite
|
||||
|
||||
bp = Blueprint("report", __name__)
|
||||
|
||||
@ -37,7 +37,7 @@ class ReportForm(FlaskForm):
|
||||
|
||||
@bp.route("/report/", methods=["GET", "POST"])
|
||||
def report():
|
||||
is_anon = not current_user.is_authenticated or not isNo(request.args.get("anon"))
|
||||
is_anon = not current_user.is_authenticated or not is_no(request.args.get("anon"))
|
||||
|
||||
url = request.args.get("url")
|
||||
if url:
|
||||
|
@ -20,8 +20,8 @@ from flask_login import login_required, current_user
|
||||
from app import csrf
|
||||
from app.models import UserRank
|
||||
from app.tasks import celery
|
||||
from app.tasks.importtasks import getMeta
|
||||
from app.utils import shouldReturnJson
|
||||
from app.tasks.importtasks import get_meta
|
||||
from app.utils import should_return_json
|
||||
|
||||
bp = Blueprint("tasks", __name__)
|
||||
|
||||
@ -33,7 +33,7 @@ def start_getmeta():
|
||||
from flask import request
|
||||
author = request.args.get("author")
|
||||
author = current_user.forums_username if author is None else author
|
||||
aresult = getMeta.delay(request.args.get("url"), author)
|
||||
aresult = get_meta.delay(request.args.get("url"), author)
|
||||
return jsonify({
|
||||
"poll_url": url_for("tasks.check", id=aresult.id),
|
||||
})
|
||||
@ -52,7 +52,7 @@ def check(id):
|
||||
'status': status,
|
||||
}
|
||||
|
||||
if current_user.is_authenticated and current_user.rank.atLeast(UserRank.ADMIN):
|
||||
if current_user.is_authenticated and current_user.rank.at_least(UserRank.ADMIN):
|
||||
info["error"] = str(traceback)
|
||||
elif str(result)[1:12] == "TaskError: ":
|
||||
info["error"] = str(result)[12:-1]
|
||||
@ -65,7 +65,7 @@ def check(id):
|
||||
'result': result,
|
||||
}
|
||||
|
||||
if shouldReturnJson():
|
||||
if should_return_json():
|
||||
return jsonify(info)
|
||||
else:
|
||||
r = request.args.get("r")
|
||||
|
@ -25,7 +25,7 @@ bp = Blueprint("threads", __name__)
|
||||
from flask_login import current_user, login_required
|
||||
from app.models import Package, db, User, Permission, Thread, UserRank, AuditSeverity, \
|
||||
NotificationType, ThreadReply
|
||||
from app.utils import addNotification, isYes, addAuditLog, get_system_user, rank_required, has_blocked_domains
|
||||
from app.utils import add_notification, is_yes, add_audit_log, get_system_user, rank_required, has_blocked_domains
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, TextAreaField, SubmitField, BooleanField
|
||||
from wtforms.validators import InputRequired, Length
|
||||
@ -99,7 +99,7 @@ def set_lock(id_):
|
||||
if thread is None or not thread.check_perm(current_user, Permission.LOCK_THREAD):
|
||||
abort(404)
|
||||
|
||||
thread.locked = isYes(request.args.get("lock"))
|
||||
thread.locked = is_yes(request.args.get("lock"))
|
||||
if thread.locked is None:
|
||||
abort(400)
|
||||
|
||||
@ -110,8 +110,8 @@ def set_lock(id_):
|
||||
msg = "Unlocked thread '{}'".format(thread.title)
|
||||
flash(gettext("Unlocked thread"), "success")
|
||||
|
||||
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)
|
||||
add_notification(thread.watchers, current_user, NotificationType.OTHER, msg, thread.get_view_url(), thread.package)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, msg, thread.get_view_url(), thread.package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -134,7 +134,7 @@ def delete_thread(id_):
|
||||
|
||||
db.session.delete(thread)
|
||||
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg, None, thread.package, summary)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, msg, None, thread.package, summary)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
@ -167,7 +167,7 @@ def delete_reply(id_):
|
||||
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.get_view_url(), thread.package, reply.comment)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, msg, thread.get_view_url(), thread.package, reply.comment)
|
||||
|
||||
db.session.delete(reply)
|
||||
db.session.commit()
|
||||
@ -206,8 +206,8 @@ 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.get_view_url(), thread.package)
|
||||
addAuditLog(severity, current_user, msg, thread.get_view_url(), thread.package, reply.comment)
|
||||
add_notification(reply.author, current_user, NotificationType.OTHER, msg, thread.get_view_url(), thread.package)
|
||||
add_audit_log(severity, current_user, msg, thread.get_view_url(), thread.package, reply.comment)
|
||||
|
||||
reply.comment = comment
|
||||
|
||||
@ -253,18 +253,18 @@ def view(id_):
|
||||
continue
|
||||
|
||||
msg = "Mentioned by {} in '{}'".format(current_user.display_name, thread.title)
|
||||
addNotification(mentioned, current_user, NotificationType.THREAD_REPLY,
|
||||
msg, thread.get_view_url(), thread.package)
|
||||
add_notification(mentioned, current_user, NotificationType.THREAD_REPLY,
|
||||
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.get_view_url(), thread.package)
|
||||
add_notification(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.get_view_url(), thread.package)
|
||||
add_notification(approvers, current_user, NotificationType.EDITOR_MISC, msg,
|
||||
thread.get_view_url(), thread.package)
|
||||
post_discord_webhook.delay(current_user.username,
|
||||
"Replied to bot messages: {}".format(thread.get_view_url(absolute=True)), True)
|
||||
|
||||
@ -294,7 +294,7 @@ def new():
|
||||
abort(404)
|
||||
|
||||
def_is_private = request.args.get("private") or False
|
||||
if package is None and not current_user.rank.atLeast(UserRank.APPROVER):
|
||||
if package is None and not current_user.rank.at_least(UserRank.APPROVER):
|
||||
abort(404)
|
||||
|
||||
allow_private_change = not package or package.approved
|
||||
@ -359,17 +359,17 @@ def new():
|
||||
continue
|
||||
|
||||
msg = "Mentioned by {} in new thread '{}'".format(current_user.display_name, thread.title)
|
||||
addNotification(mentioned, current_user, NotificationType.NEW_THREAD,
|
||||
msg, thread.get_view_url(), thread.package)
|
||||
add_notification(mentioned, current_user, NotificationType.NEW_THREAD,
|
||||
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.get_view_url(), package)
|
||||
add_notification(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.get_view_url(), package)
|
||||
add_notification(approvers, current_user, NotificationType.EDITOR_MISC, notif_msg, thread.get_view_url(), package)
|
||||
|
||||
if is_review_thread:
|
||||
post_discord_webhook.delay(current_user.username,
|
||||
|
@ -22,7 +22,7 @@ from sqlalchemy import or_
|
||||
from app.models import Package, PackageState, PackageScreenshot, PackageUpdateConfig, ForumTopic, db, \
|
||||
PackageRelease, Permission, UserRank, License, MetaPackage, Dependency, AuditLogEntry, Tag, MinetestRelease
|
||||
from app.querybuilder import QueryBuilder
|
||||
from app.utils import get_int_or_abort, isYes
|
||||
from app.utils import get_int_or_abort, is_yes
|
||||
from . import bp
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ def view_editor():
|
||||
|
||||
return render_template("todo/editor.html", current_tab="editor",
|
||||
packages=packages, wip_packages=wip_packages, releases=releases, screenshots=screenshots,
|
||||
canApproveNew=can_approve_new, canApproveRel=can_approve_rel, canApproveScn=can_approve_scn,
|
||||
can_approve_new=can_approve_new, can_approve_rel=can_approve_rel, can_approve_scn=can_approve_scn,
|
||||
license_needed=license_needed, total_packages=total_packages, total_to_tag=total_to_tag,
|
||||
unfulfilled_meta_packages=unfulfilled_meta_packages, audit_log=audit_log)
|
||||
|
||||
@ -94,8 +94,8 @@ def view_editor():
|
||||
@login_required
|
||||
def topics():
|
||||
qb = QueryBuilder(request.args)
|
||||
qb.setSortIfNone("date")
|
||||
query = qb.buildTopicQuery()
|
||||
qb.set_sort_if_none("date")
|
||||
query = qb.build_topic_query()
|
||||
|
||||
tmp_q = ForumTopic.query
|
||||
if not qb.show_discarded:
|
||||
@ -105,7 +105,7 @@ def topics():
|
||||
|
||||
page = get_int_or_abort(request.args.get("page"), 1)
|
||||
num = get_int_or_abort(request.args.get("n"), 100)
|
||||
if num > 100 and not current_user.rank.atLeast(UserRank.APPROVER):
|
||||
if num > 100 and not current_user.rank.at_least(UserRank.APPROVER):
|
||||
num = 100
|
||||
|
||||
query = query.paginate(page=page, per_page=num)
|
||||
@ -126,10 +126,10 @@ def topics():
|
||||
@login_required
|
||||
def tags():
|
||||
qb = QueryBuilder(request.args)
|
||||
qb.setSortIfNone("score", "desc")
|
||||
query = qb.buildPackageQuery()
|
||||
qb.set_sort_if_none("score", "desc")
|
||||
query = qb.build_package_query()
|
||||
|
||||
only_no_tags = isYes(request.args.get("no_tags"))
|
||||
only_no_tags = is_yes(request.args.get("no_tags"))
|
||||
if only_no_tags:
|
||||
query = query.filter(Package.tags == None)
|
||||
|
||||
@ -153,7 +153,7 @@ def modnames():
|
||||
@bp.route("/todo/outdated/")
|
||||
@login_required
|
||||
def outdated():
|
||||
is_mtm_only = isYes(request.args.get("mtm"))
|
||||
is_mtm_only = is_yes(request.args.get("mtm"))
|
||||
|
||||
query = db.session.query(Package).select_from(PackageUpdateConfig) \
|
||||
.filter(PackageUpdateConfig.outdated_at.isnot(None)) \
|
||||
@ -177,7 +177,7 @@ def outdated():
|
||||
@bp.route("/todo/screenshots/")
|
||||
@login_required
|
||||
def screenshots():
|
||||
is_mtm_only = isYes(request.args.get("mtm"))
|
||||
is_mtm_only = is_yes(request.args.get("mtm"))
|
||||
|
||||
query = db.session.query(Package) \
|
||||
.filter(~Package.screenshots.any()) \
|
||||
@ -200,7 +200,7 @@ def screenshots():
|
||||
@bp.route("/todo/mtver_support/")
|
||||
@login_required
|
||||
def mtver_support():
|
||||
is_mtm_only = isYes(request.args.get("mtm"))
|
||||
is_mtm_only = is_yes(request.args.get("mtm"))
|
||||
|
||||
current_stable = MinetestRelease.query.filter(~MinetestRelease.name.like("%-dev")).order_by(db.desc(MinetestRelease.id)).first()
|
||||
|
||||
|
@ -22,8 +22,8 @@ from sqlalchemy import or_, and_
|
||||
|
||||
from app.models import User, Package, PackageState, PackageScreenshot, PackageUpdateConfig, ForumTopic, db, \
|
||||
PackageRelease, Permission, NotificationType, AuditSeverity, UserRank, PackageType
|
||||
from app.tasks.importtasks import makeVCSRelease
|
||||
from app.utils import addNotification, addAuditLog
|
||||
from app.tasks.importtasks import make_vcs_release
|
||||
from app.utils import add_notification, add_audit_log
|
||||
from . import bp
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ def view_user(username=None):
|
||||
if not user:
|
||||
abort(404)
|
||||
|
||||
if current_user != user and not current_user.rank.atLeast(UserRank.APPROVER):
|
||||
if current_user != user and not current_user.rank.at_least(UserRank.APPROVER):
|
||||
abort(403)
|
||||
|
||||
unapproved_packages = user.packages \
|
||||
@ -97,7 +97,7 @@ def apply_all_updates(username):
|
||||
if not user:
|
||||
abort(404)
|
||||
|
||||
if current_user != user and not current_user.rank.atLeast(UserRank.EDITOR):
|
||||
if current_user != user and not current_user.rank.at_least(UserRank.EDITOR):
|
||||
abort(403)
|
||||
|
||||
outdated_packages = user.maintained_packages \
|
||||
@ -124,13 +124,13 @@ def apply_all_updates(username):
|
||||
db.session.add(rel)
|
||||
db.session.commit()
|
||||
|
||||
makeVCSRelease.apply_async((rel.id, ref),
|
||||
task_id=rel.task_id)
|
||||
make_vcs_release.apply_async((rel.id, ref),
|
||||
task_id=rel.task_id)
|
||||
|
||||
msg = "Created release {} (Applied all Git Update Detection)".format(rel.title)
|
||||
addNotification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg,
|
||||
rel.get_url("packages.create_edit"), package)
|
||||
addAuditLog(AuditSeverity.NORMAL, current_user, msg, package.get_url("packages.view"), package)
|
||||
add_notification(package.maintainers, current_user, NotificationType.PACKAGE_EDIT, msg,
|
||||
rel.get_url("packages.create_edit"), package)
|
||||
add_audit_log(AuditSeverity.NORMAL, current_user, msg, package.get_url("packages.view"), package)
|
||||
db.session.commit()
|
||||
|
||||
return redirect(url_for("todo.view_user", username=username))
|
||||
@ -144,7 +144,7 @@ def all_game_support(username=None):
|
||||
return redirect(url_for("todo.all_game_support", username=current_user.username))
|
||||
|
||||
user: User = User.query.filter_by(username=username).one_or_404()
|
||||
if current_user != user and not current_user.rank.atLeast(UserRank.EDITOR):
|
||||
if current_user != user and not current_user.rank.at_least(UserRank.EDITOR):
|
||||
abort(403)
|
||||
|
||||
packages = user.maintained_packages.filter(
|
||||
@ -159,7 +159,7 @@ def all_game_support(username=None):
|
||||
@login_required
|
||||
def confirm_supports_all_games(username=None):
|
||||
user: User = User.query.filter_by(username=username).one_or_404()
|
||||
if current_user != user and not current_user.rank.atLeast(UserRank.EDITOR):
|
||||
if current_user != user and not current_user.rank.at_least(UserRank.EDITOR):
|
||||
abort(403)
|
||||
|
||||
packages = user.maintained_packages.filter(
|
||||
@ -173,8 +173,8 @@ def confirm_supports_all_games(username=None):
|
||||
package.supports_all_games = True
|
||||
db.session.merge(package)
|
||||
|
||||
addAuditLog(AuditSeverity.NORMAL, current_user, "Enabled 'Supports all games' (bulk)",
|
||||
package.get_url("packages.game_support"), package)
|
||||
add_audit_log(AuditSeverity.NORMAL, current_user, "Enabled 'Supports all games' (bulk)",
|
||||
package.get_url("packages.game_support"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
|
@ -25,8 +25,8 @@ from wtforms import StringField, SubmitField, BooleanField, PasswordField, valid
|
||||
from wtforms.validators import InputRequired, Length, Regexp, DataRequired, Optional, Email, EqualTo
|
||||
|
||||
from app.tasks.emails import send_verify_email, send_anon_email, send_unsubscribe_verify, send_user_email
|
||||
from app.utils import randomString, make_flask_login_password, is_safe_url, check_password_hash, addAuditLog, \
|
||||
nonEmptyOrNone, post_login, is_username_valid
|
||||
from app.utils import random_string, make_flask_login_password, is_safe_url, check_password_hash, add_audit_log, \
|
||||
nonempty_or_none, post_login, is_username_valid
|
||||
from . import bp
|
||||
from app.models import User, AuditSeverity, db, UserRank, PackageAlias, EmailSubscription, UserNotificationPreferences, \
|
||||
UserEmailVerification
|
||||
@ -58,8 +58,8 @@ def handle_login(form):
|
||||
flash(gettext("You need to confirm the registration email"), "danger")
|
||||
return
|
||||
|
||||
addAuditLog(AuditSeverity.USER, user, "Logged in using password",
|
||||
url_for("users.profile", username=user.username))
|
||||
add_audit_log(AuditSeverity.USER, user, "Logged in using password",
|
||||
url_for("users.profile", username=user.username))
|
||||
db.session.commit()
|
||||
|
||||
if not login_user(user, remember=form.remember_me.data):
|
||||
@ -97,7 +97,7 @@ def logout():
|
||||
|
||||
|
||||
class RegisterForm(FlaskForm):
|
||||
display_name = StringField(lazy_gettext("Display Name"), [Optional(), Length(1, 20)], filters=[nonEmptyOrNone])
|
||||
display_name = StringField(lazy_gettext("Display Name"), [Optional(), Length(1, 20)], filters=[nonempty_or_none])
|
||||
username = StringField(lazy_gettext("Username"), [InputRequired(),
|
||||
Regexp("^[a-zA-Z0-9._-]+$", message=lazy_gettext(
|
||||
"Only alphabetic letters (A-Za-z), numbers (0-9), underscores (_), minuses (-), and periods (.) allowed"))])
|
||||
@ -154,10 +154,10 @@ def handle_register(form):
|
||||
user.display_name = form.display_name.data
|
||||
db.session.add(user)
|
||||
|
||||
addAuditLog(AuditSeverity.USER, user, "Registered with email, display name=" + user.display_name,
|
||||
url_for("users.profile", username=user.username))
|
||||
add_audit_log(AuditSeverity.USER, user, "Registered with email, display name=" + user.display_name,
|
||||
url_for("users.profile", username=user.username))
|
||||
|
||||
token = randomString(32)
|
||||
token = random_string(32)
|
||||
|
||||
ver = UserEmailVerification()
|
||||
ver.user = user
|
||||
@ -194,10 +194,10 @@ def forgot_password():
|
||||
email = form.email.data
|
||||
user = User.query.filter_by(email=email).first()
|
||||
if user:
|
||||
token = randomString(32)
|
||||
token = random_string(32)
|
||||
|
||||
addAuditLog(AuditSeverity.USER, user, "(Anonymous) requested a password reset",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
add_audit_log(AuditSeverity.USER, user, "(Anonymous) requested a password reset",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
|
||||
ver = UserEmailVerification()
|
||||
ver.user = user
|
||||
@ -241,12 +241,12 @@ def handle_set_password(form):
|
||||
flash(gettext("Passwords do not match"), "danger")
|
||||
return
|
||||
|
||||
addAuditLog(AuditSeverity.USER, current_user, "Changed their password", url_for("users.profile", username=current_user.username))
|
||||
add_audit_log(AuditSeverity.USER, current_user, "Changed their password", url_for("users.profile", username=current_user.username))
|
||||
|
||||
current_user.password = make_flask_login_password(form.password.data)
|
||||
|
||||
if hasattr(form, "email"):
|
||||
new_email = nonEmptyOrNone(form.email.data)
|
||||
new_email = nonempty_or_none(form.email.data)
|
||||
if new_email and new_email != current_user.email:
|
||||
if EmailSubscription.query.filter_by(email=form.email.data, blacklisted=True).count() > 0:
|
||||
flash(gettext(u"That email address has been unsubscribed/blacklisted, and cannot be used"), "danger")
|
||||
@ -258,7 +258,7 @@ def handle_set_password(form):
|
||||
gettext(u"We were unable to create the account as the email is already in use by %(display_name)s. Try a different email address.",
|
||||
display_name=user_by_email.display_name))
|
||||
else:
|
||||
token = randomString(32)
|
||||
token = random_string(32)
|
||||
|
||||
ver = UserEmailVerification()
|
||||
ver.user = current_user
|
||||
@ -329,8 +329,8 @@ def verify_email():
|
||||
|
||||
user = ver.user
|
||||
|
||||
addAuditLog(AuditSeverity.USER, user, "Confirmed their email",
|
||||
url_for("users.profile", username=user.username))
|
||||
add_audit_log(AuditSeverity.USER, user, "Confirmed their email",
|
||||
url_for("users.profile", username=user.username))
|
||||
|
||||
was_activating = not user.is_active
|
||||
|
||||
@ -383,7 +383,7 @@ def unsubscribe_verify():
|
||||
sub = EmailSubscription(email)
|
||||
db.session.add(sub)
|
||||
|
||||
sub.token = randomString(32)
|
||||
sub.token = random_string(32)
|
||||
db.session.commit()
|
||||
send_unsubscribe_verify.delay(form.email.data, get_locale().language)
|
||||
|
||||
|
@ -19,9 +19,9 @@ from flask_babel import gettext
|
||||
from . import bp
|
||||
from flask import redirect, render_template, session, request, flash, url_for
|
||||
from app.models import db, User, UserRank
|
||||
from app.utils import randomString, login_user_set_active, is_username_valid
|
||||
from app.tasks.forumtasks import checkForumAccount
|
||||
from app.utils.phpbbparser import getProfile
|
||||
from app.utils import random_string, login_user_set_active, is_username_valid
|
||||
from app.tasks.forumtasks import check_forum_account
|
||||
from app.utils.phpbbparser import get_profile
|
||||
|
||||
|
||||
@bp.route("/user/claim/", methods=["GET", "POST"])
|
||||
@ -42,7 +42,7 @@ def claim_forums():
|
||||
return redirect(url_for("users.claim_forums"))
|
||||
|
||||
user = User.query.filter_by(forums_username=username).first()
|
||||
if user and user.rank.atLeast(UserRank.NEW_MEMBER):
|
||||
if user and user.rank.at_least(UserRank.NEW_MEMBER):
|
||||
flash(gettext("User has already been claimed"), "danger")
|
||||
return redirect(url_for("users.claim_forums"))
|
||||
elif method == "github":
|
||||
@ -55,7 +55,7 @@ def claim_forums():
|
||||
if "forum_token" in session:
|
||||
token = session["forum_token"]
|
||||
else:
|
||||
token = randomString(12)
|
||||
token = random_string(12)
|
||||
session["forum_token"] = token
|
||||
|
||||
if request.method == "POST":
|
||||
@ -65,17 +65,17 @@ def claim_forums():
|
||||
if not is_username_valid(username):
|
||||
flash(gettext("Invalid username, Only alphabetic letters (A-Za-z), numbers (0-9), underscores (_), minuses (-), and periods (.) allowed. Consider contacting an admin"), "danger")
|
||||
elif ctype == "github":
|
||||
task = checkForumAccount.delay(username)
|
||||
task = check_forum_account.delay(username)
|
||||
return redirect(url_for("tasks.check", id=task.id, r=url_for("users.claim_forums", username=username, method="github")))
|
||||
elif ctype == "forum":
|
||||
user = User.query.filter_by(forums_username=username).first()
|
||||
if user is not None and user.rank.atLeast(UserRank.NEW_MEMBER):
|
||||
if user is not None and user.rank.at_least(UserRank.NEW_MEMBER):
|
||||
flash(gettext("That user has already been claimed!"), "danger")
|
||||
return redirect(url_for("users.claim_forums"))
|
||||
|
||||
# Get signature
|
||||
try:
|
||||
profile = getProfile("https://forum.minetest.net", username)
|
||||
profile = get_profile("https://forum.minetest.net", username)
|
||||
sig = profile.signature if profile else None
|
||||
except IOError as e:
|
||||
if hasattr(e, 'message'):
|
||||
|
@ -25,7 +25,7 @@ from wtforms.validators import Length, Optional, Email, URL
|
||||
from app.models import User, AuditSeverity, db, UserRank, PackageAlias, EmailSubscription, UserNotificationPreferences, \
|
||||
UserEmailVerification, Permission, NotificationType, UserBan
|
||||
from app.tasks.emails import send_verify_email
|
||||
from app.utils import nonEmptyOrNone, addAuditLog, randomString, rank_required, has_blocked_domains
|
||||
from app.utils import nonempty_or_none, add_audit_log, random_string, rank_required, has_blocked_domains
|
||||
from . import bp
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ def get_setting_tabs(user):
|
||||
},
|
||||
]
|
||||
|
||||
if current_user.rank.atLeast(UserRank.MODERATOR):
|
||||
if current_user.rank.at_least(UserRank.MODERATOR):
|
||||
ret.append({
|
||||
"id": "modtools",
|
||||
"title": gettext("Moderator Tools"),
|
||||
@ -64,7 +64,7 @@ def get_setting_tabs(user):
|
||||
|
||||
|
||||
class UserProfileForm(FlaskForm):
|
||||
display_name = StringField(lazy_gettext("Display Name"), [Optional(), Length(1, 20)], filters=[lambda x: nonEmptyOrNone(x.strip())])
|
||||
display_name = StringField(lazy_gettext("Display Name"), [Optional(), Length(1, 20)], filters=[lambda x: nonempty_or_none(x.strip())])
|
||||
website_url = StringField(lazy_gettext("Website URL"), [Optional(), URL()], filters = [lambda x: x or None])
|
||||
donate_url = StringField(lazy_gettext("Donation URL"), [Optional(), URL()], filters = [lambda x: x or None])
|
||||
submit = SubmitField(lazy_gettext("Save"))
|
||||
@ -72,8 +72,8 @@ class UserProfileForm(FlaskForm):
|
||||
|
||||
def handle_profile_edit(form: UserProfileForm, user: User, username: str):
|
||||
severity = AuditSeverity.NORMAL if current_user == user else AuditSeverity.MODERATION
|
||||
addAuditLog(severity, current_user, "Edited {}'s profile".format(user.display_name),
|
||||
url_for("users.profile", username=username))
|
||||
add_audit_log(severity, current_user, "Edited {}'s profile".format(user.display_name),
|
||||
url_for("users.profile", username=username))
|
||||
|
||||
display_name = form.display_name.data or user.username
|
||||
if user.check_perm(current_user, Permission.CHANGE_DISPLAY_NAME) and \
|
||||
@ -95,9 +95,9 @@ def handle_profile_edit(form: UserProfileForm, user: User, username: str):
|
||||
user.display_name = display_name
|
||||
|
||||
severity = AuditSeverity.USER if current_user == user else AuditSeverity.MODERATION
|
||||
addAuditLog(severity, current_user, "Changed display name of {} to {}"
|
||||
.format(user.username, user.display_name),
|
||||
url_for("users.profile", username=username))
|
||||
add_audit_log(severity, current_user, "Changed display name of {} to {}"
|
||||
.format(user.username, user.display_name),
|
||||
url_for("users.profile", username=username))
|
||||
|
||||
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 \
|
||||
@ -167,12 +167,12 @@ def handle_email_notifications(user, prefs: UserNotificationPreferences, is_new,
|
||||
flash(gettext("That email address has been unsubscribed/blacklisted, and cannot be used"), "danger")
|
||||
return
|
||||
|
||||
token = randomString(32)
|
||||
token = random_string(32)
|
||||
|
||||
severity = AuditSeverity.NORMAL if current_user == user else AuditSeverity.MODERATION
|
||||
|
||||
msg = "Changed email of {}".format(user.display_name)
|
||||
addAuditLog(severity, current_user, msg, url_for("users.profile", username=user.username))
|
||||
add_audit_log(severity, current_user, msg, url_for("users.profile", username=user.username))
|
||||
|
||||
ver = UserEmailVerification()
|
||||
ver.user = user
|
||||
@ -245,19 +245,19 @@ def delete(username):
|
||||
if not user:
|
||||
abort(404)
|
||||
|
||||
if user.rank.atLeast(UserRank.MODERATOR):
|
||||
if user.rank.at_least(UserRank.MODERATOR):
|
||||
flash(gettext("Users with moderator rank or above cannot be deleted"), "danger")
|
||||
return redirect(url_for("users.account", username=username))
|
||||
|
||||
if request.method == "GET":
|
||||
return render_template("users/delete.html", user=user, can_delete=user.can_delete())
|
||||
|
||||
if "delete" in request.form and (user.can_delete() or current_user.rank.atLeast(UserRank.ADMIN)):
|
||||
if "delete" in request.form and (user.can_delete() or current_user.rank.at_least(UserRank.ADMIN)):
|
||||
msg = "Deleted user {}".format(user.username)
|
||||
flash(msg, "success")
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg, None)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, msg, None)
|
||||
|
||||
if current_user.rank.atLeast(UserRank.ADMIN):
|
||||
if current_user.rank.at_least(UserRank.ADMIN):
|
||||
for pkg in user.packages.all():
|
||||
pkg.review_thread = None
|
||||
db.session.delete(pkg)
|
||||
@ -273,7 +273,7 @@ def delete(username):
|
||||
|
||||
msg = "Deactivated user {}".format(user.username)
|
||||
flash(msg, "success")
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg, None)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, msg, None)
|
||||
else:
|
||||
assert False
|
||||
|
||||
@ -308,8 +308,8 @@ def modtools(username):
|
||||
form = ModToolsForm(obj=user)
|
||||
if form.validate_on_submit():
|
||||
severity = AuditSeverity.NORMAL if current_user == user else AuditSeverity.MODERATION
|
||||
addAuditLog(severity, current_user, "Edited {}'s account".format(user.display_name),
|
||||
url_for("users.profile", username=username))
|
||||
add_audit_log(severity, current_user, "Edited {}'s account".format(user.display_name),
|
||||
url_for("users.profile", username=username))
|
||||
|
||||
# Copy form fields to user_profile fields
|
||||
if user.check_perm(current_user, Permission.CHANGE_USERNAMES):
|
||||
@ -322,17 +322,17 @@ def modtools(username):
|
||||
user.username = form.username.data
|
||||
|
||||
user.display_name = form.display_name.data
|
||||
user.forums_username = nonEmptyOrNone(form.forums_username.data)
|
||||
user.github_username = nonEmptyOrNone(form.github_username.data)
|
||||
user.forums_username = nonempty_or_none(form.forums_username.data)
|
||||
user.github_username = nonempty_or_none(form.github_username.data)
|
||||
|
||||
if user.check_perm(current_user, Permission.CHANGE_RANK):
|
||||
new_rank = form["rank"].data
|
||||
if current_user.rank.atLeast(new_rank):
|
||||
if current_user.rank.at_least(new_rank):
|
||||
if new_rank != user.rank:
|
||||
user.rank = form["rank"].data
|
||||
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))
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, msg,
|
||||
url_for("users.profile", username=username))
|
||||
else:
|
||||
flash(gettext("Can't promote a user to a rank higher than yourself!"), "danger")
|
||||
|
||||
@ -356,9 +356,9 @@ def modtools_set_email(username):
|
||||
user.email = request.form["email"]
|
||||
user.is_active = False
|
||||
|
||||
token = randomString(32)
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, f"Set email and sent a password reset on {user.username}",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
token = random_string(32)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, f"Set email and sent a password reset on {user.username}",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
|
||||
ver = UserEmailVerification()
|
||||
ver.user = user
|
||||
@ -396,8 +396,8 @@ def modtools_ban(username):
|
||||
else:
|
||||
user.rank = UserRank.BANNED
|
||||
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, f"Banned {user.username}, expires {user.ban.expires_at or '-'}, message: {message}",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, f"Banned {user.username}, expires {user.ban.expires_at or '-'}, message: {message}",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
db.session.commit()
|
||||
|
||||
flash(f"Banned {user.username}", "success")
|
||||
@ -420,8 +420,8 @@ def modtools_unban(username):
|
||||
if user.rank == UserRank.BANNED:
|
||||
user.rank = UserRank.MEMBER
|
||||
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, f"Unbanned {user.username}",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
add_audit_log(AuditSeverity.MODERATION, current_user, f"Unbanned {user.username}",
|
||||
url_for("users.profile", username=user.username), None)
|
||||
db.session.commit()
|
||||
|
||||
flash(f"Unbanned {user.username}", "success")
|
||||
|
@ -22,6 +22,7 @@ from sqlalchemy import and_, or_
|
||||
|
||||
from app.models import Package, PackageType, PackageState, PackageRelease
|
||||
|
||||
|
||||
ValidationError = namedtuple("ValidationError", "status message")
|
||||
|
||||
|
||||
|
@ -24,7 +24,7 @@ from flask_babel import lazy_gettext, LazyString
|
||||
from app.logic.LogicError import LogicError
|
||||
from app.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, AuditSeverity, \
|
||||
License, UserRank, PackageDevState
|
||||
from app.utils import addAuditLog, has_blocked_domains, diff_dictionaries, describe_difference
|
||||
from app.utils import add_audit_log, has_blocked_domains, diff_dictionaries, describe_difference
|
||||
from app.utils.url import clean_youtube_url
|
||||
|
||||
|
||||
@ -173,7 +173,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
|
||||
if not was_web and tag.is_protected:
|
||||
continue
|
||||
|
||||
if tag.is_protected and tag not in old_tags and not user.rank.atLeast(UserRank.EDITOR):
|
||||
if tag.is_protected and tag not in old_tags and not user.rank.at_least(UserRank.EDITOR):
|
||||
raise LogicError(400, lazy_gettext("Unable to add protected tag %(title)s to package", title=tag.title))
|
||||
|
||||
package.tags.append(tag)
|
||||
@ -208,7 +208,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.get_url("packages.view"), package, json.dumps(diff, indent=4))
|
||||
add_audit_log(severity, user, msg, package.get_url("packages.view"), package, json.dumps(diff, indent=4))
|
||||
|
||||
db.session.commit()
|
||||
|
||||
|
@ -23,8 +23,8 @@ from flask_babel import lazy_gettext
|
||||
from app.logic.LogicError import LogicError
|
||||
from app.logic.uploads import upload_file
|
||||
from app.models import PackageRelease, db, Permission, User, Package, MinetestRelease
|
||||
from app.tasks.importtasks import makeVCSRelease, checkZipRelease
|
||||
from app.utils import AuditSeverity, addAuditLog, nonEmptyOrNone
|
||||
from app.tasks.importtasks import make_vcs_release, check_zip_release
|
||||
from app.utils import AuditSeverity, add_audit_log, nonempty_or_none
|
||||
|
||||
|
||||
def check_can_create_release(user: User, package: Package):
|
||||
@ -54,11 +54,11 @@ 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.get_url("packages.view"), package)
|
||||
add_audit_log(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
makeVCSRelease.apply_async((rel.id, nonEmptyOrNone(ref)), task_id=rel.task_id)
|
||||
make_vcs_release.apply_async((rel.id, nonempty_or_none(ref)), task_id=rel.task_id)
|
||||
|
||||
return rel
|
||||
|
||||
@ -89,10 +89,10 @@ 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.get_url("packages.view"), package)
|
||||
add_audit_log(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
checkZipRelease.apply_async((rel.id, uploaded_path), task_id=rel.task_id)
|
||||
check_zip_release.apply_async((rel.id, uploaded_path), task_id=rel.task_id)
|
||||
|
||||
return rel
|
||||
|
@ -21,7 +21,7 @@ from flask_babel import lazy_gettext
|
||||
from app.logic.LogicError import LogicError
|
||||
from app.logic.uploads import upload_file
|
||||
from app.models import User, Package, PackageScreenshot, Permission, NotificationType, db, AuditSeverity
|
||||
from app.utils import addNotification, addAuditLog
|
||||
from app.utils import add_notification, add_audit_log
|
||||
from app.utils.image import get_image_size
|
||||
|
||||
|
||||
@ -58,8 +58,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.get_url("packages.view"), package)
|
||||
addAuditLog(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
|
||||
add_notification(package.maintainers, user, NotificationType.PACKAGE_EDIT, msg, package.get_url("packages.view"), package)
|
||||
add_audit_log(AuditSeverity.NORMAL, user, msg, package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
|
@ -21,7 +21,7 @@ from flask_babel import lazy_gettext
|
||||
|
||||
from app import app
|
||||
from app.logic.LogicError import LogicError
|
||||
from app.utils import randomString
|
||||
from app.utils import random_string
|
||||
|
||||
|
||||
def get_extension(filename):
|
||||
@ -59,7 +59,7 @@ def upload_file(file, file_type, file_type_desc):
|
||||
|
||||
file.stream.seek(0)
|
||||
|
||||
filename = randomString(10) + "." + ext
|
||||
filename = random_string(10) + "." + ext
|
||||
filepath = os.path.join(app.config["UPLOAD_DIR"], filename)
|
||||
file.save(filepath)
|
||||
|
||||
|
@ -116,7 +116,7 @@ class AuditLogEntry(db.Model):
|
||||
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)
|
||||
return user.rank.at_least(UserRank.APPROVER if self.package is not None else UserRank.MODERATOR)
|
||||
else:
|
||||
raise Exception("Permission {} is not related to audit log entries".format(perm.name))
|
||||
|
||||
@ -181,7 +181,7 @@ class ForumTopic(db.Model):
|
||||
raise Exception("Unknown permission given to ForumTopic.check_perm()")
|
||||
|
||||
if perm == Permission.TOPIC_DISCARD:
|
||||
return self.author == user or user.rank.atLeast(UserRank.EDITOR)
|
||||
return self.author == user or user.rank.at_least(UserRank.EDITOR)
|
||||
|
||||
else:
|
||||
raise Exception("Permission {} is not related to topics".format(perm.name))
|
||||
|
@ -271,7 +271,7 @@ class Dependency(db.Model):
|
||||
else:
|
||||
raise Exception("Either meta or package must be given, but not both!")
|
||||
|
||||
def getName(self):
|
||||
def get_name(self):
|
||||
if self.meta_package:
|
||||
return self.meta_package.name
|
||||
elif self.package:
|
||||
@ -484,7 +484,7 @@ class Package(db.Model):
|
||||
query = query.filter_by(optional=not is_hard)
|
||||
|
||||
deps = query.all()
|
||||
deps.sort(key=lambda x: x.getName())
|
||||
deps.sort(key=lambda x: x.get_name())
|
||||
return deps
|
||||
|
||||
def get_sorted_hard_dependencies(self):
|
||||
@ -654,25 +654,25 @@ class Package(db.Model):
|
||||
raise Exception("Unknown permission given to Package.check_perm()")
|
||||
|
||||
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)
|
||||
is_maintainer = is_owner or user.rank.at_least(UserRank.EDITOR) or user in self.maintainers
|
||||
is_approver = user.rank.at_least(UserRank.APPROVER)
|
||||
|
||||
if perm == Permission.CREATE_THREAD:
|
||||
return user.rank.atLeast(UserRank.NEW_MEMBER)
|
||||
return user.rank.at_least(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 is_maintainer
|
||||
|
||||
elif perm == Permission.EDIT_PACKAGE:
|
||||
return is_maintainer and user.rank.atLeast(UserRank.NEW_MEMBER)
|
||||
return is_maintainer and user.rank.at_least(UserRank.NEW_MEMBER)
|
||||
|
||||
elif perm == Permission.APPROVE_RELEASE:
|
||||
return (is_maintainer or is_approver) and user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
|
||||
return (is_maintainer or is_approver) and user.rank.at_least(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:
|
||||
return not self.approved or user.rank.atLeast(UserRank.EDITOR)
|
||||
return not self.approved or user.rank.at_least(UserRank.EDITOR)
|
||||
|
||||
# Editors can change authors and approve new packages
|
||||
elif perm == Permission.APPROVE_NEW or perm == Permission.CHANGE_AUTHOR:
|
||||
@ -680,16 +680,16 @@ class Package(db.Model):
|
||||
|
||||
elif perm == Permission.APPROVE_SCREENSHOT:
|
||||
return (is_maintainer or is_approver) and \
|
||||
user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
|
||||
user.rank.at_least(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
|
||||
|
||||
elif perm == Permission.EDIT_MAINTAINERS or perm == Permission.DELETE_PACKAGE:
|
||||
return is_owner or user.rank.atLeast(UserRank.EDITOR)
|
||||
return is_owner or user.rank.at_least(UserRank.EDITOR)
|
||||
|
||||
elif perm == Permission.UNAPPROVE_PACKAGE:
|
||||
return is_owner or user.rank.atLeast(UserRank.APPROVER)
|
||||
return is_owner or user.rank.at_least(UserRank.APPROVER)
|
||||
|
||||
elif perm == Permission.CHANGE_RELEASE_URL:
|
||||
return user.rank.atLeast(UserRank.MODERATOR)
|
||||
return user.rank.at_least(UserRank.MODERATOR)
|
||||
|
||||
else:
|
||||
raise Exception("Permission {} is not related to packages".format(perm.name))
|
||||
@ -738,7 +738,7 @@ class Package(db.Model):
|
||||
|
||||
elif state == PackageState.WIP:
|
||||
return self.check_perm(user, Permission.EDIT_PACKAGE) and \
|
||||
(user in self.maintainers or user.rank.atLeast(UserRank.ADMIN))
|
||||
(user in self.maintainers or user.rank.at_least(UserRank.ADMIN))
|
||||
|
||||
return True
|
||||
|
||||
@ -1018,10 +1018,10 @@ class PackageRelease(db.Model):
|
||||
is_maintainer = user == self.package.author or user in self.package.maintainers
|
||||
|
||||
if perm == Permission.DELETE_RELEASE:
|
||||
if user.rank.atLeast(UserRank.ADMIN):
|
||||
if user.rank.at_least(UserRank.ADMIN):
|
||||
return True
|
||||
|
||||
if not (is_maintainer or user.rank.atLeast(UserRank.EDITOR)):
|
||||
if not (is_maintainer or user.rank.at_least(UserRank.EDITOR)):
|
||||
return False
|
||||
|
||||
if not self.package.approved or self.task_id is not None:
|
||||
@ -1033,8 +1033,8 @@ class PackageRelease(db.Model):
|
||||
|
||||
return count > 0
|
||||
elif perm == Permission.APPROVE_RELEASE:
|
||||
return user.rank.atLeast(UserRank.APPROVER) or \
|
||||
(is_maintainer and user.rank.atLeast(
|
||||
return user.rank.at_least(UserRank.APPROVER) or \
|
||||
(is_maintainer and user.rank.at_least(
|
||||
UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER))
|
||||
else:
|
||||
raise Exception("Permission {} is not related to releases".format(perm.name))
|
||||
|
@ -92,21 +92,21 @@ class Thread(db.Model):
|
||||
if self.package:
|
||||
isMaintainer = isMaintainer or user in self.package.maintainers
|
||||
|
||||
canSee = not self.private or isMaintainer or user.rank.atLeast(UserRank.APPROVER) or user in self.watchers
|
||||
canSee = not self.private or isMaintainer or user.rank.at_least(UserRank.APPROVER) or user in self.watchers
|
||||
|
||||
if perm == Permission.SEE_THREAD:
|
||||
return canSee
|
||||
|
||||
elif perm == Permission.COMMENT_THREAD:
|
||||
return canSee and (not self.locked or user.rank.atLeast(UserRank.MODERATOR))
|
||||
return canSee and (not self.locked or user.rank.at_least(UserRank.MODERATOR))
|
||||
|
||||
elif perm == Permission.LOCK_THREAD:
|
||||
return user.rank.atLeast(UserRank.MODERATOR)
|
||||
return user.rank.at_least(UserRank.MODERATOR)
|
||||
|
||||
elif perm == Permission.DELETE_THREAD:
|
||||
from app.utils.models import get_system_user
|
||||
return (self.author == get_system_user() and self.package and
|
||||
user in self.package.maintainers) or user.rank.atLeast(UserRank.MODERATOR)
|
||||
user in self.package.maintainers) or user.rank.at_least(UserRank.MODERATOR)
|
||||
|
||||
else:
|
||||
raise Exception("Permission {} is not related to threads".format(perm.name))
|
||||
@ -157,10 +157,10 @@ class ThreadReply(db.Model):
|
||||
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
|
||||
return user.rank.at_least(UserRank.NEW_MEMBER if user == self.author else UserRank.MODERATOR) and not self.thread.locked
|
||||
|
||||
elif perm == Permission.DELETE_REPLY:
|
||||
return user.rank.atLeast(UserRank.MODERATOR) and self.thread.first_reply != self
|
||||
return user.rank.at_least(UserRank.MODERATOR) and self.thread.first_reply != self
|
||||
|
||||
else:
|
||||
raise Exception("Permission {} is not related to threads".format(perm.name))
|
||||
@ -227,7 +227,7 @@ class PackageReview(db.Model):
|
||||
name=self.package.name,
|
||||
reviewer=self.author.username)
|
||||
|
||||
def getVoteUrl(self, next_url=None):
|
||||
def get_vote_url(self, next_url=None):
|
||||
return url_for("packages.review_vote",
|
||||
author=self.package.author.username,
|
||||
name=self.package.name,
|
||||
@ -248,7 +248,7 @@ class PackageReview(db.Model):
|
||||
raise Exception("Unknown permission given to PackageReview.check_perm()")
|
||||
|
||||
if perm == Permission.DELETE_REVIEW:
|
||||
return user == self.author or user.rank.atLeast(UserRank.MODERATOR)
|
||||
return user == self.author or user.rank.at_least(UserRank.MODERATOR)
|
||||
else:
|
||||
raise Exception("Permission {} is not related to reviews".format(perm.name))
|
||||
|
||||
|
@ -37,7 +37,7 @@ class UserRank(enum.Enum):
|
||||
MODERATOR = 8
|
||||
ADMIN = 9
|
||||
|
||||
def atLeast(self, min):
|
||||
def at_least(self, min):
|
||||
return self.value >= min.value
|
||||
|
||||
def get_title(self):
|
||||
@ -101,10 +101,10 @@ class Permission(enum.Enum):
|
||||
self == Permission.APPROVE_RELEASE or \
|
||||
self == Permission.APPROVE_SCREENSHOT or \
|
||||
self == Permission.SEE_THREAD:
|
||||
return user.rank.atLeast(UserRank.APPROVER)
|
||||
return user.rank.at_least(UserRank.APPROVER)
|
||||
|
||||
elif self == Permission.EDIT_TAGS or self == Permission.CREATE_TAG:
|
||||
return user.rank.atLeast(UserRank.EDITOR)
|
||||
return user.rank.at_least(UserRank.EDITOR)
|
||||
|
||||
else:
|
||||
raise Exception("Non-global permission checked globally. Use Package.check_perm or User.check_perm instead.")
|
||||
@ -234,20 +234,20 @@ class User(db.Model, UserMixin):
|
||||
|
||||
# Members can edit their own packages, and editors can edit any packages
|
||||
if perm == Permission.CHANGE_AUTHOR:
|
||||
return user.rank.atLeast(UserRank.EDITOR)
|
||||
return user.rank.at_least(UserRank.EDITOR)
|
||||
elif perm == Permission.CHANGE_USERNAMES:
|
||||
return user.rank.atLeast(UserRank.MODERATOR)
|
||||
return user.rank.at_least(UserRank.MODERATOR)
|
||||
elif perm == Permission.CHANGE_RANK:
|
||||
return user.rank.atLeast(UserRank.MODERATOR) and not self.rank.atLeast(user.rank)
|
||||
return user.rank.at_least(UserRank.MODERATOR) and not self.rank.at_least(user.rank)
|
||||
elif perm == Permission.CHANGE_EMAIL or perm == Permission.CHANGE_PROFILE_URLS:
|
||||
return user == self or (user.rank.atLeast(UserRank.MODERATOR) and not self.rank.atLeast(user.rank))
|
||||
return user == self or (user.rank.at_least(UserRank.MODERATOR) and not self.rank.at_least(user.rank))
|
||||
elif perm == Permission.CHANGE_DISPLAY_NAME:
|
||||
return user.rank.atLeast(UserRank.NEW_MEMBER if user == self else UserRank.MODERATOR)
|
||||
return user.rank.at_least(UserRank.NEW_MEMBER if user == self else UserRank.MODERATOR)
|
||||
elif perm == Permission.CREATE_TOKEN:
|
||||
if user == self:
|
||||
return user.rank.atLeast(UserRank.NEW_MEMBER)
|
||||
return user.rank.at_least(UserRank.NEW_MEMBER)
|
||||
else:
|
||||
return user.rank.atLeast(UserRank.MODERATOR) and user.rank.atLeast(self.rank)
|
||||
return user.rank.at_least(UserRank.MODERATOR) and user.rank.at_least(self.rank)
|
||||
else:
|
||||
raise Exception("Permission {} is not related to users".format(perm.name))
|
||||
|
||||
@ -255,11 +255,11 @@ class User(db.Model, UserMixin):
|
||||
from app.models import ThreadReply
|
||||
|
||||
factor = 1
|
||||
if self.rank.atLeast(UserRank.ADMIN):
|
||||
if self.rank.at_least(UserRank.ADMIN):
|
||||
return True
|
||||
elif self.rank.atLeast(UserRank.TRUSTED_MEMBER):
|
||||
elif self.rank.at_least(UserRank.TRUSTED_MEMBER):
|
||||
factor = 3
|
||||
elif self.rank.atLeast(UserRank.MEMBER):
|
||||
elif self.rank.at_least(UserRank.MEMBER):
|
||||
factor = 2
|
||||
|
||||
one_min_ago = datetime.datetime.utcnow() - datetime.timedelta(minutes=1)
|
||||
@ -278,11 +278,11 @@ class User(db.Model, UserMixin):
|
||||
from app.models import Thread
|
||||
|
||||
factor = 1
|
||||
if self.rank.atLeast(UserRank.ADMIN):
|
||||
if self.rank.at_least(UserRank.ADMIN):
|
||||
return True
|
||||
elif self.rank.atLeast(UserRank.TRUSTED_MEMBER):
|
||||
elif self.rank.at_least(UserRank.TRUSTED_MEMBER):
|
||||
factor = 5
|
||||
elif self.rank.atLeast(UserRank.MEMBER):
|
||||
elif self.rank.at_least(UserRank.MEMBER):
|
||||
factor = 2
|
||||
|
||||
hour_ago = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
|
||||
@ -293,9 +293,9 @@ class User(db.Model, UserMixin):
|
||||
from app.models import PackageReview
|
||||
|
||||
factor = 1
|
||||
if self.rank.atLeast(UserRank.ADMIN):
|
||||
if self.rank.at_least(UserRank.ADMIN):
|
||||
return True
|
||||
elif self.rank.atLeast(UserRank.TRUSTED_MEMBER):
|
||||
elif self.rank.at_least(UserRank.TRUSTED_MEMBER):
|
||||
factor *= 5
|
||||
|
||||
five_mins_ago = datetime.datetime.utcnow() - datetime.timedelta(minutes=5)
|
||||
|
@ -23,7 +23,7 @@ from sqlalchemy_searchable import search
|
||||
|
||||
from .models import db, PackageType, Package, ForumTopic, License, MinetestRelease, PackageRelease, User, Tag, \
|
||||
ContentWarning, PackageState, PackageDevState
|
||||
from .utils import isYes, get_int_or_abort
|
||||
from .utils import is_yes, get_int_or_abort
|
||||
|
||||
|
||||
class QueryBuilder:
|
||||
@ -105,10 +105,10 @@ class QueryBuilder:
|
||||
else:
|
||||
self.version = None
|
||||
|
||||
self.show_discarded = isYes(args.get("show_discarded"))
|
||||
self.show_discarded = is_yes(args.get("show_discarded"))
|
||||
self.show_added = args.get("show_added")
|
||||
if self.show_added is not None:
|
||||
self.show_added = isYes(self.show_added)
|
||||
self.show_added = is_yes(self.show_added)
|
||||
|
||||
if self.search is not None and self.search.strip() == "":
|
||||
self.search = None
|
||||
@ -117,12 +117,12 @@ class QueryBuilder:
|
||||
if self.game:
|
||||
self.game = Package.get_by_key(self.game)
|
||||
|
||||
def setSortIfNone(self, name, dir="desc"):
|
||||
def set_sort_if_none(self, name, dir="desc"):
|
||||
if self.order_by is None:
|
||||
self.order_by = name
|
||||
self.order_dir = dir
|
||||
|
||||
def getReleases(self):
|
||||
def get_releases(self):
|
||||
releases_query = db.session.query(PackageRelease.package_id, func.max(PackageRelease.id)) \
|
||||
.select_from(PackageRelease).filter(PackageRelease.approved) \
|
||||
.group_by(PackageRelease.package_id)
|
||||
@ -136,18 +136,18 @@ class QueryBuilder:
|
||||
|
||||
return releases_query.all()
|
||||
|
||||
def convertToDictionary(self, packages):
|
||||
def convert_to_dictionary(self, packages):
|
||||
releases = {}
|
||||
for [package_id, release_id] in self.getReleases():
|
||||
for [package_id, release_id] in self.get_releases():
|
||||
releases[package_id] = release_id
|
||||
|
||||
def toJson(package: Package):
|
||||
def to_json(package: Package):
|
||||
release_id = releases.get(package.id)
|
||||
return package.as_short_dict(current_app.config["BASE_URL"], release_id=release_id, no_load=True)
|
||||
|
||||
return [toJson(pkg) for pkg in packages]
|
||||
return [to_json(pkg) for pkg in packages]
|
||||
|
||||
def buildPackageQuery(self):
|
||||
def build_package_query(self):
|
||||
if self.order_by == "last_release":
|
||||
query = db.session.query(Package).select_from(PackageRelease).join(Package) \
|
||||
.filter_by(state=PackageState.APPROVED)
|
||||
@ -156,14 +156,14 @@ class QueryBuilder:
|
||||
|
||||
query = query.options(subqueryload(Package.main_screenshot), subqueryload(Package.aliases))
|
||||
|
||||
query = self.orderPackageQuery(self.filterPackageQuery(query))
|
||||
query = self.order_package_query(self.filter_package_query(query))
|
||||
|
||||
if self.limit:
|
||||
query = query.limit(self.limit)
|
||||
|
||||
return query
|
||||
|
||||
def filterPackageQuery(self, query):
|
||||
def filter_package_query(self, query):
|
||||
if len(self.types) > 0:
|
||||
query = query.filter(Package.type.in_(self.types))
|
||||
|
||||
@ -207,7 +207,7 @@ class QueryBuilder:
|
||||
|
||||
return query
|
||||
|
||||
def orderPackageQuery(self, query):
|
||||
def order_package_query(self, query):
|
||||
if self.search:
|
||||
query = search(query, self.search, sort=self.order_by is None)
|
||||
|
||||
@ -250,7 +250,7 @@ class QueryBuilder:
|
||||
|
||||
return query
|
||||
|
||||
def buildTopicQuery(self, show_added=False):
|
||||
def build_topic_query(self, show_added=False):
|
||||
query = ForumTopic.query
|
||||
|
||||
if not self.show_discarded:
|
||||
|
@ -75,11 +75,11 @@ celery = make_celery(app)
|
||||
|
||||
CELERYBEAT_SCHEDULE = {
|
||||
'topic_list_import': {
|
||||
'task': 'app.tasks.forumtasks.importTopicList',
|
||||
'task': 'app.tasks.forumtasks.import_topic_list',
|
||||
'schedule': crontab(minute=1, hour=1), # 0101
|
||||
},
|
||||
'package_score_update': {
|
||||
'task': 'app.tasks.pkgtasks.updatePackageScores',
|
||||
'task': 'app.tasks.pkgtasks.update_package_scores',
|
||||
'schedule': crontab(minute=10, hour=1), # 0110
|
||||
},
|
||||
'check_for_updates': {
|
||||
|
@ -23,7 +23,7 @@ from flask_mail import Message
|
||||
from app import mail
|
||||
from app.models import Notification, db, EmailSubscription, User
|
||||
from app.tasks import celery
|
||||
from app.utils import abs_url_for, abs_url, randomString
|
||||
from app.utils import abs_url_for, abs_url, random_string
|
||||
|
||||
|
||||
def get_email_subscription(email):
|
||||
@ -31,7 +31,7 @@ def get_email_subscription(email):
|
||||
ret = EmailSubscription.query.filter_by(email=email).first()
|
||||
if not ret:
|
||||
ret = EmailSubscription(email)
|
||||
ret.token = randomString(32)
|
||||
ret.token = random_string(32)
|
||||
db.session.add(ret)
|
||||
db.session.commit()
|
||||
|
||||
|
@ -23,15 +23,15 @@ from urllib.parse import urljoin
|
||||
from app.models import User, db, PackageType, ForumTopic
|
||||
from app.tasks import celery
|
||||
from app.utils import is_username_valid
|
||||
from app.utils.phpbbparser import getProfile, getTopicsFromForum
|
||||
from app.utils.phpbbparser import get_profile, get_topics_from_forum
|
||||
from .usertasks import set_profile_picture_from_url
|
||||
|
||||
|
||||
@celery.task()
|
||||
def checkForumAccount(forums_username):
|
||||
def check_forum_account(forums_username):
|
||||
print("### Checking " + forums_username, file=sys.stderr)
|
||||
try:
|
||||
profile = getProfile("https://forum.minetest.net", forums_username)
|
||||
profile = get_profile("https://forum.minetest.net", forums_username)
|
||||
except OSError as e:
|
||||
print(e, file=sys.stderr)
|
||||
return
|
||||
@ -42,7 +42,7 @@ def checkForumAccount(forums_username):
|
||||
user = User.query.filter_by(forums_username=forums_username).first()
|
||||
|
||||
# Create user
|
||||
needsSaving = False
|
||||
needs_saving = False
|
||||
if user is None:
|
||||
user = User(forums_username)
|
||||
user.forums_username = forums_username
|
||||
@ -53,14 +53,14 @@ def checkForumAccount(forums_username):
|
||||
if github_username is not None and github_username.strip() != "":
|
||||
print("Updated GitHub username for " + user.display_name + " to " + github_username)
|
||||
user.github_username = github_username
|
||||
needsSaving = True
|
||||
needs_saving = True
|
||||
|
||||
pic = profile.avatar
|
||||
if pic and pic.startswith("http"):
|
||||
pic = None
|
||||
|
||||
# Save
|
||||
if needsSaving:
|
||||
if needs_saving:
|
||||
db.session.commit()
|
||||
|
||||
if pic:
|
||||
@ -74,21 +74,21 @@ def checkForumAccount(forums_username):
|
||||
print(f"####### Queueing", file=sys.stderr)
|
||||
set_profile_picture_from_url.delay(user.username, pic)
|
||||
|
||||
return needsSaving
|
||||
return needs_saving
|
||||
|
||||
|
||||
@celery.task()
|
||||
def checkAllForumAccounts():
|
||||
def check_all_forum_accounts():
|
||||
query = User.query.filter(User.forums_username.isnot(None))
|
||||
for user in query.all():
|
||||
checkForumAccount(user.forums_username)
|
||||
check_forum_account(user.forums_username)
|
||||
|
||||
|
||||
regex_tag = re.compile(r"\[([a-z0-9_]+)\]")
|
||||
BANNED_NAMES = ["mod", "game", "old", "outdated", "wip", "api", "beta", "alpha", "git"]
|
||||
|
||||
|
||||
def getNameFromTaglist(taglist):
|
||||
def get_name_from_taglist(taglist):
|
||||
for tag in reversed(regex_tag.findall(taglist)):
|
||||
if len(tag) < 30 and not tag in BANNED_NAMES and \
|
||||
not re.match(r"^[a-z]?[0-9]+$", tag):
|
||||
@ -100,15 +100,16 @@ def getNameFromTaglist(taglist):
|
||||
regex_title = re.compile(r"^((?:\[[^\]]+\] *)*)([^\[]+) *((?:\[[^\]]+\] *)*)[^\[]*$")
|
||||
|
||||
|
||||
def parseTitle(title):
|
||||
def parse_title(title):
|
||||
m = regex_title.match(title)
|
||||
if m is None:
|
||||
print("Invalid title format: " + title)
|
||||
return title, getNameFromTaglist(title)
|
||||
return title, get_name_from_taglist(title)
|
||||
else:
|
||||
return m.group(2).strip(), getNameFromTaglist(m.group(3))
|
||||
return m.group(2).strip(), get_name_from_taglist(m.group(3))
|
||||
|
||||
def getLinksFromModSearch():
|
||||
|
||||
def get_links_from_mod_search():
|
||||
links = {}
|
||||
|
||||
try:
|
||||
@ -127,15 +128,16 @@ def getLinksFromModSearch():
|
||||
|
||||
return links
|
||||
|
||||
|
||||
@celery.task()
|
||||
def importTopicList():
|
||||
links_by_id = getLinksFromModSearch()
|
||||
def import_topic_list():
|
||||
links_by_id = get_links_from_mod_search()
|
||||
|
||||
info_by_id = {}
|
||||
getTopicsFromForum(11, out=info_by_id, extra={ 'type': PackageType.MOD, 'wip': False })
|
||||
getTopicsFromForum(9, out=info_by_id, extra={ 'type': PackageType.MOD, 'wip': True })
|
||||
getTopicsFromForum(15, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': False })
|
||||
getTopicsFromForum(50, out=info_by_id, extra={ 'type': PackageType.GAME, 'wip': True })
|
||||
get_topics_from_forum(11, out=info_by_id, extra={'type': PackageType.MOD, 'wip': False})
|
||||
get_topics_from_forum(9, out=info_by_id, extra={'type': PackageType.MOD, 'wip': True})
|
||||
get_topics_from_forum(15, out=info_by_id, extra={'type': PackageType.GAME, 'wip': False})
|
||||
get_topics_from_forum(50, out=info_by_id, extra={'type': PackageType.GAME, 'wip': True})
|
||||
|
||||
# Caches
|
||||
username_to_user = {}
|
||||
@ -182,7 +184,7 @@ def importTopicList():
|
||||
db.session.add(topic)
|
||||
|
||||
# Parse title
|
||||
title, name = parseTitle(info["title"])
|
||||
title, name = parse_title(info["title"])
|
||||
|
||||
# Get link
|
||||
link = links_by_id.get(id)
|
||||
|
@ -30,7 +30,7 @@ from kombu import uuid
|
||||
from app.models import AuditSeverity, db, NotificationType, PackageRelease, MetaPackage, Dependency, PackageType, \
|
||||
MinetestRelease, Package, PackageState, PackageScreenshot, PackageUpdateTrigger, PackageUpdateConfig
|
||||
from app.tasks import celery, TaskError
|
||||
from app.utils import randomString, post_bot_message, addSystemNotification, addSystemAuditLog, get_games_from_csv
|
||||
from app.utils import random_string, post_bot_message, add_system_notification, add_system_audit_log, get_games_from_csv
|
||||
from app.utils.git import clone_repo, get_latest_tag, get_latest_commit, get_temp_dir
|
||||
from .minetestcheck import build_tree, MinetestCheckError, ContentType
|
||||
from app import app
|
||||
@ -41,7 +41,7 @@ from app.utils.image import get_image_size
|
||||
|
||||
|
||||
@celery.task()
|
||||
def getMeta(urlstr, author):
|
||||
def get_meta(urlstr, author):
|
||||
with clone_repo(urlstr, recursive=True) as repo:
|
||||
try:
|
||||
tree = build_tree(repo.working_tree_dir, author=author, repo=urlstr)
|
||||
@ -82,13 +82,13 @@ def getMeta(urlstr, author):
|
||||
|
||||
|
||||
@celery.task()
|
||||
def updateAllGameSupport():
|
||||
def update_all_game_support():
|
||||
resolver = GameSupportResolver(db.session)
|
||||
resolver.init_all()
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def postReleaseCheckUpdate(self, release: PackageRelease, path):
|
||||
def post_release_check_update(self, release: PackageRelease, path):
|
||||
try:
|
||||
tree = build_tree(path, expected_type=ContentType[release.package.type.name],
|
||||
author=release.package.author.username, name=release.package.name)
|
||||
@ -97,14 +97,14 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
|
||||
raise MinetestCheckError(f"Expected {tree.relative} to have technical name {release.package.name}, instead has name {tree.name}")
|
||||
|
||||
cache = {}
|
||||
def getMetaPackages(names):
|
||||
def get_meta_packages(names):
|
||||
return [ MetaPackage.GetOrCreate(x, cache) for x in names ]
|
||||
|
||||
provides = tree.get_mod_names()
|
||||
|
||||
package = release.package
|
||||
package.provides.clear()
|
||||
package.provides.extend(getMetaPackages(tree.get_mod_names()))
|
||||
package.provides.extend(get_meta_packages(tree.get_mod_names()))
|
||||
|
||||
# Delete all mod name dependencies
|
||||
package.dependencies.filter(Dependency.meta_package != None).delete()
|
||||
@ -124,10 +124,10 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
|
||||
raise MinetestCheckError("Game has unresolved hard dependencies: " + deps)
|
||||
|
||||
# Add dependencies
|
||||
for meta in getMetaPackages(depends):
|
||||
for meta in get_meta_packages(depends):
|
||||
db.session.add(Dependency(package, meta=meta, optional=False))
|
||||
|
||||
for meta in getMetaPackages(optional_depends):
|
||||
for meta in get_meta_packages(optional_depends):
|
||||
db.session.add(Dependency(package, meta=meta, optional=True))
|
||||
|
||||
# Update min/max
|
||||
@ -191,7 +191,7 @@ def postReleaseCheckUpdate(self, release: PackageRelease, path):
|
||||
|
||||
|
||||
@celery.task(bind=True)
|
||||
def checkZipRelease(self, id, path):
|
||||
def check_zip_release(self, id, path):
|
||||
release = PackageRelease.query.get(id)
|
||||
if release is None:
|
||||
raise TaskError("No such release!")
|
||||
@ -202,7 +202,7 @@ def checkZipRelease(self, id, path):
|
||||
with ZipFile(path, 'r') as zip_ref:
|
||||
zip_ref.extractall(temp)
|
||||
|
||||
postReleaseCheckUpdate(self, release, temp)
|
||||
post_release_check_update(self, release, temp)
|
||||
|
||||
release.task_id = None
|
||||
release.approve(release.package.author)
|
||||
@ -210,7 +210,7 @@ def checkZipRelease(self, id, path):
|
||||
|
||||
|
||||
@celery.task(bind=True)
|
||||
def makeVCSRelease(self, id, branch):
|
||||
def make_vcs_release(self, id, branch):
|
||||
release = PackageRelease.query.get(id)
|
||||
if release is None:
|
||||
raise TaskError("No such release!")
|
||||
@ -218,9 +218,9 @@ def makeVCSRelease(self, id, branch):
|
||||
raise TaskError("No package attached to release")
|
||||
|
||||
with clone_repo(release.package.repo, ref=branch, recursive=True) as repo:
|
||||
postReleaseCheckUpdate(self, release, repo.working_tree_dir)
|
||||
post_release_check_update(self, release, repo.working_tree_dir)
|
||||
|
||||
filename = randomString(10) + ".zip"
|
||||
filename = random_string(10) + ".zip"
|
||||
destPath = os.path.join(app.config["UPLOAD_DIR"], filename)
|
||||
|
||||
assert(not os.path.isfile(destPath))
|
||||
@ -238,7 +238,7 @@ def makeVCSRelease(self, id, branch):
|
||||
|
||||
|
||||
@celery.task()
|
||||
def importRepoScreenshot(id):
|
||||
def import_repo_screenshot(id):
|
||||
package = Package.query.get(id)
|
||||
if package is None or package.state == PackageState.DELETED:
|
||||
raise Exception("Unexpected none package")
|
||||
@ -248,7 +248,7 @@ def importRepoScreenshot(id):
|
||||
for ext in ["png", "jpg", "jpeg"]:
|
||||
sourcePath = repo.working_tree_dir + "/screenshot." + ext
|
||||
if os.path.isfile(sourcePath):
|
||||
filename = randomString(10) + "." + ext
|
||||
filename = random_string(10) + "." + ext
|
||||
destPath = os.path.join(app.config["UPLOAD_DIR"], filename)
|
||||
shutil.copyfile(sourcePath, destPath)
|
||||
|
||||
@ -313,11 +313,11 @@ def check_update_config_impl(package):
|
||||
db.session.add(rel)
|
||||
|
||||
msg = "Created release {} (Git Update Detection)".format(rel.title)
|
||||
addSystemAuditLog(AuditSeverity.NORMAL, msg, package.get_url("packages.view"), package)
|
||||
add_system_audit_log(AuditSeverity.NORMAL, msg, package.get_url("packages.view"), package)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
makeVCSRelease.apply_async((rel.id, commit), task_id=rel.task_id)
|
||||
make_vcs_release.apply_async((rel.id, commit), task_id=rel.task_id)
|
||||
|
||||
elif config.outdated_at is None:
|
||||
config.set_outdated()
|
||||
@ -338,8 +338,8 @@ def check_update_config_impl(package):
|
||||
.format(tag, msg_last)
|
||||
|
||||
for user in package.maintainers:
|
||||
addSystemNotification(user, NotificationType.BOT,
|
||||
msg, url_for("todo.view_user", username=user.username, _external=False), package)
|
||||
add_system_notification(user, NotificationType.BOT,
|
||||
msg, url_for("todo.view_user", username=user.username, _external=False), package)
|
||||
|
||||
config.last_commit = commit
|
||||
config.last_tag = tag
|
||||
|
@ -19,7 +19,7 @@ from app.models import Package, db
|
||||
from app.tasks import celery
|
||||
|
||||
@celery.task()
|
||||
def updatePackageScores():
|
||||
def update_package_scores():
|
||||
Package.query.update({ "score_downloads": Package.score_downloads * 0.95 })
|
||||
db.session.commit()
|
||||
|
||||
|
@ -23,7 +23,7 @@ from sqlalchemy import or_, and_
|
||||
|
||||
from app import app
|
||||
from app.models import User, db, UserRank, ThreadReply, Package
|
||||
from app.utils import randomString
|
||||
from app.utils import random_string
|
||||
from app.utils.models import create_session
|
||||
from app.tasks import celery, TaskError
|
||||
|
||||
@ -76,7 +76,7 @@ def set_profile_picture_from_url(username: str, url: str):
|
||||
else:
|
||||
raise TaskError(f"Unacceptable content-type: {content_type}")
|
||||
|
||||
filename = randomString(10) + "." + ext
|
||||
filename = random_string(10) + "." + ext
|
||||
filepath = os.path.join(app.config["UPLOAD_DIR"], filename)
|
||||
with open(filepath, "wb") as f:
|
||||
size = 0
|
||||
|
@ -147,10 +147,10 @@
|
||||
{{ _("Statistics") }}
|
||||
</a>
|
||||
</li>
|
||||
{% if current_user.rank.atLeast(current_user.rank.EDITOR) or check_global_perm(current_user, "CREATE_TAG") %}
|
||||
{% if current_user.rank.at_least(current_user.rank.EDITOR) or check_global_perm(current_user, "CREATE_TAG") %}
|
||||
<li class="dropdown-divider"></li>
|
||||
{% endif %}
|
||||
{% if current_user.rank.atLeast(current_user.rank.MODERATOR) %}
|
||||
{% if current_user.rank.at_least(current_user.rank.MODERATOR) %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ url_for('admin.audit') }}">
|
||||
{{ _("Audit Log") }}
|
||||
@ -164,7 +164,7 @@
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if current_user.rank.atLeast(current_user.rank.EDITOR) %}
|
||||
{% if current_user.rank.at_least(current_user.rank.EDITOR) %}
|
||||
<li class="nav-item"><a class="nav-link" href="{{ url_for('admin.restore') }}">{{ _("Restore Package") }}</a></li>
|
||||
{% endif %}
|
||||
{% if check_global_perm(current_user, "EDIT_TAGS") %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% macro render_review_vote(review, current_user, next_url) %}
|
||||
{% set (positive, negative, is_positive) = review.get_totals(current_user) %}
|
||||
<form class="-group" method="post" action="{{ review.getVoteUrl(next_url) }}">
|
||||
<form class="-group" method="post" action="{{ review.get_vote_url(next_url) }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<div class="btn-group">
|
||||
<button class="btn {% if is_positive == true %}btn-primary{% else %}btn-secondary{% endif %}" name="is_positive" value="yes">
|
||||
|
@ -25,7 +25,7 @@
|
||||
<td class="btn-group">
|
||||
{% 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) }}">
|
||||
href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.get_repo_url(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
|
||||
{{ _("Create") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
@ -61,7 +61,7 @@
|
||||
{% endif %}
|
||||
{% if topic.author == current_user or topic.author.check_perm(current_user, "CHANGE_AUTHOR") %}
|
||||
|
|
||||
<a href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.getRepoURL(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
|
||||
<a href="{{ url_for('packages.create_edit', author=topic.author.username, repo=topic.get_repo_url(), forums=topic.topic_id, title=topic.title, bname=topic.name) }}">
|
||||
{{ _("Create") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
@ -323,7 +323,7 @@
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% if current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.ADMIN) %}
|
||||
{% if current_user.is_authenticated and current_user.rank.at_least(current_user.rank.ADMIN) %}
|
||||
<a href="{{ package.get_url('packages.review_votes') }}" class="btn btn-secondary">{{ _("Review Votes") }}</a>
|
||||
{% endif %}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
{% block content %}
|
||||
<h2 class="mb-4">{{ _("Approval Queue") }}</h2>
|
||||
{% if canApproveScn and screenshots %}
|
||||
{% if can_approve_scn and screenshots %}
|
||||
<div class="card my-4">
|
||||
<h3 class="card-header">{{ _("Screenshots") }}
|
||||
<form class="float-right" method="post" action="{{ url_for('todo.view_editor') }}">
|
||||
@ -40,7 +40,7 @@
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
{% if canApproveNew and (packages or wip_packages) %}
|
||||
{% if can_approve_new and (packages or wip_packages) %}
|
||||
<div class="col-sm-6">
|
||||
<div class="card">
|
||||
<h3 class="card-header">{{ _("Packages") }}</h3>
|
||||
@ -69,7 +69,7 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if canApproveRel and releases %}
|
||||
{% if can_approve_rel and releases %}
|
||||
<div class="col-sm-6">
|
||||
<div class="card">
|
||||
<h3 class="card-header">{{ _("Releases") }}</h3>
|
||||
@ -159,7 +159,7 @@
|
||||
|
||||
<h2 class="mt-5">{{ _("WIP") }}</h2>
|
||||
|
||||
{% if canApproveNew and (packages or wip_packages) %}
|
||||
{% if can_approve_new and (packages or wip_packages) %}
|
||||
<div class="card">
|
||||
<h3 class="card-header">WIP Packages</h3>
|
||||
<div class="list-group list-group-flush" style="max-height: 300px; overflow: hidden auto;">
|
||||
@ -188,7 +188,7 @@
|
||||
|
||||
|
||||
<div class="mt-5"></div>
|
||||
{% if current_user.rank.atLeast(current_user.rank.MODERATOR) %}
|
||||
{% if current_user.rank.at_least(current_user.rank.MODERATOR) %}
|
||||
<a class="btn btn-secondary float-right" href="{{ url_for('admin.audit') }}">
|
||||
{{ _("View All") }}
|
||||
</a>
|
||||
|
@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block container %}
|
||||
{% if current_user.rank.atLeast(current_user.rank.APPROVER) %}
|
||||
{% if current_user.rank.at_least(current_user.rank.APPROVER) %}
|
||||
<nav class="pt-4 tabs-container">
|
||||
<div class="container">
|
||||
<ul class="nav nav-tabs">
|
||||
@ -47,7 +47,7 @@
|
||||
{% endif %}
|
||||
|
||||
<main class="container mt-5">
|
||||
{% if not current_user.rank.atLeast(current_user.rank.APPROVER) %}
|
||||
{% if not current_user.rank.at_least(current_user.rank.APPROVER) %}
|
||||
<h1 class="mb-5">{{ self.title() }}</h1>
|
||||
{% endif %}
|
||||
|
||||
|
@ -22,7 +22,7 @@ Topics to be Added
|
||||
</div>
|
||||
|
||||
<div class="btn-group btn-group-sm">
|
||||
{% if current_user.rank.atLeast(current_user.rank.APPROVER) %}
|
||||
{% if current_user.rank.at_least(current_user.rank.APPROVER) %}
|
||||
{% if n >= 10000 %}
|
||||
<a class="btn btn-secondary"
|
||||
href="{{ url_for('todo.topics', q=query, show_discarded=show_discarded, n=100, sort=sort_by) }}">
|
||||
|
@ -68,7 +68,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
{% if current_user.rank.atLeast(current_user.rank.MODERATOR) %}
|
||||
{% if current_user.rank.at_least(current_user.rank.MODERATOR) %}
|
||||
<a class="btn btn-secondary float-right" href="{{ url_for('admin.audit', username=user.username) }}">
|
||||
{{ _("View All") }}
|
||||
</a>
|
||||
@ -81,7 +81,7 @@
|
||||
|
||||
<h3>{{ _("Account Deletion and Deactivation") }}</h3>
|
||||
|
||||
{% if current_user.rank.atLeast(current_user.rank.ADMIN) %}
|
||||
{% if current_user.rank.at_least(current_user.rank.ADMIN) %}
|
||||
<a class="btn btn-danger" href="{{ url_for('users.delete', username=user.username) }}">
|
||||
{{ _("Delete or Deactivate") }}</a>
|
||||
{% else %}
|
||||
|
@ -36,7 +36,7 @@
|
||||
name="deactivate" value="{{ _('Deactivate') }}"
|
||||
{% endif %}
|
||||
class="btn btn-danger" />
|
||||
{% if not can_delete and current_user.rank.atLeast(current_user.rank.ADMIN) %}
|
||||
{% if not can_delete and current_user.rank.at_least(current_user.rank.ADMIN) %}
|
||||
<input type="submit" name="delete" value="{{ _('Delete Anyway') }}" class="btn btn-danger ml-3" />
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -39,7 +39,7 @@
|
||||
<p class="text-danger">{{ _("Doesn't have password") }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if not user.rank.atLeast(current_user.rank) %}
|
||||
{% if not user.rank.at_least(current_user.rank) %}
|
||||
<h3>{{ _("Ban") }}</h3>
|
||||
{% if user.ban %}
|
||||
<p>
|
||||
|
@ -28,8 +28,8 @@
|
||||
{{ _("Report") }}
|
||||
</a>
|
||||
|
||||
{% if current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.MODERATOR) %}
|
||||
{% if not user.rank.atLeast(current_user.rank) %}
|
||||
{% if current_user.is_authenticated and current_user.rank.at_least(current_user.rank.MODERATOR) %}
|
||||
{% if not user.rank.at_least(current_user.rank) %}
|
||||
<a class="btn btn-secondary float-right mr-3" href="{{ url_for('users.modtools', username=user.username) }}">
|
||||
<i class="fas fa-user-shield mr-1"></i>
|
||||
{{ _("Moderator Tools") }}
|
||||
@ -164,7 +164,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if current_user == user or (current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.ADMIN)) %}
|
||||
{% if current_user == user or (current_user.is_authenticated and current_user.rank.at_least(current_user.rank.ADMIN)) %}
|
||||
{% for medal in medals_locked %}
|
||||
{% set value = medal.progress[0] %}
|
||||
{% set target = medal.progress[1] %}
|
||||
@ -202,7 +202,7 @@
|
||||
{{ _("Create package") }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if current_user == user or (current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.EDITOR)) %}
|
||||
{% if current_user == user or (current_user.is_authenticated and current_user.rank.at_least(current_user.rank.EDITOR)) %}
|
||||
<a class="float-right btn btn-sm btn-secondary mr-2"
|
||||
href="{{ url_for('todo.tags', author=user.username) }}">
|
||||
{{ _("View list of tags") }}
|
||||
|
@ -33,27 +33,27 @@ def is_username_valid(username):
|
||||
re.match(r"^[A-Za-z0-9._-]*$", username) and not re.match(r"^\.*$", username)
|
||||
|
||||
|
||||
def isYes(val):
|
||||
def is_yes(val):
|
||||
return val and val.lower() in YESES
|
||||
|
||||
|
||||
def isNo(val):
|
||||
return val and not isYes(val)
|
||||
def is_no(val):
|
||||
return val and not is_yes(val)
|
||||
|
||||
|
||||
def nonEmptyOrNone(str):
|
||||
def nonempty_or_none(str):
|
||||
if str is None or str == "":
|
||||
return None
|
||||
|
||||
return str
|
||||
|
||||
|
||||
def shouldReturnJson():
|
||||
def should_return_json():
|
||||
return "application/json" in request.accept_mimetypes and \
|
||||
not "text/html" in request.accept_mimetypes
|
||||
|
||||
|
||||
def randomString(n):
|
||||
def random_string(n):
|
||||
return secrets.token_hex(int(n / 2))
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ from urllib.parse import urlsplit
|
||||
from git import GitCommandError
|
||||
|
||||
from app.tasks import TaskError
|
||||
from app.utils import randomString
|
||||
from app.utils import random_string
|
||||
|
||||
|
||||
def generate_git_url(urlstr):
|
||||
@ -40,7 +40,7 @@ def generate_git_url(urlstr):
|
||||
|
||||
@contextlib.contextmanager
|
||||
def get_temp_dir():
|
||||
temp = os.path.join(tempfile.gettempdir(), randomString(10))
|
||||
temp = os.path.join(tempfile.gettempdir(), random_string(10))
|
||||
yield temp
|
||||
shutil.rmtree(temp)
|
||||
|
||||
@ -50,21 +50,21 @@ def get_temp_dir():
|
||||
# Throws `TaskError` on failure.
|
||||
# Caller is responsible for deleting returned directory.
|
||||
@contextlib.contextmanager
|
||||
def clone_repo(urlstr, ref=None, recursive=False):
|
||||
gitDir = os.path.join(tempfile.gettempdir(), randomString(10))
|
||||
def clone_repo(url_str, ref=None, recursive=False):
|
||||
git_dir = os.path.join(tempfile.gettempdir(), random_string(10))
|
||||
|
||||
try:
|
||||
gitUrl = generate_git_url(urlstr)
|
||||
print("Cloning from " + gitUrl)
|
||||
git_url = generate_git_url(url_str)
|
||||
print("Cloning from " + git_url)
|
||||
|
||||
if ref is None:
|
||||
repo = git.Repo.clone_from(gitUrl, gitDir,
|
||||
repo = git.Repo.clone_from(git_url, git_dir,
|
||||
progress=None, env=None, depth=1, recursive=recursive, kill_after_timeout=15)
|
||||
else:
|
||||
assert ref != ""
|
||||
|
||||
repo = git.Repo.init(gitDir)
|
||||
origin = repo.create_remote("origin", url=gitUrl)
|
||||
repo = git.Repo.init(git_dir)
|
||||
origin = repo.create_remote("origin", url=git_url)
|
||||
assert origin.exists()
|
||||
origin.fetch()
|
||||
repo.git.checkout(ref)
|
||||
@ -72,7 +72,7 @@ def clone_repo(urlstr, ref=None, recursive=False):
|
||||
repo.git.submodule('update', '--init')
|
||||
|
||||
yield repo
|
||||
shutil.rmtree(gitDir)
|
||||
shutil.rmtree(git_dir)
|
||||
return
|
||||
|
||||
except GitCommandError as e:
|
||||
@ -83,7 +83,7 @@ def clone_repo(urlstr, ref=None, recursive=False):
|
||||
err = "Unable to find the reference " + (ref or "?") + "\n" + e.stderr
|
||||
|
||||
raise TaskError(err.replace("stderr: ", "") \
|
||||
.replace("Cloning into '" + gitDir + "'...", "") \
|
||||
.replace("Cloning into '" + git_dir + "'...", "") \
|
||||
.strip())
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ from sqlalchemy.orm import sessionmaker
|
||||
from app.models import User, NotificationType, Package, UserRank, Notification, db, AuditSeverity, AuditLogEntry, ThreadReply, Thread, PackageState, PackageType, PackageAlias
|
||||
|
||||
|
||||
def getPackageByInfo(author, name):
|
||||
def get_package_by_info(author, name):
|
||||
user = User.query.filter_by(username=author).first()
|
||||
if user is None:
|
||||
return None
|
||||
@ -39,6 +39,7 @@ def getPackageByInfo(author, name):
|
||||
|
||||
return package
|
||||
|
||||
|
||||
def is_package_page(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
@ -48,9 +49,9 @@ def is_package_page(f):
|
||||
author = kwargs["author"]
|
||||
name = kwargs["name"]
|
||||
|
||||
package = getPackageByInfo(author, name)
|
||||
package = get_package_by_info(author, name)
|
||||
if package is None:
|
||||
package = getPackageByInfo(author, name + "_game")
|
||||
package = get_package_by_info(author, name + "_game")
|
||||
if package and package.type == PackageType.GAME:
|
||||
args = dict(kwargs)
|
||||
args["name"] = name + "_game"
|
||||
@ -72,28 +73,28 @@ def is_package_page(f):
|
||||
return decorated_function
|
||||
|
||||
|
||||
def addNotification(target, causer: User, type: NotificationType, title: str, url: str, package: Package = None):
|
||||
def add_notification(target, causer: User, type: NotificationType, title: str, url: str, package: Package = None):
|
||||
try:
|
||||
iter(target)
|
||||
for x in target:
|
||||
addNotification(x, causer, type, title, url, package)
|
||||
add_notification(x, causer, type, title, url, package)
|
||||
return
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
if target.rank.atLeast(UserRank.NEW_MEMBER) and target != causer:
|
||||
if target.rank.at_least(UserRank.NEW_MEMBER) and target != causer:
|
||||
Notification.query.filter_by(user=target, causer=causer, type=type, title=title, url=url, package=package).delete()
|
||||
notif = Notification(target, causer, type, title, url, package)
|
||||
db.session.add(notif)
|
||||
|
||||
|
||||
def addAuditLog(severity: AuditSeverity, causer: User, title: str, url: typing.Optional[str],
|
||||
package: Package = None, description: str = None):
|
||||
def add_audit_log(severity: AuditSeverity, causer: User, title: str, url: typing.Optional[str],
|
||||
package: Package = None, description: str = None):
|
||||
entry = AuditLogEntry(causer, severity, title, url, package, description)
|
||||
db.session.add(entry)
|
||||
|
||||
|
||||
def clearNotifications(url):
|
||||
def clear_notifications(url):
|
||||
if current_user.is_authenticated:
|
||||
Notification.query.filter_by(user=current_user, url=url).delete()
|
||||
db.session.commit()
|
||||
@ -105,12 +106,12 @@ def get_system_user():
|
||||
return system_user
|
||||
|
||||
|
||||
def addSystemNotification(target, type: NotificationType, title: str, url: str, package: Package = None):
|
||||
return addNotification(target, get_system_user(), type, title, url, package)
|
||||
def add_system_notification(target, type: NotificationType, title: str, url: str, package: Package = None):
|
||||
return add_notification(target, get_system_user(), type, title, url, package)
|
||||
|
||||
|
||||
def addSystemAuditLog(severity: AuditSeverity, title: str, url: str, package=None, description=None):
|
||||
return addAuditLog(severity, get_system_user(), title, url, package, description)
|
||||
def add_system_audit_log(severity: AuditSeverity, title: str, url: str, package=None, description=None):
|
||||
return add_audit_log(severity, get_system_user(), title, url, package, description)
|
||||
|
||||
|
||||
def post_bot_message(package: Package, title: str, message: str):
|
||||
@ -133,8 +134,7 @@ def post_bot_message(package: Package, title: str, message: str):
|
||||
reply.comment = "**{}**\n\n{}\n\nThis is an automated message, but you can reply if you need help".format(title, message)
|
||||
db.session.add(reply)
|
||||
|
||||
addNotification(thread.watchers, system_user, NotificationType.BOT,
|
||||
title, thread.get_view_url(), thread.package)
|
||||
add_notification(thread.watchers, system_user, NotificationType.BOT, title, thread.get_view_url(), thread.package)
|
||||
|
||||
thread.replies.append(reply)
|
||||
|
||||
|
@ -12,9 +12,10 @@ from urllib.parse import urlencode
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
def urlEncodeNonAscii(b):
|
||||
def url_encode_non_ascii(b):
|
||||
return re.sub('[\x80-\xFF]', lambda c: '%%%02x' % ord(c.group(0)), b)
|
||||
|
||||
|
||||
class Profile:
|
||||
def __init__(self, username):
|
||||
self.username = username
|
||||
@ -31,6 +32,7 @@ class Profile:
|
||||
def __str__(self):
|
||||
return self.username + "\n" + str(self.signature) + "\n" + str(self.properties)
|
||||
|
||||
|
||||
def __extract_properties(profile, soup):
|
||||
el = soup.find(id="viewprofile")
|
||||
if el is None:
|
||||
@ -66,6 +68,7 @@ def __extract_properties(profile, soup):
|
||||
elif element and element.name is not None:
|
||||
print("Unexpected other")
|
||||
|
||||
|
||||
def __extract_signature(soup):
|
||||
res = soup.find_all("div", class_="signature")
|
||||
if len(res) != 1:
|
||||
@ -74,7 +77,7 @@ def __extract_signature(soup):
|
||||
return str(res[0])
|
||||
|
||||
|
||||
def getProfileURL(url, username):
|
||||
def get_profile_url(url, username):
|
||||
url = urlparse.urlparse(url)
|
||||
|
||||
# Update path
|
||||
@ -89,8 +92,8 @@ def getProfileURL(url, username):
|
||||
return urlparse.urlunparse(url)
|
||||
|
||||
|
||||
def getProfile(url, username):
|
||||
url = getProfileURL(url, username)
|
||||
def get_profile(url, username):
|
||||
url = get_profile_url(url, username)
|
||||
|
||||
try:
|
||||
req = urllib.request.urlopen(url, timeout=15)
|
||||
@ -114,7 +117,8 @@ def getProfile(url, username):
|
||||
|
||||
regex_id = re.compile(r"^.*t=([0-9]+).*$")
|
||||
|
||||
def parseForumListPage(id, page, out, extra=None):
|
||||
|
||||
def parse_forum_list_page(id, page, out, extra=None):
|
||||
num_per_page = 30
|
||||
start = page*num_per_page+1
|
||||
print(" - Fetching page {} (topics {}-{})".format(page, start, start+num_per_page))
|
||||
@ -171,15 +175,11 @@ def parseForumListPage(id, page, out, extra=None):
|
||||
|
||||
return True
|
||||
|
||||
def getTopicsFromForum(id, out, extra=None):
|
||||
|
||||
def get_topics_from_forum(id, out, extra=None):
|
||||
print("Fetching all topics from forum {}".format(id))
|
||||
page = 0
|
||||
while parseForumListPage(id, page, out, extra):
|
||||
while parse_forum_list_page(id, page, out, extra):
|
||||
page = page + 1
|
||||
|
||||
return out
|
||||
|
||||
def dumpTitlesToFile(topics, path):
|
||||
with open(path, "w") as out_file:
|
||||
for topic in topics.values():
|
||||
out_file.write(topic["title"] + "\n")
|
||||
|
@ -76,7 +76,7 @@ def rank_required(rank):
|
||||
def decorated_function(*args, **kwargs):
|
||||
if not current_user.is_authenticated:
|
||||
return redirect(url_for("users.login"))
|
||||
if not current_user.rank.atLeast(rank):
|
||||
if not current_user.rank.at_least(rank):
|
||||
abort(403)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
Loading…
Reference in New Issue
Block a user