2 # Copyright (C) 2018 rubenwardy
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
19 from flask_user import *
21 from .auth import is_api_authd
22 from .support import error, handleCreateRelease
24 from app.models import *
25 from app.utils import is_package_page
26 from app.markdown import render_markdown
27 from app.querybuilder import QueryBuilder
29 @bp.route("/api/packages/")
31 qb = QueryBuilder(request.args)
32 query = qb.buildPackageQuery()
33 ver = qb.getMinetestVersion()
35 pkgs = [package.getAsDictionaryShort(current_app.config["BASE_URL"], version=ver) \
36 for package in query.all()]
40 @bp.route("/api/scores/")
42 qb = QueryBuilder(request.args)
43 query = qb.buildPackageQuery()
45 pkgs = [package.getScoreDict() for package in query.all()]
49 @bp.route("/api/packages/<author>/<name>/")
52 return jsonify(package.getAsDictionary(current_app.config["BASE_URL"]))
55 def resolve_package_deps(out, package, only_hard):
63 for dep in package.dependencies:
64 if only_hard and dep.optional:
71 name = dep.package.name
72 fulfilled_by = [ dep.package.getId() ]
73 resolve_package_deps(out, dep.package, only_hard)
75 elif dep.meta_package:
76 name = dep.meta_package.name
77 fulfilled_by = [ pkg.getId() for pkg in dep.meta_package.packages]
78 # TODO: resolve most likely candidate
81 raise "Malformed dependency"
85 "is_optional": dep.optional,
86 "packages": fulfilled_by
90 @bp.route("/api/packages/<author>/<name>/dependencies/")
92 def package_dependencies(package):
93 only_hard = request.args.get("only_hard")
96 resolve_package_deps(out, package, only_hard)
101 @bp.route("/api/packages/<author>/<name>/releases/")
103 def list_releases(package):
104 releases = package.releases.filter_by(approved=True).all()
105 return jsonify([ rel.getAsDictionary() for rel in releases ])
108 @bp.route("/api/topics/")
110 qb = QueryBuilder(request.args)
111 query = qb.buildTopicQuery(show_added=True)
112 return jsonify([t.getAsDictionary() for t in query.all()])
115 @bp.route("/api/topic_discard/", methods=["POST"])
117 def topic_set_discard():
118 tid = request.args.get("tid")
119 discard = request.args.get("discard")
120 if tid is None or discard is None:
123 topic = ForumTopic.query.get(tid)
124 if not topic.checkPerm(current_user, Permission.TOPIC_DISCARD):
127 topic.discarded = discard == "true"
130 return jsonify(topic.getAsDictionary())
133 @bp.route("/api/minetest_versions/")
135 return jsonify([{ "name": rel.name, "protocol_version": rel.protocol }\
136 for rel in MinetestRelease.query.all() if rel.getActual() is not None])
139 @bp.route("/api/whoami/")
143 return jsonify({ "is_authenticated": False, "username": None })
145 return jsonify({ "is_authenticated": True, "username": token.owner.username })
148 @bp.route("/api/markdown/", methods=["POST"])
151 return render_markdown(request.data.decode("utf-8"))
154 @bp.route("/api/packages/<author>/<name>/releases/new/", methods=["POST"])
158 def create_release(token, package):
160 error(401, "Authentication needed")
162 if not package.checkPerm(token.owner, Permission.APPROVE_RELEASE):
163 error(403, "You do not have the permission to approve releases")
167 error(400, "JSON post data is required")
169 for option in ["method", "title", "ref"]:
170 if json.get(option) is None:
171 error(400, option + " is required in the POST data")
173 if json["method"].lower() != "git":
174 error(400, "Release-creation methods other than git are not supported")
176 return handleCreateRelease(token, package, json["title"], json["ref"])