js models working somewhat

master
Anton Lydike 4 years ago
parent 86cc2502a6
commit b3586a6708

@ -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):

@ -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')

@ -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
}
}
}

@ -1,12 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<script>(() => {onload_list = []; window.onload = (f) => {onload_list.push(f)}; window.__is_loaded = () => {onload_list.forEach(x => x());window.__is_loaded = () => undefined} })()</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.1/socket.io.js"></script>
<meta charset="UTF-8">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TOTPAL - {{ title }}</title>
<title>Family - {{ title }}</title>
<script src="{{ url_for('static', filename='api.js') }}"></script>
<script src="{{ url_for('static', filename='models.js') }}"></script>
<script src="{{ url_for('static', filename='site.js') }}"></script>
{% block head %}
{% endblock %}
@ -43,8 +44,5 @@
{% endblock %}
</div>
</footer>
<script>
if (__is_loaded) {__is_loaded()}
</script>
</body>
</html>

@ -5,38 +5,6 @@
{% endblock %}
{% block content %}
<h1>Games waiting:</h1>
<h1>Home</h1>
<form action="/room" method="POST" id="create-room">
<input type="text" placeholder="Name" name="name">
<button class="create-room" type="submit">Create game</button>
<input type="hidden" name="secret" class="insert-secret"/>
</form>
<ul class="active-lobbies"></ul>
<script>
onload(() => {
socket.on('room_list', draw_rooms);
function draw_rooms(list) {
console.log(list);
const root = $('.active-lobbies');
root.innerHTML = "";
list.forEach(room => {
const elm = create_elm(`<li>${room.name} with ${room.players.map(x => (x.online ? '&#9679; ' : '&#9675; ') + x.name).join(", ")} <a href="/room/${room.id}">JOIN</a></li>`)[0]
root.appendChild(elm)
})
}
$('form#create-room').addEventListener('submit', e => {
e.target.elements.secret.value = localStorage.getItem('secret')
});
draw_rooms({{ rooms | safe }})
})
</script>
{% endblock %}
Loading…
Cancel
Save