Add API endpoints for editing collections and media elements

master
Felix Stupp 3 years ago
parent 5346a2f7a4
commit 38381e0b1f
Signed by: zocker
GPG Key ID: 93E1BD26F6B02FB7

@ -10,7 +10,7 @@ import os
from urllib.parse import urlencode, quote_plus
from typing import Any, Callable, Dict, Iterable, Optional, Union
from flask import Flask, jsonify, make_response, request
from flask import Flask, jsonify, make_response, request, redirect
from flask.templating import render_template
from markupsafe import Markup
from pony.flask import Pony
@ -230,6 +230,84 @@ def test():
# TODO add table for failed attempts so these may be resolved afterwards with increasing delays (add to MediaElement with flag "retrieved" and "last_updated" as date to resolve last try)
def redirect_back_or_okay():
if "redirect" not in request.form:
return {
"status": True,
}, 200
uri = request.form.get("redirect", type=str)
if not uri.startswith("/"):
return "400 Bad Request : Invalid Redirect Specified", 400
return redirect(uri)
@flask_app.route("/api/collection/list")
def api_collection_list():
collection_list: Iterable[MediaCollection] = MediaCollection.select()
return {
"status": True,
"data": [{
"id": collection.id,
"title": collection.title,
"release_date": collection.release_date,
"length": collection.length,
"progress": collection.progress,
} for collection in collection_list],
}, 200
@flask_app.route("/api/collection/<int:collection_id>", methods=["GET", "POST"])
def api_collection_element(collection_id: int):
collection: MediaCollection = MediaCollection.get(id=collection_id)
if collection is None:
return {
"status": False,
"error": f"Object not found",
}, 404
if request.method == "GET":
return {
"status": True,
"data": {
"id": collection.id,
"title": collection.title,
"notes": collection.notes,
"release_date": collection.release_date,
"ignored": collection.ignored,
"media_links": [{
"media": {
"id": link.element.id,
"title": link.element.title,
},
"season": link.season,
"episode": link.episode,
} for link in collection.media_links]
}
}, 200
elif request.method == "POST":
data = request.form.to_dict()
if "redirect" in data:
del data["redirect"]
KEY_CONVERTER = {
"title": str,
"notes": str,
"ignored": environ_bool,
"keep_updated": environ_bool,
"watch_in_order": environ_bool,
}
for key in data:
if key not in KEY_CONVERTER:
return {
"status": False,
"error": f"Cannot set key {key!r} on MediaCollection",
}, 400
if "watch_in_order" in data: # TODO move to property
collection.watch_in_order_auto = False
collection.set(**{key: KEY_CONVERTER[key](val) for key, val in data.items()})
return redirect_back_or_okay()
else:
return {
"status": False,
"error": "405 Method Not Allowed",
}, 405
@flask_app.route("/api/media/list")
def api_media_list():
media_list: Iterable[MediaElement] = MediaElement.select()
@ -243,3 +321,59 @@ def api_media_list():
"progress": media.progress,
} for media in media_list],
}, 200
@flask_app.route("/api/media/<int:media_id>", methods=["GET", "POST"])
def api_media_element(media_id: int):
element: MediaElement = MediaElement.get(id=media_id)
if element is None:
return {
"status": False,
"error": f"Object not found",
}, 404
if request.method == "GET":
return {
"status": True,
"data": {
"id": element.id,
"title": element.title,
"notes": element.notes,
"release_date": element.release_date,
"length": element.length,
"progress": element.progress,
"ignored": element.ignored,
"watched": element.watched,
"can_considered": element.can_considered,
"collection_links": [{
"collection": {
"id": link.collection.id,
"title": link.collection.title,
},
"season": link.season,
"episode": link.episode,
} for link in element.collection_links]
}
}, 200
elif request.method == "POST":
data = request.form.to_dict()
if "redirect" in data:
del data["redirect"]
KEY_CONVERTER = {
"title": str,
"notes": str,
"progress": int,
"ignored": environ_bool,
"watched": environ_bool,
}
for key in data:
if key not in KEY_CONVERTER:
return {
"status": False,
"error": f"Cannot set key {key!r} on MediaElement",
}, 400
element.set(**{key: KEY_CONVERTER[key](val) for key, val in data.items()})
return redirect_back_or_okay()
else:
return {
"status": False,
"error": "405 Method Not Allowed",
}, 405

Loading…
Cancel
Save