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.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.utils import is_package_page
from . import bp
@ -317,6 +317,11 @@ def tags():
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/")
def licenses():
return jsonify([ { "name": license.name, "is_foss": license.is_foss } \

@ -63,7 +63,7 @@ Examples:
# Edit packages
curl -X PUT http://localhost:5123/api/packages/username/name/ \
-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
curl -X PUT http://localhost:5123/api/packages/username/name/ \

@ -38,6 +38,40 @@ and for mods only:
* `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
### Git-based Releases and Submodules

@ -15,11 +15,12 @@
# 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.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, NotificationType, AuditSeverity, License
from app.utils import addNotification, addAuditLog
from app.models import User, Package, PackageType, MetaPackage, Tag, ContentWarning, db, Permission, AuditSeverity, License
from app.utils import addAuditLog
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:
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
addAuditLog(severity, user, msg, package.getDetailsURL(), package)

@ -727,6 +727,10 @@ class ContentWarning(db.Model):
regex = re.compile("[^a-z_]")
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):
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
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import json
import os, shutil, gitdb
from zipfile import ZipFile
from git import GitCommandError
@ -23,9 +22,11 @@ from kombu import uuid
from app.models import *
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 .minetestcheck import build_tree, MinetestCheckError, ContentType
from ..logic.LogicError import LogicError
from ..logic.packages import do_edit_package
@celery.task()
@ -90,13 +91,21 @@ def postReleaseCheckUpdate(self, release, path):
db.session.add(Dependency(package, meta=meta, optional=True))
# Update min/max
if tree.meta.get("min_minetest_version"):
release.min_rel = MinetestRelease.get(tree.meta["min_minetest_version"], None)
if tree.meta.get("max_minetest_version"):
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
except MinetestCheckError as err:

@ -85,23 +85,23 @@ def clearNotifications(url):
Notification.query.filter_by(user=current_user, url=url).delete()
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()
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):
system_user = User.query.filter_by(username="ContentDB").first()
assert system_user
return addAuditLog(severity, system_user, title, url, package, description)
return addAuditLog(severity, get_system_user(), title, url, package, description)
def post_bot_message(package: Package, title: str, message: str):
system_user = User.query.filter_by(username="ContentDB").first()
assert system_user
system_user = get_system_user()
thread = package.threads.filter_by(author=system_user).first()
if not thread: