diff options
Diffstat (limited to 'app/blueprints/api')
-rw-r--r-- | app/blueprints/api/endpoints.py | 30 | ||||
-rw-r--r-- | app/blueprints/api/support.py | 40 |
2 files changed, 69 insertions, 1 deletions
diff --git a/app/blueprints/api/endpoints.py b/app/blueprints/api/endpoints.py index 266bf93..bd17bb5 100644 --- a/app/blueprints/api/endpoints.py +++ b/app/blueprints/api/endpoints.py @@ -19,6 +19,7 @@ from flask import * from flask_user import * from . import bp from .auth import is_api_authd +from .support import error, handleCreateRelease from app import csrf from app.models import * from app.utils import is_package_page @@ -71,6 +72,13 @@ def package_dependencies(package): return jsonify(ret) +@bp.route("/api/packages/<author>/<name>/releases/") +@is_package_page +def list_releases(package): + releases = package.releases.filter_by(approved=True).all() + return jsonify([ rel.getAsDictionary() for rel in releases ]) + + @bp.route("/api/topics/") def topics(): qb = QueryBuilder(request.args) @@ -113,5 +121,25 @@ def whoami(token): @bp.route("/api/markdown/", methods=["POST"]) @csrf.exempt -def clean_markdown(): +def markdown(): return render_markdown(request.data.decode("utf-8")) + + +@bp.route("/api/packages/<author>/<name>/releases/new/", methods=["POST"]) +@csrf.exempt +@is_package_page +@is_api_authd +def create_release(token, package): + json = request.json + if json is None: + return error(400, "JSON post data is required") + + for option in ["method", "title", "ref"]: + if json.get(option) is None: + return error(400, option + " is required in the POST data") + + + if json["method"].lower() != "vcs": + return error(400, "Release-creation methods other than VCS are not supported") + + return handleCreateRelease(token, package, json["title"], json["ref"]) diff --git a/app/blueprints/api/support.py b/app/blueprints/api/support.py new file mode 100644 index 0000000..0adf3db --- /dev/null +++ b/app/blueprints/api/support.py @@ -0,0 +1,40 @@ +from app.models import PackageRelease, db, Permission +from app.tasks.importtasks import makeVCSRelease +from celery import uuid +from flask import jsonify, make_response, url_for +import datetime + + +def error(status, message): + return make_response(jsonify({ "success": False, "error": message }), status) + + +def handleCreateRelease(token, package, title, ref): + if not token.canOperateOnPackage(package): + return error(403, "API token does not have access to the package") + + if not package.checkPerm(token.owner, Permission.MAKE_RELEASE): + return error(403, "Permission denied. Missing MAKE_RELEASE permission") + + five_minutes_ago = datetime.datetime.now() - datetime.timedelta(minutes=5) + count = package.releases.filter(PackageRelease.releaseDate > five_minutes_ago).count() + if count >= 2: + return error(429, "Too many requests, please wait before trying again") + + rel = PackageRelease() + rel.package = package + rel.title = title + rel.url = "" + rel.task_id = uuid() + rel.min_rel = None + rel.max_rel = None + db.session.add(rel) + db.session.commit() + + makeVCSRelease.apply_async((rel.id, ref), task_id=rel.task_id) + + return jsonify({ + "success": True, + "task": url_for("tasks.check", id=rel.task_id), + "release": rel.getAsDictionary() + }) |