From 4bd53e4b1a19eeeceeb5bfaba642290868525480 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 20 Aug 2023 22:25:18 +0100 Subject: [PATCH] Use collections for spotlight and featured, remove protected tags --- app/blueprints/admin/tagseditor.py | 2 -- app/blueprints/api/endpoints.py | 14 +++++++++----- app/blueprints/homepage/__init__.py | 8 ++++++-- app/default_data.py | 11 +++++------ app/flatpages/help/api.md | 1 - app/logic/packages.py | 11 ----------- app/models/packages.py | 2 -- app/templates/admin/tags/edit.html | 4 ---- app/templates/index.html | 8 +++----- migrations/versions/7a749a6c8c3a_.py | 26 ++++++++++++++++++++++++++ 10 files changed, 49 insertions(+), 38 deletions(-) create mode 100644 migrations/versions/7a749a6c8c3a_.py diff --git a/app/blueprints/admin/tagseditor.py b/app/blueprints/admin/tagseditor.py index 10156a79..77454597 100644 --- a/app/blueprints/admin/tagseditor.py +++ b/app/blueprints/admin/tagseditor.py @@ -47,7 +47,6 @@ class TagForm(FlaskForm): description = TextAreaField("Description", [Optional(), Length(0, 500)]) name = StringField("Name", [Optional(), Length(1, 20), Regexp("^[a-z0-9_]", 0, "Lower case letters (a-z), digits (0-9), and underscores (_) only")]) - is_protected = BooleanField("Is Protected") submit = SubmitField("Save") @@ -69,7 +68,6 @@ def create_edit_tag(name=None): if tag is None: tag = Tag(form.title.data) tag.description = form.description.data - tag.is_protected = form.is_protected.data db.session.add(tag) add_audit_log(AuditSeverity.EDITOR, current_user, f"Created tag {tag.name}", diff --git a/app/blueprints/api/endpoints.py b/app/blueprints/api/endpoints.py index c9e80f46..22369a0c 100644 --- a/app/blueprints/api/endpoints.py +++ b/app/blueprints/api/endpoints.py @@ -21,6 +21,7 @@ from typing import List import flask_sqlalchemy from flask import request, jsonify, current_app, Response from flask_login import current_user, login_required +from sqlalchemy import and_ from sqlalchemy.orm import joinedload from sqlalchemy.sql.expression import func @@ -28,7 +29,7 @@ from app import csrf from app.logic.graphs import get_package_stats, get_package_stats_for_user, get_all_package_stats 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 + MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning, User, PackageReview, Thread, Collection from app.querybuilder import QueryBuilder from app.utils import is_package_page, get_int_or_abort, url_set_query, abs_url, is_yes, get_request_date from . import bp @@ -78,7 +79,8 @@ def packages(): # 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.convert_to_dictionary(query.filter(Package.tags.any(name="featured")).all()) + featured = qb.convert_to_dictionary(query.filter( + Package.collections.any(and_(Collection.name == "featured", Collection.author.has(username="ContentDB")))).all()) for pkg in featured: featured_lut.add(f"{pkg['author']}/{pkg['name']}") pkg["short_description"] = "Featured. " + pkg["short_description"] @@ -535,8 +537,9 @@ def homepage(): query = Package.query.filter_by(state=PackageState.APPROVED) count = query.count() - spotlight = query.filter(Package.tags.any(name="spotlight")).order_by( - func.random()).limit(6).all() + spotlight = query.filter( + Package.collections.any(and_(Collection.name == "featured", Collection.author.has(username="ContentDB")))) \ + .order_by(func.random()).limit(6).all() new = query.order_by(db.desc(Package.approved_at)).limit(4).all() pop_mod = query.filter_by(type=PackageType.MOD).order_by(db.desc(Package.score)).limit(8).all() pop_gam = query.filter_by(type=PackageType.GAME).order_by(db.desc(Package.score)).limit(8).all() @@ -574,7 +577,8 @@ def homepage(): def welcome_v1(): featured = Package.query \ .filter(Package.type == PackageType.GAME, Package.state == PackageState.APPROVED, - Package.tags.any(name="featured")) \ + Package.collections.any( + and_(Collection.name == "featured", Collection.author.has(username="ContentDB")))) \ .order_by(func.random()) \ .limit(5).all() diff --git a/app/blueprints/homepage/__init__.py b/app/blueprints/homepage/__init__.py index 381f25f7..8f58cad7 100644 --- a/app/blueprints/homepage/__init__.py +++ b/app/blueprints/homepage/__init__.py @@ -15,8 +15,10 @@ # along with this program. If not, see . from flask import Blueprint, render_template, redirect +from sqlalchemy import and_ -from app.models import Package, PackageReview, Thread, User, PackageState, db, PackageType, PackageRelease, Tags, Tag +from app.models import Package, PackageReview, Thread, User, PackageState, db, PackageType, PackageRelease, Tags, Tag, \ + Collection bp = Blueprint("homepage", __name__) @@ -49,7 +51,9 @@ def home(): query = Package.query.filter_by(state=PackageState.APPROVED) count = query.count() - spotlight_pkgs = query.filter(Package.tags.any(name="spotlight")).order_by(func.random()).limit(6).all() + spotlight_pkgs = query.filter( + Package.collections.any(and_(Collection.name == "featured", Collection.author.has(username="ContentDB")))) \ + .order_by(func.random()).limit(6).all() new = package_load(query.order_by(db.desc(Package.approved_at))).limit(4).all() pop_mod = package_load(query.filter_by(type=PackageType.MOD).order_by(db.desc(Package.score))).limit(8).all() diff --git a/app/default_data.py b/app/default_data.py index 63dd8770..917395bb 100644 --- a/app/default_data.py +++ b/app/default_data.py @@ -44,18 +44,17 @@ def populate(session): tags = {} for tag in ["Inventory", "Mapgen", "Building", - "Mobs and NPCs", "Tools", "Player effects", - "Environment", "Transport", "Maintenance", "Plants and farming", - "PvP", "PvE", "Survival", "Creative", "Puzzle", "Multiplayer", "Singleplayer", - "Featured", "Spotlight"]: + "Mobs and NPCs", "Tools", "Player effects", + "Environment", "Transport", "Maintenance", "Plants and farming", + "PvP", "PvE", "Survival", "Creative", "Puzzle", "Multiplayer", "Singleplayer"]: row = Tag(tag) tags[row.name] = row session.add(row) licenses = {} for license in ["GPLv2.1", "GPLv3", "LGPLv2.1", "LGPLv3", "AGPLv2.1", "AGPLv3", - "Apache", "BSD 3-Clause", "BSD 2-Clause", "CC0", "CC-BY-SA", - "CC-BY", "MIT", "ZLib", "Other (Free)"]: + "Apache", "BSD 3-Clause", "BSD 2-Clause", "CC0", "CC-BY-SA", + "CC-BY", "MIT", "ZLib", "Other (Free)"]: row = License(license) licenses[row.name] = row session.add(row) diff --git a/app/flatpages/help/api.md b/app/flatpages/help/api.md index 1862ed32..7220249f 100644 --- a/app/flatpages/help/api.md +++ b/app/flatpages/help/api.md @@ -451,7 +451,6 @@ Supported query parameters: * `name`: technical name. * `title`: human-readable title. * `description`: tag description or null. - * `is_protected`: boolean, whether the tag is protected (can only be set by Editors in the web interface). * `views`: number of views of this tag. ### Content Warnings diff --git a/app/logic/packages.py b/app/logic/packages.py index 09734d14..43b95448 100644 --- a/app/logic/packages.py +++ b/app/logic/packages.py @@ -170,19 +170,8 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool, if tag is None: raise LogicError(400, "Unknown tag: " + tag_id) - if not was_web and tag.is_protected: - continue - - 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) - if not was_web: - for tag in old_tags: - if tag.is_protected: - package.tags.append(tag) - if "content_warnings" in data: package.content_warnings.clear() for warning_id in (data["content_warnings"] or []): diff --git a/app/models/packages.py b/app/models/packages.py index 42303654..4cf6683e 100644 --- a/app/models/packages.py +++ b/app/models/packages.py @@ -865,7 +865,6 @@ class Tag(db.Model): backgroundColor = db.Column(db.String(6), nullable=False) textColor = db.Column(db.String(6), nullable=False) views = db.Column(db.Integer, nullable=False, default=0) - is_protected = db.Column(db.Boolean, nullable=False, default=False) packages = db.relationship("Package", back_populates="tags", secondary=Tags) @@ -884,7 +883,6 @@ class Tag(db.Model): "name": self.name, "title": self.title, "description": description, - "is_protected": self.is_protected, "views": self.views, } diff --git a/app/templates/admin/tags/edit.html b/app/templates/admin/tags/edit.html index 039c29a3..a8881833 100644 --- a/app/templates/admin/tags/edit.html +++ b/app/templates/admin/tags/edit.html @@ -21,10 +21,6 @@ {% if tag %} {{ render_field(form.name) }} {% endif %} -
- {{ render_checkbox_field(form.is_protected) }} - Whether non-Editors can add this tag to packages -
{{ render_submit_field(form.submit) }} {% if tag %} diff --git a/app/templates/index.html b/app/templates/index.html index 04e33537..c42fda9f 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -64,11 +64,9 @@ {% endfor %} {% for t in tags[:3] %} - {% if t.name != "featured" and t.name != "Spotlight" %} - - {{ t.title }} - - {% endif %} + + {{ t.title }} + {% endfor %} diff --git a/migrations/versions/7a749a6c8c3a_.py b/migrations/versions/7a749a6c8c3a_.py new file mode 100644 index 00000000..ad452e2f --- /dev/null +++ b/migrations/versions/7a749a6c8c3a_.py @@ -0,0 +1,26 @@ +"""empty message + +Revision ID: 7a749a6c8c3a +Revises: 20f2aa2f40b9 +Create Date: 2023-08-20 21:19:26.930069 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '7a749a6c8c3a' +down_revision = '20f2aa2f40b9' +branch_labels = None +depends_on = None + + +def upgrade(): + with op.batch_alter_table('tag', schema=None) as batch_op: + batch_op.drop_column('is_protected') + + +def downgrade(): + with op.batch_alter_table('tag', schema=None) as batch_op: + batch_op.add_column(sa.Column('is_protected', sa.BOOLEAN(), server_default=sa.text('false'), autoincrement=False, nullable=False))