Add support for .cdb.json

Fixes #231
This commit is contained in:
rubenwardy 2021-02-02 23:58:59 +00:00
parent 90aeb6e1a7
commit 8225e4098b
7 changed files with 70 additions and 20 deletions

@ -20,7 +20,7 @@ from sqlalchemy.sql.expression import func
from app import csrf from app import csrf
from app.utils.markdown import render_markdown from app.utils.markdown import render_markdown
from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, MinetestRelease, APIToken, PackageScreenshot, License from app.models import Tag, PackageState, PackageType, Package, db, PackageRelease, Permission, ForumTopic, MinetestRelease, APIToken, PackageScreenshot, License, ContentWarning
from app.querybuilder import QueryBuilder from app.querybuilder import QueryBuilder
from app.utils import is_package_page from app.utils import is_package_page
from . import bp from . import bp
@ -317,6 +317,11 @@ def tags():
return jsonify([tag.getAsDictionary() for tag in Tag.query.all() ]) return jsonify([tag.getAsDictionary() for tag in Tag.query.all() ])
@bp.route("/api/content_warnings/")
def content_warnings():
return jsonify([warning.getAsDictionary() for warning in ContentWarning.query.all() ])
@bp.route("/api/licenses/") @bp.route("/api/licenses/")
def licenses(): def licenses():
return jsonify([ { "name": license.name, "is_foss": license.is_foss } \ return jsonify([ { "name": license.name, "is_foss": license.is_foss } \

@ -63,7 +63,7 @@ Examples:
# Edit packages # Edit packages
curl -X PUT http://localhost:5123/api/packages/username/name/ \ curl -X PUT http://localhost:5123/api/packages/username/name/ \
-H "Authorization: Bearer YOURTOKEN" -H "Content-Type: application/json" \ -H "Authorization: Bearer YOURTOKEN" -H "Content-Type: application/json" \
-d '{ "title": "Foo bar", "tags": ["pvp", "survival"], "license": "wtfpl" }' -d '{ "title": "Foo bar", "tags": ["pvp", "survival"], "license": "WTFPL" }'
# Remove website URL # Remove website URL
curl -X PUT http://localhost:5123/api/packages/username/name/ \ curl -X PUT http://localhost:5123/api/packages/username/name/ \

@ -38,6 +38,40 @@ and for mods only:
* `name` - the mod technical name. * `name` - the mod technical name.
## .cdb.json
You can include a `.cdb.json` file in the root of your content directory (ie: next to a .conf)
to update the package meta.
It should be a JSON dictionary with one or more of the following optional keys.
* `type`: One of `GAME`, `MOD`, `TXP`.
* `title`: Human-readable title.
* `name`: Technical name (needs permission if already approved).
* `short_description`
* `tags`: List of tag names, see [/api/tags/](/api/tags/).
* `content_Warnings`: List of content warning names, see [/api/content_warnings/](/api/content_warnings/).
* `license`: A license name, see [/api/licenses/](/api/licenses/).
* `media_license`: A license name.
* `desc`: Long markdown description.
* `repo`: Git repo URL.
* `website`: Website URL.
* `issue_tracker`: Issue tracker URL.
* `forums`: forum topic ID.
Use `null` to unset fields where relevant.
Example:
```json
{
"title": "Foo bar",
"tags": ["pvp", "survival"],
"license": "WTFPL"
}
```
## Controlling Release Creation ## Controlling Release Creation
### Git-based Releases and Submodules ### Git-based Releases and Submodules

@ -15,11 +15,12 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import re, validators import re
import validators
from app.logic.LogicError import LogicError from app.logic.LogicError import LogicError
from app.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, NotificationType, AuditSeverity, License from app.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, AuditSeverity, License
from app.utils import addNotification, addAuditLog from app.utils import addAuditLog
def check(cond: bool, msg: str): def check(cond: bool, msg: str):
@ -152,9 +153,6 @@ def do_edit_package(user: User, package: Package, was_new: bool, data: dict, rea
else: else:
msg = "Edited {} ({})".format(package.title, reason) msg = "Edited {} ({})".format(package.title, reason)
addNotification(package.maintainers, user, NotificationType.PACKAGE_EDIT,
msg, package.getDetailsURL(), package)
severity = AuditSeverity.NORMAL if user in package.maintainers else AuditSeverity.EDITOR severity = AuditSeverity.NORMAL if user in package.maintainers else AuditSeverity.EDITOR
addAuditLog(severity, user, msg, package.getDetailsURL(), package) addAuditLog(severity, user, msg, package.getDetailsURL(), package)

@ -727,6 +727,10 @@ class ContentWarning(db.Model):
regex = re.compile("[^a-z_]") regex = re.compile("[^a-z_]")
self.name = regex.sub("", self.title.lower().replace(" ", "_")) self.name = regex.sub("", self.title.lower().replace(" ", "_"))
def getAsDictionary(self):
description = self.description if self.description != "" else None
return { "name": self.name, "title": self.title, "description": description }
class Tag(db.Model): class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)

@ -13,8 +13,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/>.
import json
import os, shutil, gitdb import os, shutil, gitdb
from zipfile import ZipFile from zipfile import ZipFile
from git import GitCommandError from git import GitCommandError
@ -23,9 +22,11 @@ from kombu import uuid
from app.models import * from app.models import *
from app.tasks import celery, TaskError 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_system_user
from app.utils.git import clone_repo, get_latest_tag, get_latest_commit, get_temp_dir from app.utils.git import clone_repo, get_latest_tag, get_latest_commit, get_temp_dir
from .minetestcheck import build_tree, MinetestCheckError, ContentType from .minetestcheck import build_tree, MinetestCheckError, ContentType
from ..logic.LogicError import LogicError
from ..logic.packages import do_edit_package
@celery.task() @celery.task()
@ -90,13 +91,21 @@ def postReleaseCheckUpdate(self, release, path):
db.session.add(Dependency(package, meta=meta, optional=True)) db.session.add(Dependency(package, meta=meta, optional=True))
# Update min/max # Update min/max
if tree.meta.get("min_minetest_version"): if tree.meta.get("min_minetest_version"):
release.min_rel = MinetestRelease.get(tree.meta["min_minetest_version"], None) release.min_rel = MinetestRelease.get(tree.meta["min_minetest_version"], None)
if tree.meta.get("max_minetest_version"): if tree.meta.get("max_minetest_version"):
release.max_rel = MinetestRelease.get(tree.meta["max_minetest_version"], None) release.max_rel = MinetestRelease.get(tree.meta["max_minetest_version"], None)
try:
with open(os.path.join(tree.baseDir, ".cdb.json"), "r") as f:
data = json.loads(f.read())
do_edit_package(package.author, package, False, data, "Post release hook")
except LogicError as e:
raise TaskError(e.message)
except IOError:
pass
return tree return tree
except MinetestCheckError as err: except MinetestCheckError as err:

@ -85,23 +85,23 @@ def clearNotifications(url):
Notification.query.filter_by(user=current_user, url=url).delete() Notification.query.filter_by(user=current_user, url=url).delete()
db.session.commit() db.session.commit()
def addSystemNotification(target, type: NotificationType, title: str, url: str, package: Package = None):
def get_system_user():
system_user = User.query.filter_by(username="ContentDB").first() system_user = User.query.filter_by(username="ContentDB").first()
assert system_user assert system_user
return system_user
return addNotification(target, system_user, type, title, url, package)
def addSystemNotification(target, type: NotificationType, title: str, url: str, package: Package = None):
return addNotification(target, get_system_user(), type, title, url, package)
def addSystemAuditLog(severity: AuditSeverity, title: str, url: str, package=None, description=None): def addSystemAuditLog(severity: AuditSeverity, title: str, url: str, package=None, description=None):
system_user = User.query.filter_by(username="ContentDB").first() return addAuditLog(severity, get_system_user(), title, url, package, description)
assert system_user
return addAuditLog(severity, system_user, title, url, package, description)
def post_bot_message(package: Package, title: str, message: str): def post_bot_message(package: Package, title: str, message: str):
system_user = User.query.filter_by(username="ContentDB").first() system_user = get_system_user()
assert system_user
thread = package.threads.filter_by(author=system_user).first() thread = package.threads.filter_by(author=system_user).first()
if not thread: if not thread: