]> git.lizzy.rs Git - cheatdb.git/blob - app/blueprints/api/endpoints.py
Optimise SQL queries
[cheatdb.git] / app / blueprints / api / endpoints.py
1 # Content DB
2 # Copyright (C) 2018  rubenwardy
3 #
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.
8 #
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.
13 #
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/>.
16
17
18 from flask import *
19 from flask_user import *
20 from . import bp
21 from .auth import is_api_authd
22 from .support import error, handleCreateRelease
23 from app import csrf
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
28
29 @bp.route("/api/packages/")
30 def packages():
31         import sys
32         print("\n\n############", file=sys.stderr)
33
34         qb    = QueryBuilder(request.args)
35         query = qb.buildPackageQuery()
36         ver   = qb.getMinetestVersion()
37
38         pkgs = [package.getAsDictionaryShort(current_app.config["BASE_URL"], version=ver) \
39                         for package in query.all()]
40         return jsonify(pkgs)
41
42
43 @bp.route("/api/scores/")
44 def package_scores():
45         qb    = QueryBuilder(request.args)
46         query = qb.buildPackageQuery()
47
48         pkgs = [{ "author": package.author.username, "name": package.name, "score": package.score } \
49                         for package in query.all()]
50         return jsonify(pkgs)
51
52
53 @bp.route("/api/packages/<author>/<name>/")
54 @is_package_page
55 def package(package):
56         return jsonify(package.getAsDictionary(current_app.config["BASE_URL"]))
57
58
59 @bp.route("/api/packages/<author>/<name>/dependencies/")
60 @is_package_page
61 def package_dependencies(package):
62         ret = []
63
64         for dep in package.dependencies:
65                 name = None
66                 fulfilled_by = None
67
68                 if dep.package:
69                         name = dep.package.name
70                         fulfilled_by = [ dep.package.getAsDictionaryKey() ]
71
72                 elif dep.meta_package:
73                         name = dep.meta_package.name
74                         fulfilled_by = [ pkg.getAsDictionaryKey() for pkg in dep.meta_package.packages]
75
76                 else:
77                         raise "Malformed dependency"
78
79                 ret.append({
80                         "name": name,
81                         "is_optional": dep.optional,
82                         "packages": fulfilled_by
83                 })
84
85         return jsonify(ret)
86
87
88 @bp.route("/api/packages/<author>/<name>/releases/")
89 @is_package_page
90 def list_releases(package):
91         releases = package.releases.filter_by(approved=True).all()
92         return jsonify([ rel.getAsDictionary() for rel in releases ])
93
94
95 @bp.route("/api/topics/")
96 def topics():
97         qb     = QueryBuilder(request.args)
98         query  = qb.buildTopicQuery(show_added=True)
99         return jsonify([t.getAsDictionary() for t in query.all()])
100
101
102 @bp.route("/api/topic_discard/", methods=["POST"])
103 @login_required
104 def topic_set_discard():
105         tid = request.args.get("tid")
106         discard = request.args.get("discard")
107         if tid is None or discard is None:
108                 abort(400)
109
110         topic = ForumTopic.query.get(tid)
111         if not topic.checkPerm(current_user, Permission.TOPIC_DISCARD):
112                 abort(403)
113
114         topic.discarded = discard == "true"
115         db.session.commit()
116
117         return jsonify(topic.getAsDictionary())
118
119
120 @bp.route("/api/minetest_versions/")
121 def versions():
122         return jsonify([{ "name": rel.name, "protocol_version": rel.protocol }\
123                         for rel in MinetestRelease.query.all() if rel.getActual() is not None])
124
125
126 @bp.route("/api/whoami/")
127 @is_api_authd
128 def whoami(token):
129         if token is None:
130                 return jsonify({ "is_authenticated": False, "username": None })
131         else:
132                 return jsonify({ "is_authenticated": True, "username": token.owner.username })
133
134
135 @bp.route("/api/markdown/", methods=["POST"])
136 @csrf.exempt
137 def markdown():
138         return render_markdown(request.data.decode("utf-8"))
139
140
141 @bp.route("/api/packages/<author>/<name>/releases/new/", methods=["POST"])
142 @csrf.exempt
143 @is_package_page
144 @is_api_authd
145 def create_release(token, package):
146         if not package.checkPerm(token.owner, Permission.APPROVE_RELEASE):
147                 return error(403, "You do not have the permission to approve releases")
148
149         json = request.json
150         if json is None:
151                 return error(400, "JSON post data is required")
152
153         for option in ["method", "title", "ref"]:
154                 if json.get(option) is None:
155                         return error(400, option + " is required in the POST data")
156
157
158         if json["method"].lower() != "git":
159                 return error(400, "Release-creation methods other than git are not supported")
160
161         return handleCreateRelease(token, package, json["title"], json["ref"])