diff --git a/server/abstract_api.py b/server/abstract_api.py index 55ba8dc..fcc72a3 100644 --- a/server/abstract_api.py +++ b/server/abstract_api.py @@ -71,7 +71,7 @@ def _get_target_class(rel: RelationshipDefinition) -> Type[StructuredNode]: return getattr(sys.modules[rel.module_name], target_cls) if isinstance(target_cls, str) else target_cls -def construct_object_from_request(cls: Type[StructuredNode], uid=None): +def construct_object_from_request(cls: Type[StructuredNode], uid=None, data: dict = dict()): """Construct an obect of class cls from request data""" # properties that you do not want to initialize or change this way if uid: @@ -87,6 +87,8 @@ def construct_object_from_request(cls: Type[StructuredNode], uid=None): for name, value in cls.__dict__.items(): if name[0] == '_' or name in BLOCKED_PROPERTIES or not name[0].islower(): continue + if name not in data: + continue cls_name = value.__class__.__name__ convert_with = None @@ -100,22 +102,20 @@ def construct_object_from_request(cls: Type[StructuredNode], uid=None): elif cls_name == 'FloatProperty': convert_with = float elif cls_name == 'RelationshipDefinition': - if name not in request.form: - continue - - target_cls: Type[StructuredNode] = _get_target_class(value) - for val in request.form.getlist(name): - target = target_cls.nodes.first_or_none(uid=val) - if not target: - raise ApiError(f'Cannot find referenced object uid={val} of type {target_cls.__name__}!') - - relationship_attach_callbacks.append(_connect_callback(getattr(obj, name), target)) + pass + #target_cls: Type[StructuredNode] = _get_target_class(value) + # + #for val in data[name] if + # target = target_cls.nodes.first_or_none(uid=val) + # if not target: + # raise ApiError(f'Cannot find referenced object uid={val} of type {target_cls.__name__}!') + # + # relationship_attach_callbacks.append(_connect_callback(getattr(obj, name), target)) if not convert_with: # skip this property continue - if name in request.form: - setattr(obj, name, convert_with(request.form.get(name))) + setattr(obj, name, convert_with(data[name])) return obj, lambda: [c() for c in relationship_attach_callbacks] @@ -125,7 +125,7 @@ def handle_object_api_request(cls: Type[StructuredNode]): if request.method == 'GET': return jsonify([obj.json(include_relations=False) for obj in cls.nodes.all()]) if request.method == 'POST': - obj, attach_relationships = construct_object_from_request(cls) + obj, attach_relationships = construct_object_from_request(cls, data=request.get_json()) obj.save() attach_relationships() return jsonify(obj.json()) @@ -139,7 +139,7 @@ def handle_object_api_request_id(cls: Type[StructuredNode], uid: str): raise ApiError.not_found(cls, uid) return jsonify(obj.json()) if request.method == 'PUT': - obj, attach_relationships = construct_object_from_request(cls, uid=uid) + obj, attach_relationships = construct_object_from_request(cls, uid=uid, data=request.get_json()) obj.save() attach_relationships() return jsonify(obj.json()) @@ -174,7 +174,7 @@ def handle_object_api_request_for_relation(cls: Type[StructuredNode], uid, relat getattr(obj, relation).disconnect_all() getattr(obj, relation).connect(target_obj) - return jsonify(obj) + return jsonify(obj.json()) def register_api_object(app: Flask, cls: Type[StructuredNode], name: Optional[str] = None): diff --git a/server/api.py b/server/api.py index ead0925..7a6f96c 100644 --- a/server/api.py +++ b/server/api.py @@ -1,6 +1,6 @@ from .models import * from server.abstract_api import ApiError, register_api_object -from flask import Flask +from flask import Flask, render_template def attach_to_flask(app: Flask): @@ -15,4 +15,8 @@ def attach_to_flask(app: Flask): register_api_object(app, Image) register_api_object(app, VisitRel) + @app.route('/') + def home(): + return render_template('start.html') + diff --git a/static/api.js b/static/api.js index ff5f620..3e46f40 100644 --- a/static/api.js +++ b/static/api.js @@ -9,10 +9,11 @@ class StructuredNode { this.definition = StructuredNode.classes[this.constructor.name] this.hooks = [] this.deleted = false + this.__name__ = this.constructor.name.toLowerCase() } check(name, type, new_value) { - + return true } _link_property(name, elm) { @@ -21,7 +22,7 @@ class StructuredNode { if (!relation) { throw new ApiError(`Cannot find realation ${name} of object ${this.constructor.name}!`, 404, {obj: this, elm: elm}) } - const type = StructuredNode.classes[relation.target] + const type = StructuredNode.classes[relation.target].klass if (typeof elm == "string") { elm = type.by_id(elm) @@ -40,7 +41,7 @@ class StructuredNode { this.json[name] = elm } - return Api.post(`/${this.constructor.name}/${this.json.uid}/${name}/${elm.json.uid}`).then(json => { + return Api.post(`/${this.__name__}/${this.json.uid}/${name}/${elm.json.uid}`).then(json => { this.json = json this.update('link') return this @@ -49,12 +50,15 @@ class StructuredNode { } _unlink_property(name, type, elm) { - this.json[name] = this.json[name].filter(elm => elm.json.uid === (elm.uid || elm)) - + return Api.delete(`/${this.__name__}/${this.json.uid}/${name}/${elm.json.uid}`).then(json => { + this.json = json + this.update('link') + return this + }) } static by_id(uid) { - return Api.get(this.constructor.name + '/' + uid).then(x => x.map(elm => new this.constructor(elm))) + return Api.get('/' + this.name.toLowerCase() + '/' + uid).then(x => new this(x)) } static find(attributes, settings) { @@ -67,14 +71,14 @@ class StructuredNode { } if (this.json.uid) { - return Api.put(`/${this.constructor.name}/${this.json.uid}`, this.changes).then(json => { + return Api.put(`/${this.__name__}/${this.json.uid}`, this.changes).then(json => { this.json = json this.changes = {} this.update('save') return this }) } else { - return Api.post('/' + this.constructor.name, this.json).then(json => { + return Api.post('/' + this.__name__, this.json).then(json => { this.json = json this.changes = {} this.update('created') @@ -88,14 +92,14 @@ class StructuredNode { throw new ApiError("Cannot delete object that does not exist yet!", {obj: this}) } this.deleted = true - Api.delete(`/${this.constructor.name}/${this.json.uid}`).then(r => { + Api.delete(`/${this.__name__}/${this.json.uid}`).then(r => { this.update('deleted') return this }) } exists() { - return !this.deleted && !!this.json.id + return !this.deleted && !!this.json.uid } onupdate(callback) { @@ -114,7 +118,8 @@ class StructuredNode { } static registerClassDefinition(klass, props, rels) { - StructuredNode.classes[klass.constructor.name] = {klass, props, rels} + console.log(klass, props, rels) + StructuredNode.classes[klass.name] = {klass, props, rels} } } @@ -126,9 +131,9 @@ class Api { } static get(url) { - fetch('/api' + url, {headers: Api.headers()}).then(r => { + return fetch('/api' + url, {headers: Api.headers()}).then(r => { if (r.ok) { - return r.json + return r.json() } else { // evaluate response and raise error return ApiError.fromResponse(r) @@ -136,9 +141,9 @@ class Api { }) } static post(url, body="") { - fetch('/api' + url, {headers: Api.headers(), body: JSON.stringify(body), method: 'POST'}).then(r => { + return fetch('/api' + url, {headers: Api.headers(), body: JSON.stringify(body), method: 'POST'}).then(r => { if (r.ok) { - return r.json + return r.json() } else { // evaluate response and raise error return ApiError.fromResponse(r) @@ -146,9 +151,9 @@ class Api { }) } static put(url, body) { - fetch('/api' + url, {headers: Api.headers(), body: JSON.stringify(body), method: 'PUT'}).then(r => { + return fetch('/api' + url, {headers: Api.headers(), body: JSON.stringify(body), method: 'PUT'}).then(r => { if (r.ok) { - return r.json + return r.json() } else { // evaluate response and raise error return ApiError.fromResponse(r) @@ -156,7 +161,7 @@ class Api { }) } static delete(url) { - fetch('/api' + url, {headers: Api.headers(), method: 'DELETE'}).then(r => { + return fetch('/api' + url, {headers: Api.headers(), method: 'DELETE'}).then(r => { if (r.ok) { return r } else { @@ -168,7 +173,8 @@ class Api { static headers() { return { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + // 'Authorization': 'Bearer ' + Api.token } } } diff --git a/templates/base.html b/templates/base.html index 954a365..942f059 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,12 +1,13 @@
- -