From 07f5d2e0d52ea908e0e9f1c859fb6915831b8843 Mon Sep 17 00:00:00 2001
From: rubenwardy
Date: Sun, 5 Mar 2023 18:13:07 +0000
Subject: [PATCH] Add per-package donate URLs
---
app/blueprints/api/endpoints.py | 5 +++++
app/blueprints/donate/__init__.py | 17 ++++++++++++-----
app/blueprints/packages/packages.py | 4 +++-
app/flatpages/help/api.md | 1 +
app/flatpages/help/package_config.md | 1 +
app/logic/packages.py | 5 +++--
app/models/packages.py | 6 ++++++
app/templates/donate/index.html | 2 +-
app/templates/packages/create_edit.html | 1 +
app/templates/packages/view.html | 4 ++--
migrations/versions/aa53b4d36c50_.py | 23 +++++++++++++++++++++++
11 files changed, 58 insertions(+), 11 deletions(-)
create mode 100644 migrations/versions/aa53b4d36c50_.py
diff --git a/app/blueprints/api/endpoints.py b/app/blueprints/api/endpoints.py
index 160f0242..e9c13ae6 100644
--- a/app/blueprints/api/endpoints.py
+++ b/app/blueprints/api/endpoints.py
@@ -723,5 +723,10 @@ def json_schema():
"type": ["string", "null"],
"format": "uri"
},
+ "donate_url": {
+ "description": "URL to a donation page",
+ "type": ["string", "null"],
+ "format": "uri"
+ },
},
})
diff --git a/app/blueprints/donate/__init__.py b/app/blueprints/donate/__init__.py
index 2ee52801..39b806a8 100644
--- a/app/blueprints/donate/__init__.py
+++ b/app/blueprints/donate/__init__.py
@@ -1,5 +1,6 @@
from flask import Blueprint, render_template
from flask_login import current_user
+from sqlalchemy import or_
from app.models import User, Package, PackageState, db, License
@@ -11,12 +12,18 @@ def donate():
reviewed_packages = None
if current_user.is_authenticated:
reviewed_packages = Package.query.filter(
- Package.state == PackageState.APPROVED,
- Package.reviews.any(author_id=current_user.id, recommends=True),
- Package.author.has(User.donate_url.isnot(None))).order_by(db.asc(Package.title)).all()
+ Package.state == PackageState.APPROVED,
+ Package.reviews.any(author_id=current_user.id, recommends=True),
+ or_(Package.donate_url.isnot(None), Package.author.has(User.donate_url.isnot(None)))
+ ).order_by(db.asc(Package.title)).all()
+
+ query = Package.query.filter(
+ Package.license.has(License.is_foss == True),
+ Package.media_license.has(License.is_foss == True),
+ Package.state == PackageState.APPROVED,
+ or_(Package.donate_url.isnot(None), Package.author.has(User.donate_url.isnot(None)))
+ ).order_by(db.desc(Package.score))
- query = Package.query.filter(Package.license.has(License.is_foss == True), Package.media_license.has(License.is_foss == True),
- Package.state == PackageState.APPROVED, Package.author.has(User.donate_url.isnot(None))).order_by(db.desc(Package.score))
packages_count = query.count()
top_packages = query.limit(40).all()
diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py
index fe75d28f..fd4d3e75 100644
--- a/app/blueprints/packages/packages.py
+++ b/app/blueprints/packages/packages.py
@@ -248,7 +248,8 @@ class PackageForm(FlaskForm):
website = StringField(lazy_gettext("Website URL"), [Optional(), URL()], filters = [lambda x: x or None])
issueTracker = StringField(lazy_gettext("Issue Tracker URL"), [Optional(), URL()], filters = [lambda x: x or None])
forums = IntegerField(lazy_gettext("Forum Topic ID"), [Optional(), NumberRange(0,999999)])
- video_url = StringField(lazy_gettext("Video URL"), [Optional(), URL()], filters = [lambda x: x or None])
+ video_url = StringField(lazy_gettext("Video URL"), [Optional(), URL()], filters=[lambda x: x or None])
+ donate_url = StringField(lazy_gettext("Donate URL"), [Optional(), URL()], filters=[lambda x: x or None])
submit = SubmitField(lazy_gettext("Save"))
@@ -294,6 +295,7 @@ def handle_create_edit(package: typing.Optional[Package], form: PackageForm, aut
"issueTracker": form.issueTracker.data,
"forums": form.forums.data,
"video_url": form.video_url.data,
+ "donate_url": form.donate_url.data,
})
if wasNew:
diff --git a/app/flatpages/help/api.md b/app/flatpages/help/api.md
index f5beb06f..666e4551 100644
--- a/app/flatpages/help/api.md
+++ b/app/flatpages/help/api.md
@@ -90,6 +90,7 @@ Tokens can be attained by visiting [Settings > API Tokens](/user/tokens/).
* `issue_tracker`: Issue tracker URL.
* `forums`: forum topic ID.
* `video_url`: URL to a video.
+ * `donate_url`: URL to a donation page.
* `game_support`: Array of game support information objects. Not currently documented, as subject to change.
* GET `/api/packages///dependencies/`
* Returns dependencies, with suggested candidates
diff --git a/app/flatpages/help/package_config.md b/app/flatpages/help/package_config.md
index 16e05c77..bcc89f83 100644
--- a/app/flatpages/help/package_config.md
+++ b/app/flatpages/help/package_config.md
@@ -75,6 +75,7 @@ It should be a JSON dictionary with one or more of the following optional keys:
* `issue_tracker`: Issue tracker URL.
* `forums`: forum topic ID.
* `video_url`: URL to a video.
+* `donate_url`: URL to a donation page.
Use `null` or `[]` to unset fields where relevant.
diff --git a/app/logic/packages.py b/app/logic/packages.py
index 34da108b..64b5ff6e 100644
--- a/app/logic/packages.py
+++ b/app/logic/packages.py
@@ -63,6 +63,7 @@ ALLOWED_FIELDS = {
"issueTracker": str,
"forums": int,
"video_url": str,
+ "donate_url": str,
}
ALIASES = {
@@ -118,7 +119,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
validate(data)
- for field in ["short_desc", "desc", "website", "issueTracker", "repo", "video_url"]:
+ for field in ["short_desc", "desc", "website", "issueTracker", "repo", "video_url", "donate_url"]:
if field in data and has_blocked_domains(data[field], user.username,
f"{field} of {package.getId()}"):
raise LogicError(403, lazy_gettext("Linking to blocked sites is not allowed"))
@@ -141,7 +142,7 @@ def do_edit_package(user: User, package: Package, was_new: bool, was_web: bool,
raise LogicError(403, "Never gonna give you up / Never gonna let you down / Never gonna run around and desert you")
for key in ["name", "title", "short_desc", "desc", "type", "dev_state", "license", "media_license",
- "repo", "website", "issueTracker", "forums", "video_url"]:
+ "repo", "website", "issueTracker", "forums", "video_url", "donate_url"]:
if key in data:
setattr(package, key, data[key])
diff --git a/app/models/packages.py b/app/models/packages.py
index ae78f64e..8cb79049 100644
--- a/app/models/packages.py
+++ b/app/models/packages.py
@@ -414,6 +414,11 @@ class Package(db.Model):
issueTracker = db.Column(db.String(200), nullable=True)
forums = db.Column(db.Integer, nullable=True)
video_url = db.Column(db.String(200), nullable=True, default=None)
+ donate_url = db.Column(db.String(200), nullable=True, default=None)
+
+ @property
+ def donate_url_actual(self):
+ return self.donate_url or self.author.donate_url
enable_game_support_detection = db.Column(db.Boolean, nullable=False, default=True)
@@ -581,6 +586,7 @@ class Package(db.Model):
"issue_tracker": self.issueTracker,
"forums": self.forums,
"video_url": self.video_url,
+ "donate_url": self.donate_url_actual,
"tags": [x.name for x in self.tags],
"content_warnings": [x.name for x in self.content_warnings],
diff --git a/app/templates/donate/index.html b/app/templates/donate/index.html
index 5fb19056..4ad7ee0d 100644
--- a/app/templates/donate/index.html
+++ b/app/templates/donate/index.html
@@ -36,7 +36,7 @@
{{ _("View package") }}
-
+
{{ _("Donate") }}
diff --git a/app/templates/packages/create_edit.html b/app/templates/packages/create_edit.html
index 8324059d..306e5e1a 100644
--- a/app/templates/packages/create_edit.html
+++ b/app/templates/packages/create_edit.html
@@ -118,6 +118,7 @@
prefix="forum.minetest.net/viewtopic.php?t=",
placeholder=_("Tip: paste in a forum topic URL")) }}
{{ render_field(form.video_url, class_="pkg_meta", hint=_("YouTube videos will be shown in an embed.")) }}
+ {{ render_field(form.donate_url, class_="pkg_meta", hint=_("If blank, the author's donation URL will be used instead.")) }}
{{ render_submit_field(form.submit) }}
diff --git a/app/templates/packages/view.html b/app/templates/packages/view.html
index b4735b59..57959439 100644
--- a/app/templates/packages/view.html
+++ b/app/templates/packages/view.html
@@ -378,10 +378,10 @@
{% endif %}
- {% if package.author.donate_url %}
+ {% if package.donate_url_actual %}
{{ _("Like this package? Help support its development by making a donation", display_name=package.author.display_name) }}
-
+
{{ _("Donate now") }}
diff --git a/migrations/versions/aa53b4d36c50_.py b/migrations/versions/aa53b4d36c50_.py
new file mode 100644
index 00000000..31f9861a
--- /dev/null
+++ b/migrations/versions/aa53b4d36c50_.py
@@ -0,0 +1,23 @@
+"""empty message
+
+Revision ID: aa53b4d36c50
+Revises: ea83ce985e55
+Create Date: 2023-03-05 18:11:29.743388
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+# revision identifiers, used by Alembic.
+revision = 'aa53b4d36c50'
+down_revision = 'ea83ce985e55'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ op.add_column('package', sa.Column('donate_url', sa.String(length=200), nullable=True))
+
+
+def downgrade():
+ op.drop_column('package', 'donate_url')