mirror of
https://github.com/minetest/contentdb.git
synced 2025-01-03 11:47:28 +01:00
Add release notes and long titles to releases
Fixes #492 and fixes #480
This commit is contained in:
parent
4147e5edc7
commit
019cd66033
@ -283,7 +283,7 @@ def markdown():
|
|||||||
def list_all_releases():
|
def list_all_releases():
|
||||||
query = PackageRelease.query.filter_by(approved=True) \
|
query = PackageRelease.query.filter_by(approved=True) \
|
||||||
.filter(PackageRelease.package.has(state=PackageState.APPROVED)) \
|
.filter(PackageRelease.package.has(state=PackageState.APPROVED)) \
|
||||||
.order_by(db.desc(PackageRelease.releaseDate))
|
.order_by(db.desc(PackageRelease.created_at))
|
||||||
|
|
||||||
if "author" in request.args:
|
if "author" in request.args:
|
||||||
author = User.query.filter_by(username=request.args["author"]).first()
|
author = User.query.filter_by(username=request.args["author"]).first()
|
||||||
@ -333,7 +333,7 @@ def create_release(token, package):
|
|||||||
if option not in data:
|
if option not in data:
|
||||||
error(400, option + " is required in the POST data")
|
error(400, option + " is required in the POST data")
|
||||||
|
|
||||||
return api_create_vcs_release(token, package, data["title"], data["ref"])
|
return api_create_vcs_release(token, package, data["title"], data["title"], data.get("release_notes"), data["ref"])
|
||||||
|
|
||||||
elif request.files:
|
elif request.files:
|
||||||
file = request.files.get("file")
|
file = request.files.get("file")
|
||||||
@ -342,7 +342,7 @@ def create_release(token, package):
|
|||||||
|
|
||||||
commit_hash = data.get("commit")
|
commit_hash = data.get("commit")
|
||||||
|
|
||||||
return api_create_zip_release(token, package, data["title"], file, None, None, "API", commit_hash)
|
return api_create_zip_release(token, package, data["title"], data["title"], data.get("release_notes"), file, None, None, "API", commit_hash)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
error(400, "Unknown release-creation method. Specify the method or provide a file.")
|
error(400, "Unknown release-creation method. Specify the method or provide a file.")
|
||||||
@ -622,7 +622,7 @@ def homepage():
|
|||||||
|
|
||||||
updated = db.session.query(Package).select_from(PackageRelease).join(Package) \
|
updated = db.session.query(Package).select_from(PackageRelease).join(Package) \
|
||||||
.filter_by(state=PackageState.APPROVED) \
|
.filter_by(state=PackageState.APPROVED) \
|
||||||
.order_by(db.desc(PackageRelease.releaseDate)) \
|
.order_by(db.desc(PackageRelease.created_at)) \
|
||||||
.limit(20).all()
|
.limit(20).all()
|
||||||
updated = updated[:4]
|
updated = updated[:4]
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
from flask import jsonify, abort, make_response, url_for, current_app
|
from flask import jsonify, abort, make_response, url_for, current_app
|
||||||
|
|
||||||
from app.logic.packages import do_edit_package
|
from app.logic.packages import do_edit_package
|
||||||
@ -38,14 +38,14 @@ def guard(f):
|
|||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def api_create_vcs_release(token: APIToken, package: Package, title: str, ref: str,
|
def api_create_vcs_release(token: APIToken, package: Package, name: str, title: Optional[str], release_notes: Optional[str], ref: str,
|
||||||
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason="API"):
|
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason="API"):
|
||||||
if not token.can_operate_on_package(package):
|
if not token.can_operate_on_package(package):
|
||||||
error(403, "API token does not have access to the package")
|
error(403, "API token does not have access to the package")
|
||||||
|
|
||||||
reason += ", token=" + token.name
|
reason += ", token=" + token.name
|
||||||
|
|
||||||
rel = guard(do_create_vcs_release)(token.owner, package, title, ref, min_v, max_v, reason)
|
rel = guard(do_create_vcs_release)(token.owner, package, name, title, release_notes, ref, min_v, max_v, reason)
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
@ -54,14 +54,14 @@ def api_create_vcs_release(token: APIToken, package: Package, title: str, ref: s
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def api_create_zip_release(token: APIToken, package: Package, title: str, file,
|
def api_create_zip_release(token: APIToken, package: Package, name: str, title: Optional[str], release_notes: Optional[str], file,
|
||||||
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason="API", commit_hash: str = None):
|
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason="API", commit_hash: str = None):
|
||||||
if not token.can_operate_on_package(package):
|
if not token.can_operate_on_package(package):
|
||||||
error(403, "API token does not have access to the package")
|
error(403, "API token does not have access to the package")
|
||||||
|
|
||||||
reason += ", token=" + token.name
|
reason += ", token=" + token.name
|
||||||
|
|
||||||
rel = guard(do_create_zip_release)(token.owner, package, title, file, min_v, max_v, reason, commit_hash)
|
rel = guard(do_create_zip_release)(token.owner, package, name, title, release_notes, file, min_v, max_v, reason, commit_hash)
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": True,
|
"success": True,
|
||||||
|
@ -105,7 +105,7 @@ def home():
|
|||||||
recent_releases_query = (
|
recent_releases_query = (
|
||||||
db.session.query(
|
db.session.query(
|
||||||
Package.id,
|
Package.id,
|
||||||
func.max(PackageRelease.releaseDate).label("max_created_at")
|
func.max(PackageRelease.created_at).label("max_created_at")
|
||||||
)
|
)
|
||||||
.join(PackageRelease, Package.releases)
|
.join(PackageRelease, Package.releases)
|
||||||
.group_by(Package.id)
|
.group_by(Package.id)
|
||||||
|
@ -44,7 +44,7 @@ def game_hub(package: Package):
|
|||||||
|
|
||||||
updated = db.session.query(Package).select_from(PackageRelease).join(Package) \
|
updated = db.session.query(Package).select_from(PackageRelease).join(Package) \
|
||||||
.filter(Package.supported_games.any(game=package, supports=True), Package.state==PackageState.APPROVED) \
|
.filter(Package.supported_games.any(game=package, supports=True), Package.state==PackageState.APPROVED) \
|
||||||
.order_by(db.desc(PackageRelease.releaseDate)) \
|
.order_by(db.desc(PackageRelease.created_at)) \
|
||||||
.limit(20).all()
|
.limit(20).all()
|
||||||
updated = updated[:4]
|
updated = updated[:4]
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ from flask_babel import lazy_gettext, gettext
|
|||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import StringField, SubmitField, BooleanField, RadioField, FileField
|
from wtforms import StringField, SubmitField, BooleanField, RadioField, FileField
|
||||||
|
from wtforms.fields.simple import TextAreaField
|
||||||
from wtforms.validators import InputRequired, Length, Optional
|
from wtforms.validators import InputRequired, Length, Optional
|
||||||
from wtforms_sqlalchemy.fields import QuerySelectField
|
from wtforms_sqlalchemy.fields import QuerySelectField
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ from app.models import Package, db, User, PackageState, Permission, UserRank, Pa
|
|||||||
PackageRelease, PackageUpdateTrigger, PackageUpdateConfig
|
PackageRelease, PackageUpdateTrigger, PackageUpdateConfig
|
||||||
from app.rediscache import has_key, set_temp_key, make_download_key
|
from app.rediscache import has_key, set_temp_key, make_download_key
|
||||||
from app.tasks.importtasks import check_update_config
|
from app.tasks.importtasks import check_update_config
|
||||||
from app.utils import is_user_bot, is_package_page, nonempty_or_none
|
from app.utils import is_user_bot, is_package_page, nonempty_or_none, normalize_line_endings
|
||||||
from . import bp, get_package_tabs
|
from . import bp, get_package_tabs
|
||||||
|
|
||||||
|
|
||||||
@ -51,19 +52,25 @@ def get_mt_releases(is_max):
|
|||||||
|
|
||||||
|
|
||||||
class CreatePackageReleaseForm(FlaskForm):
|
class CreatePackageReleaseForm(FlaskForm):
|
||||||
title = StringField(lazy_gettext("Title"), [InputRequired(), Length(1, 30)])
|
name = StringField(lazy_gettext("Name"), [InputRequired(), Length(1, 30)])
|
||||||
uploadOpt = RadioField(lazy_gettext("Method"), choices=[("upload", lazy_gettext("File Upload"))], default="upload")
|
title = StringField(lazy_gettext("Title"), [Optional(), Length(1, 100)], filters=[nonempty_or_none])
|
||||||
vcsLabel = StringField(lazy_gettext("Git reference (ie: commit hash, branch, or tag)"), default=None)
|
release_notes = TextAreaField(lazy_gettext("Release Notes"), [Optional(), Length(1, 100)],
|
||||||
|
filters=[nonempty_or_none, normalize_line_endings])
|
||||||
|
upload_mode = RadioField(lazy_gettext("Method"), choices=[("upload", lazy_gettext("File Upload"))], default="upload")
|
||||||
|
vcs_label = StringField(lazy_gettext("Git reference (ie: commit hash, branch, or tag)"), default=None)
|
||||||
file_upload = FileField(lazy_gettext("File Upload"))
|
file_upload = FileField(lazy_gettext("File Upload"))
|
||||||
min_rel = QuerySelectField(lazy_gettext("Minimum Minetest Version"), [InputRequired()],
|
min_rel = QuerySelectField(lazy_gettext("Minimum Minetest Version"), [InputRequired()],
|
||||||
query_factory=lambda: get_mt_releases(False), get_pk=lambda a: a.id, get_label=lambda a: a.name)
|
query_factory=lambda: get_mt_releases(False), get_pk=lambda a: a.id, get_label=lambda a: a.name)
|
||||||
max_rel = QuerySelectField(lazy_gettext("Maximum Minetest Version"), [InputRequired()],
|
max_rel = QuerySelectField(lazy_gettext("Maximum Minetest Version"), [InputRequired()],
|
||||||
query_factory=lambda: get_mt_releases(True), get_pk=lambda a: a.id, get_label=lambda a: a.name)
|
query_factory=lambda: get_mt_releases(True), get_pk=lambda a: a.id, get_label=lambda a: a.name)
|
||||||
submit = SubmitField(lazy_gettext("Save"))
|
submit = SubmitField(lazy_gettext("Save"))
|
||||||
|
|
||||||
|
|
||||||
class EditPackageReleaseForm(FlaskForm):
|
class EditPackageReleaseForm(FlaskForm):
|
||||||
title = StringField(lazy_gettext("Title"), [InputRequired(), Length(1, 30)])
|
name = StringField(lazy_gettext("Name"), [InputRequired(), Length(1, 30)])
|
||||||
|
title = StringField(lazy_gettext("Title"), [Optional(), Length(1, 30)], filters=[nonempty_or_none])
|
||||||
|
release_notes = TextAreaField(lazy_gettext("Release Notes"), [Optional(), Length(1, 100)],
|
||||||
|
filters=[nonempty_or_none, normalize_line_endings])
|
||||||
url = StringField(lazy_gettext("URL"), [Optional()])
|
url = StringField(lazy_gettext("URL"), [Optional()])
|
||||||
task_id = StringField(lazy_gettext("Task ID"), filters = [lambda x: x or None])
|
task_id = StringField(lazy_gettext("Task ID"), filters = [lambda x: x or None])
|
||||||
approved = BooleanField(lazy_gettext("Is Approved"))
|
approved = BooleanField(lazy_gettext("Is Approved"))
|
||||||
@ -88,21 +95,21 @@ def create_release(package):
|
|||||||
# Initial form class from post data and default data
|
# Initial form class from post data and default data
|
||||||
form = CreatePackageReleaseForm()
|
form = CreatePackageReleaseForm()
|
||||||
if package.repo is not None:
|
if package.repo is not None:
|
||||||
form["uploadOpt"].choices = [("vcs", gettext("Import from Git")), ("upload", gettext("Upload .zip file"))]
|
form.upload_mode.choices = [("vcs", gettext("Import from Git")), ("upload", gettext("Upload .zip file"))]
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
form["uploadOpt"].data = "vcs"
|
form.upload_mode.data = "vcs"
|
||||||
form.vcsLabel.data = request.args.get("ref")
|
form.vcs_label.data = request.args.get("ref")
|
||||||
|
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
form.title.data = request.args.get("title")
|
form.title.data = request.args.get("title")
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
try:
|
try:
|
||||||
if form["uploadOpt"].data == "vcs":
|
if form.upload_mode.data == "vcs":
|
||||||
rel = do_create_vcs_release(current_user, package, form.title.data,
|
rel = do_create_vcs_release(current_user, package, form.name.data, form.title.data, form.release_notes.data,
|
||||||
form.vcsLabel.data, form.min_rel.data.get_actual(), form.max_rel.data.get_actual())
|
form.vcs_label.data, form.min_rel.data.get_actual(), form.max_rel.data.get_actual())
|
||||||
else:
|
else:
|
||||||
rel = do_create_zip_release(current_user, package, form.title.data,
|
rel = do_create_zip_release(current_user, package, form.name.data, form.title.data, form.release_notes.data,
|
||||||
form.file_upload.data, form.min_rel.data.get_actual(), form.max_rel.data.get_actual())
|
form.file_upload.data, form.min_rel.data.get_actual(), form.max_rel.data.get_actual())
|
||||||
return redirect(url_for("tasks.check", id=rel.task_id, r=rel.get_edit_url()))
|
return redirect(url_for("tasks.check", id=rel.task_id, r=rel.get_edit_url()))
|
||||||
except LogicError as e:
|
except LogicError as e:
|
||||||
|
@ -192,7 +192,7 @@ def github_webhook():
|
|||||||
if package.releases.filter_by(commit_hash=ref).count() > 0:
|
if package.releases.filter_by(commit_hash=ref).count() > 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
return api_create_vcs_release(token, package, title, ref, reason="Webhook")
|
return api_create_vcs_release(token, package, title, title, None, ref, reason="Webhook")
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": False,
|
"success": False,
|
||||||
|
@ -68,7 +68,7 @@ def webhook_impl():
|
|||||||
if package.releases.filter_by(commit_hash=ref).count() > 0:
|
if package.releases.filter_by(commit_hash=ref).count() > 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return api_create_vcs_release(token, package, title, ref, reason="Webhook")
|
return api_create_vcs_release(token, package, title, title, None, ref, reason="Webhook")
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"success": False,
|
"success": False,
|
||||||
|
@ -224,7 +224,9 @@ Format query parameters:
|
|||||||
* `maintainer`: Filter by maintainer
|
* `maintainer`: Filter by maintainer
|
||||||
* Returns array of release dictionaries with keys:
|
* Returns array of release dictionaries with keys:
|
||||||
* `id`: release ID
|
* `id`: release ID
|
||||||
|
* `name`: short release name
|
||||||
* `title`: human-readable title
|
* `title`: human-readable title
|
||||||
|
* `release_notes`: string or null, what's new in this release
|
||||||
* `release_date`: Date released
|
* `release_date`: Date released
|
||||||
* `url`: download URL
|
* `url`: download URL
|
||||||
* `commit`: commit hash or null
|
* `commit`: commit hash or null
|
||||||
@ -248,6 +250,7 @@ Format query parameters:
|
|||||||
* Requires authentication.
|
* Requires authentication.
|
||||||
* Body can be JSON or multipart form data. Zip uploads must be multipart form data.
|
* Body can be JSON or multipart form data. Zip uploads must be multipart form data.
|
||||||
* `title`: human-readable name of the release.
|
* `title`: human-readable name of the release.
|
||||||
|
* `release_notes`: string or null, what's new in this release.
|
||||||
* For Git release creation:
|
* For Git release creation:
|
||||||
* `method`: must be `git`.
|
* `method`: must be `git`.
|
||||||
* `ref`: (Optional) git reference, eg: `master`.
|
* `ref`: (Optional) git reference, eg: `master`.
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from celery import uuid
|
from celery import uuid
|
||||||
from flask_babel import lazy_gettext
|
from flask_babel import lazy_gettext
|
||||||
@ -32,18 +33,20 @@ def check_can_create_release(user: User, package: Package):
|
|||||||
raise LogicError(403, lazy_gettext("You don't have permission to make releases"))
|
raise LogicError(403, lazy_gettext("You don't have permission to make releases"))
|
||||||
|
|
||||||
five_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=5)
|
five_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=5)
|
||||||
count = package.releases.filter(PackageRelease.releaseDate > five_minutes_ago).count()
|
count = package.releases.filter(PackageRelease.created_at > five_minutes_ago).count()
|
||||||
if count >= 5:
|
if count >= 5:
|
||||||
raise LogicError(429, lazy_gettext("You've created too many releases for this package in the last 5 minutes, please wait before trying again"))
|
raise LogicError(429, lazy_gettext("You've created too many releases for this package in the last 5 minutes, please wait before trying again"))
|
||||||
|
|
||||||
|
|
||||||
def do_create_vcs_release(user: User, package: Package, title: str, ref: str,
|
def do_create_vcs_release(user: User, package: Package, name: str, title: Optional[str], release_notes: Optional[str], ref: str,
|
||||||
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None):
|
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None):
|
||||||
check_can_create_release(user, package)
|
check_can_create_release(user, package)
|
||||||
|
|
||||||
rel = PackageRelease()
|
rel = PackageRelease()
|
||||||
rel.package = package
|
rel.package = package
|
||||||
rel.title = title
|
rel.name = name
|
||||||
|
rel.title = title or name
|
||||||
|
rel.release_notes = release_notes
|
||||||
rel.url = ""
|
rel.url = ""
|
||||||
rel.task_id = uuid()
|
rel.task_id = uuid()
|
||||||
rel.min_rel = min_v
|
rel.min_rel = min_v
|
||||||
@ -63,7 +66,7 @@ def do_create_vcs_release(user: User, package: Package, title: str, ref: str,
|
|||||||
return rel
|
return rel
|
||||||
|
|
||||||
|
|
||||||
def do_create_zip_release(user: User, package: Package, title: str, file,
|
def do_create_zip_release(user: User, package: Package, name: str, title: Optional[str], release_notes: Optional[str], file,
|
||||||
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None,
|
min_v: MinetestRelease = None, max_v: MinetestRelease = None, reason: str = None,
|
||||||
commit_hash: str = None):
|
commit_hash: str = None):
|
||||||
check_can_create_release(user, package)
|
check_can_create_release(user, package)
|
||||||
@ -77,7 +80,9 @@ def do_create_zip_release(user: User, package: Package, title: str, file,
|
|||||||
|
|
||||||
rel = PackageRelease()
|
rel = PackageRelease()
|
||||||
rel.package = package
|
rel.package = package
|
||||||
rel.title = title
|
rel.name = name
|
||||||
|
rel.title = title or name
|
||||||
|
rel.release_notes = release_notes
|
||||||
rel.url = uploaded_url
|
rel.url = uploaded_url
|
||||||
rel.task_id = uuid()
|
rel.task_id = uuid()
|
||||||
rel.commit_hash = commit_hash
|
rel.commit_hash = commit_hash
|
||||||
|
@ -474,7 +474,7 @@ class Package(db.Model):
|
|||||||
content_warnings = db.relationship("ContentWarning", secondary=ContentWarnings, back_populates="packages")
|
content_warnings = db.relationship("ContentWarning", secondary=ContentWarnings, back_populates="packages")
|
||||||
|
|
||||||
releases = db.relationship("PackageRelease", back_populates="package",
|
releases = db.relationship("PackageRelease", back_populates="package",
|
||||||
lazy="dynamic", order_by=db.desc("package_release_releaseDate"), cascade="all, delete, delete-orphan")
|
lazy="dynamic", order_by=db.desc("package_release_created_at"), cascade="all, delete, delete-orphan")
|
||||||
|
|
||||||
screenshots = db.relationship("PackageScreenshot", back_populates="package", foreign_keys="PackageScreenshot.package_id",
|
screenshots = db.relationship("PackageScreenshot", back_populates="package", foreign_keys="PackageScreenshot.package_id",
|
||||||
lazy="dynamic", order_by=db.asc("package_screenshot_order"), cascade="all, delete, delete-orphan")
|
lazy="dynamic", order_by=db.asc("package_screenshot_order"), cascade="all, delete, delete-orphan")
|
||||||
@ -1085,13 +1085,15 @@ class PackageRelease(db.Model):
|
|||||||
package_id = db.Column(db.Integer, db.ForeignKey("package.id"))
|
package_id = db.Column(db.Integer, db.ForeignKey("package.id"))
|
||||||
package = db.relationship("Package", back_populates="releases", foreign_keys=[package_id])
|
package = db.relationship("Package", back_populates="releases", foreign_keys=[package_id])
|
||||||
|
|
||||||
|
name = db.Column(db.String(30), nullable=False)
|
||||||
title = db.Column(db.String(100), nullable=False)
|
title = db.Column(db.String(100), nullable=False)
|
||||||
releaseDate = db.Column(db.DateTime, nullable=False)
|
created_at = db.Column(db.DateTime, nullable=False)
|
||||||
url = db.Column(db.String(200), nullable=False, default="")
|
url = db.Column(db.String(200), nullable=False, default="")
|
||||||
approved = db.Column(db.Boolean, nullable=False, default=False)
|
approved = db.Column(db.Boolean, nullable=False, default=False)
|
||||||
task_id = db.Column(db.String(37), nullable=True)
|
task_id = db.Column(db.String(37), nullable=True)
|
||||||
commit_hash = db.Column(db.String(41), nullable=True, default=None)
|
commit_hash = db.Column(db.String(41), nullable=True, default=None)
|
||||||
downloads = db.Column(db.Integer, nullable=False, default=0)
|
downloads = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
release_notes = db.Column(db.UnicodeText, nullable=True, default=None)
|
||||||
|
|
||||||
min_rel_id = db.Column(db.Integer, db.ForeignKey("minetest_release.id"), nullable=True, server_default=None)
|
min_rel_id = db.Column(db.Integer, db.ForeignKey("minetest_release.id"), nullable=True, server_default=None)
|
||||||
min_rel = db.relationship("MinetestRelease", foreign_keys=[min_rel_id])
|
min_rel = db.relationship("MinetestRelease", foreign_keys=[min_rel_id])
|
||||||
@ -1126,9 +1128,11 @@ class PackageRelease(db.Model):
|
|||||||
def as_dict(self):
|
def as_dict(self):
|
||||||
return {
|
return {
|
||||||
"id": self.id,
|
"id": self.id,
|
||||||
|
"name": self.name,
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
|
"release_notes": self.release_notes,
|
||||||
"url": self.url if self.url != "" else None,
|
"url": self.url if self.url != "" else None,
|
||||||
"release_date": self.releaseDate.isoformat(),
|
"release_date": self.created_at.isoformat(),
|
||||||
"commit": self.commit_hash,
|
"commit": self.commit_hash,
|
||||||
"downloads": self.downloads,
|
"downloads": self.downloads,
|
||||||
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
|
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
|
||||||
@ -1141,7 +1145,7 @@ class PackageRelease(db.Model):
|
|||||||
"id": self.id,
|
"id": self.id,
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
"url": self.url if self.url != "" else None,
|
"url": self.url if self.url != "" else None,
|
||||||
"release_date": self.releaseDate.isoformat(),
|
"release_date": self.created_at.isoformat(),
|
||||||
"commit": self.commit_hash,
|
"commit": self.commit_hash,
|
||||||
"downloads": self.downloads,
|
"downloads": self.downloads,
|
||||||
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
|
"min_minetest_version": self.min_rel and self.min_rel.as_dict(),
|
||||||
@ -1169,7 +1173,7 @@ class PackageRelease(db.Model):
|
|||||||
id=self.id)
|
id=self.id)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.releaseDate = datetime.datetime.now()
|
self.created_at = datetime.datetime.now()
|
||||||
|
|
||||||
def get_download_filename(self):
|
def get_download_filename(self):
|
||||||
return f"{self.package.name}_{self.id}.zip"
|
return f"{self.package.name}_{self.id}.zip"
|
||||||
|
@ -5,15 +5,15 @@
|
|||||||
|
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
function check_opt() {
|
function check_opt() {
|
||||||
if (document.querySelector("input[name='uploadOpt']:checked").value === "vcs") {
|
if (document.querySelector("input[name='upload_mode']:checked").value === "vcs") {
|
||||||
document.getElementById("file_upload").parentElement.classList.add("d-none");
|
document.getElementById("file_upload").parentElement.classList.add("d-none");
|
||||||
document.getElementById("vcsLabel").parentElement.classList.remove("d-none");
|
document.getElementById("vcs_label").parentElement.classList.remove("d-none");
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("file_upload").parentElement.classList.remove("d-none");
|
document.getElementById("file_upload").parentElement.classList.remove("d-none");
|
||||||
document.getElementById("vcsLabel").parentElement.classList.add("d-none");
|
document.getElementById("vcs_label").parentElement.classList.add("d-none");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll("input[name='uploadOpt']").forEach(x => x.addEventListener("change", check_opt));
|
document.querySelectorAll("input[name='upload_mode']").forEach(x => x.addEventListener("change", check_opt));
|
||||||
check_opt();
|
check_opt();
|
||||||
});
|
});
|
||||||
|
@ -343,7 +343,7 @@ class QueryBuilder:
|
|||||||
elif self.order_by == "approved_at" or self.order_by == "date":
|
elif self.order_by == "approved_at" or self.order_by == "date":
|
||||||
to_order = Package.approved_at
|
to_order = Package.approved_at
|
||||||
elif self.order_by == "last_release":
|
elif self.order_by == "last_release":
|
||||||
to_order = PackageRelease.releaseDate
|
to_order = PackageRelease.created_at
|
||||||
else:
|
else:
|
||||||
abort(400)
|
abort(400)
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
[{{ rel.commit_hash | truncate(5, end='') }}]
|
[{{ rel.commit_hash | truncate(5, end='') }}]
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ _("created %(date)s", date=rel.releaseDate | date) }}.
|
{{ _("created %(date)s", date=rel.created_at | date) }}.
|
||||||
</small>
|
</small>
|
||||||
</a>
|
</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -50,7 +50,7 @@
|
|||||||
[{{ rel.commit_hash | truncate(5, end='') }}]
|
[{{ rel.commit_hash | truncate(5, end='') }}]
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ _("created %(date)s", date=rel.releaseDate | date) }}.
|
{{ _("created %(date)s", date=rel.created_at | date) }}.
|
||||||
</small>
|
</small>
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -96,7 +96,7 @@
|
|||||||
[{{ rel.commit_hash | truncate(5, end='') }}]
|
[{{ rel.commit_hash | truncate(5, end='') }}]
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{{ _("created %(date)s", date=rel.releaseDate | date) }}.
|
{{ _("created %(date)s", date=rel.created_at | date) }}.
|
||||||
</small>
|
</small>
|
||||||
{% if (package.check_perm(current_user, "MAKE_RELEASE") or rel.check_perm(current_user, "APPROVE_RELEASE")) and rel.task_id %}
|
{% if (package.check_perm(current_user, "MAKE_RELEASE") or rel.check_perm(current_user, "APPROVE_RELEASE")) and rel.task_id %}
|
||||||
<a href="{{ url_for('tasks.check', id=rel.task_id, r=package.get_url('packages.view')) }}">
|
<a href="{{ url_for('tasks.check', id=rel.task_id, r=package.get_url('packages.view')) }}">
|
||||||
|
@ -12,9 +12,17 @@
|
|||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
|
|
||||||
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
{% if package.check_perm(current_user, "MAKE_RELEASE") %}
|
||||||
{{ render_field(form.title) }}
|
{{ render_field(form.name, hint=_("Release short name. Eg: 1.0.0 or 2018-05-28")) }}
|
||||||
|
{{ render_field(form.title, hint=_("Human-readable name. Eg: 1.0.0 - The Trains Update")) }}
|
||||||
|
{{ render_field(form.release_notes) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ _("Title") }}: {{ release.title }}
|
<p>
|
||||||
|
{{ _("Name") }}: {{ release.name }}<br>
|
||||||
|
{{ _("Title") }}: {{ release.title }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{ release.release_notes }}
|
||||||
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if package.check_perm(current_user, "CHANGE_RELEASE_URL") %}
|
{% if package.check_perm(current_user, "CHANGE_RELEASE_URL") %}
|
||||||
|
@ -39,15 +39,16 @@
|
|||||||
|
|
||||||
<h3>{{ _("1. Name release") }}</h3>
|
<h3>{{ _("1. Name release") }}</h3>
|
||||||
|
|
||||||
{{ render_field(form.title, placeholder=_("Human readable. Eg: 1.0.0 or 2018-05-28")) }}
|
{{ render_field(form.name, hint=_("Release short name. Eg: 1.0.0 or 2018-05-28")) }}
|
||||||
|
{{ render_field(form.title, hint=_("Human-readable name. Eg: 1.0.0 - The Trains Update")) }}
|
||||||
|
{{ render_field(form.release_notes) }}
|
||||||
|
|
||||||
<h3 class="mt-5">{{ _("2. Set the content") }}</h3>
|
<h3 class="mt-5">{{ _("2. Set the content") }}</h3>
|
||||||
|
|
||||||
<p class="mb-0">{{ _("Method") }}</p>
|
{{ render_radio_field(form.upload_mode) }}
|
||||||
{{ render_radio_field(form.uploadOpt) }}
|
|
||||||
|
|
||||||
{% if package.repo %}
|
{% if package.repo %}
|
||||||
{{ render_field(form.vcsLabel, placeholder=_("Leave blank to use default branch"), class_="mt-3",
|
{{ render_field(form.vcs_label, placeholder=_("Leave blank to use default branch"), class_="mt-3",
|
||||||
pattern="[A-Za-z0-9/._-]+") }}
|
pattern="[A-Za-z0-9/._-]+") }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@ -99,5 +100,5 @@
|
|||||||
|
|
||||||
{% block scriptextra %}
|
{% block scriptextra %}
|
||||||
<script src="/static/js/release_minmax.js?v=2"></script>
|
<script src="/static/js/release_minmax.js?v=2"></script>
|
||||||
<script src="/static/js/release_new.js"></script>
|
<script src="/static/js/release_new.js?v=2"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user