From 42841896d1f859ae0b26902c3832a926267532f2 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 25 Jun 2022 01:16:22 +0100 Subject: [PATCH] Add ability for editors to set game support --- app/blueprints/packages/packages.py | 33 +++++++++++++++++++++--- app/logic/game_support.py | 9 +++++-- app/models/packages.py | 3 ++- app/tasks/importtasks.py | 17 +----------- app/templates/macros/forms.html | 2 +- app/templates/packages/game_support.html | 23 +++++++++++++++++ app/utils/models.py | 18 +++++++++++++ 7 files changed, 81 insertions(+), 24 deletions(-) diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py index e7e100e..f2aafd9 100644 --- a/app/blueprints/packages/packages.py +++ b/app/blueprints/packages/packages.py @@ -36,6 +36,7 @@ from app.logic.LogicError import LogicError from app.logic.packages import do_edit_package from app.models.packages import PackageProvides from app.tasks.webhooktasks import post_discord_webhook +from ...logic.game_support import GameSupportResolver @bp.route("/packages/") @@ -626,16 +627,40 @@ def similar(package): packages_modnames=packages_modnames, similar_topics=similar_topics) -@bp.route("/packages///support/") +class GameSupportForm(FlaskForm): + supported = StringField(lazy_gettext("Supported games (Comma-separated)"), [Optional()]) + unsupported = StringField(lazy_gettext("Unsupported games (Comma-separated)"), [Optional()]) + submit = SubmitField(lazy_gettext("Save")) + + +@bp.route("/packages///support/", methods=["GET", "POST"]) @login_required @is_package_page def game_support(package): if package.type != PackageType.MOD: abort(404) - if not (package.checkPerm(current_user, Permission.EDIT_PACKAGE) or - package.checkPerm(current_user, Permission.APPROVE_NEW)): + can_edit = package.checkPerm(current_user, Permission.EDIT_PACKAGE) + if not (can_edit or package.checkPerm(current_user, Permission.APPROVE_NEW)): abort(403) - return render_template("packages/game_support.html", package=package, + form = GameSupportForm() if can_edit else None + if request.method == "GET": + manual_supported_games = package.supported_games.filter_by(confidence=8).all() + form.supported.data = ", ".join([x.game.name for x in manual_supported_games if x.supports]) + form.unsupported.data = ", ".join([x.game.name for x in manual_supported_games if not x.supports]) + + if form and form.validate_on_submit(): + resolver = GameSupportResolver() + game_is_supported = [] + for game in get_games_from_csv(form.supported.data or ""): + game_is_supported.append((game, True)) + for game in get_games_from_csv(form.unsupported.data or ""): + game_is_supported.append((game, False)) + resolver.set_supported(package, game_is_supported, 8) + db.session.commit() + + return redirect(package.getURL("packages.game_support")) + + return render_template("packages/game_support.html", package=package, form=form, tabs=get_package_tabs(current_user, package), current_tab="game_support") diff --git a/app/logic/game_support.py b/app/logic/game_support.py index 6348087..52c60c1 100644 --- a/app/logic/game_support.py +++ b/app/logic/game_support.py @@ -163,7 +163,7 @@ class GameSupportResolver: for package in Package.query.filter(Package.type == PackageType.MOD, Package.state != PackageState.DELETED).all(): retval = self.resolve(package, []) for game in retval: - support = PackageGameSupport(package, game, 1) + support = PackageGameSupport(package, game, 1, True) db.session.add(support) """ @@ -177,10 +177,15 @@ class GameSupportResolver: db.session.merge(support.game) previous_supported[support.game.id] = support + seen_game = {} for game, supports in game_is_supported: + if seen_game.get(game.id): + continue + + seen_game[game.id] = True lookup = previous_supported.pop(game.id, None) if lookup is None: - support = PackageGameSupport(package, game, confidence) + support = PackageGameSupport(package, game, confidence, supports) db.session.add(support) elif lookup.confidence <= confidence: lookup.supports = supports diff --git a/app/models/packages.py b/app/models/packages.py index ff362b2..e69f44b 100644 --- a/app/models/packages.py +++ b/app/models/packages.py @@ -358,10 +358,11 @@ class PackageGameSupport(db.Model): __table_args__ = (db.UniqueConstraint("game_id", "package_id", name="_package_game_support_uc"),) - def __init__(self, package, game, confidence): + def __init__(self, package, game, confidence, supports): self.package = package self.game = game self.confidence = confidence + self.supports = supports class Package(db.Model): diff --git a/app/tasks/importtasks.py b/app/tasks/importtasks.py index b125c20..fffd05a 100644 --- a/app/tasks/importtasks.py +++ b/app/tasks/importtasks.py @@ -20,11 +20,10 @@ from zipfile import ZipFile from git import GitCommandError from git_archive_all import GitArchiver from kombu import uuid -from sqlalchemy import or_, and_ from app.models import * from app.tasks import celery, TaskError -from app.utils import randomString, post_bot_message, addSystemNotification, addSystemAuditLog +from app.utils import randomString, post_bot_message, addSystemNotification, addSystemAuditLog, 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 ..logic.LogicError import LogicError @@ -74,20 +73,6 @@ def getMeta(urlstr, author): return result -def get_games_from_csv(csv: str) -> List[Package]: - retval = [] - supported_games_raw = csv.split(",") - for game_name in supported_games_raw: - game_name = game_name.strip() - if game_name.endswith("_game"): - game_name = game_name[:-5] - games = Package.query.filter(and_(Package.state==PackageState.APPROVED, Package.type==PackageType.GAME, - or_(Package.name==game_name, Package.name==game_name + "_game"))).all() - retval.extend(games) - - return retval - - def postReleaseCheckUpdate(self, release: PackageRelease, path): try: tree = build_tree(path, expected_type=ContentType[release.package.type.name], diff --git a/app/templates/macros/forms.html b/app/templates/macros/forms.html index 208b37e..203e508 100644 --- a/app/templates/macros/forms.html +++ b/app/templates/macros/forms.html @@ -117,7 +117,7 @@ {% if not label %}{% set label=field.label.text %}{% endif %}
{%- endmacro %} diff --git a/app/templates/packages/game_support.html b/app/templates/packages/game_support.html index 09a4034..d0a699d 100644 --- a/app/templates/packages/game_support.html +++ b/app/templates/packages/game_support.html @@ -7,6 +7,9 @@ {% block content %}

{{ self.title() }}

+

+ This feature is experimental +

{{ _("Read more") }} @@ -40,6 +43,8 @@ {% if support.confidence == 1 %} {{ _("Detected from dependencies") }} + {% elif support.confidence == 8 %} + {{ _("Added by Editor") }} {% elif support.confidence == 10 %} {{ _("mod.conf") }} {% else %} @@ -61,4 +66,22 @@ {% endfor %} + + + {% if form and package.checkPerm(current_user, "EDIT_PACKAGE") and current_user not in package.maintainers %} +

+ {{ _("Added by Editor") }} + +

+ + {% from "macros/forms.html" import render_field, render_checkbox_field, render_submit_field %} +
+ {{ form.hidden_tag() }} + + {{ render_field(form.supported) }} + {{ render_field(form.unsupported) }} + + {{ render_submit_field(form.submit, class_="mt-4 btn btn-primary") }} +
+ {% endif %} {% endblock %} diff --git a/app/utils/models.py b/app/utils/models.py index 30dc03d..3abe0c7 100644 --- a/app/utils/models.py +++ b/app/utils/models.py @@ -16,8 +16,12 @@ from functools import wraps +from typing import List + from flask import abort, redirect, url_for, request from flask_login import current_user +from sqlalchemy import or_, and_ + from app.models import User, NotificationType, Package, UserRank, Notification, db, AuditSeverity, AuditLogEntry, ThreadReply, Thread, PackageState, PackageType, PackageAlias @@ -130,3 +134,17 @@ def post_bot_message(package: Package, title: str, message: str): title, thread.getViewURL(), thread.package) thread.replies.append(reply) + + +def get_games_from_csv(csv: str) -> List[Package]: + retval = [] + supported_games_raw = csv.split(",") + for game_name in supported_games_raw: + game_name = game_name.strip() + if game_name.endswith("_game"): + game_name = game_name[:-5] + games = Package.query.filter(and_(Package.state==PackageState.APPROVED, Package.type==PackageType.GAME, + or_(Package.name==game_name, Package.name==game_name + "_game"))).all() + retval.extend(games) + + return retval