Add per-package donate URLs

This commit is contained in:
rubenwardy 2023-03-05 18:13:07 +00:00
parent 08054e4969
commit 07f5d2e0d5
11 changed files with 58 additions and 11 deletions

@ -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"
},
},
})

@ -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()

@ -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:

@ -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/<username>/<name>/dependencies/`
* Returns dependencies, with suggested candidates

@ -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.

@ -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])

@ -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],

@ -36,7 +36,7 @@
<a href="{{ package.getURL('packages.view') }}" class="btn btn-sm btn-secondary mr-1">
{{ _("View package") }}
</a>
<a href="{{ package.author.donate_url }}" class="btn btn-sm btn-primary" rel="nofollow">
<a href="{{ package.donate_url_actual }}" class="btn btn-sm btn-primary" rel="nofollow">
<i class="fas fa-heart mr-1"></i>
{{ _("Donate") }}
</a>

@ -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.")) }}
</fieldset>
<div class="pkg_meta mt-5">{{ render_submit_field(form.submit) }}</div>

@ -378,10 +378,10 @@
</p>
{% endif %}
{% if package.author.donate_url %}
{% if package.donate_url_actual %}
<div class="alert alert-secondary mb-4">
<p>{{ _("Like this package? Help support its development by making a donation", display_name=package.author.display_name) }}</p>
<a class="btn btn-block btn-primary" href="{{ package.author.donate_url }}" rel="nofollow">
<a class="btn btn-block btn-primary" href="{{ package.donate_url_actual }}" rel="nofollow">
<i class="fas fa-heart mr-2"></i>
{{ _("Donate now") }}
</a>

@ -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')