From 8bf79a12881075437aa6e0aeaf3a753cd372da45 Mon Sep 17 00:00:00 2001 From: Laurent Bossavit Date: Thu, 5 May 2016 22:31:54 +0200 Subject: [PATCH] Adds an editor for geometry and properties --- backend.py | 42 +++++++--- editor/event-schema.json | 17 ++++ editor/index.html | 167 +++++++++++++++++++++++++++++++++++++++ examples/other.json | 69 ++++++++++++++++ 4 files changed, 285 insertions(+), 10 deletions(-) create mode 100644 editor/event-schema.json create mode 100644 editor/index.html create mode 100644 examples/other.json diff --git a/backend.py b/backend.py index 95ab272..9e493b8 100644 --- a/backend.py +++ b/backend.py @@ -6,6 +6,7 @@ import falcon import psycopg2 import uuid import json +import codecs def db_connect(): db_host = os.getenv("DB_HOST","localhost") @@ -13,6 +14,11 @@ def db_connect(): db = psycopg2.connect(dbname="oedb",host=db_host,password=db_password,user="postgres") return db +def standard_headers(resp): + resp.set_header('X-Powered-By', 'OpenEventDatabase') + resp.set_header('Access-Control-Allow-Origin', '*') + resp.set_header('Access-Control-Allow-Headers', 'X-Requested-With') + class StatsResource(object): def on_get(self, req, resp): db = db_connect() @@ -22,10 +28,21 @@ class StatsResource(object): cur.close() db.close() + standard_headers(resp) resp.body = """{"events_count": %s, "last_created": "%s", "last_updated": "%s"}""" % (stat[0], stat[1],stat[2]) - resp.set_header('X-Powered-By', 'OpenEventDatabase') - resp.set_header('Access-Control-Allow-Origin', '*') - resp.set_header('Access-Control-Allow-Headers', 'X-Requested-With') + resp.status = falcon.HTTP_200 + +class EventsResource(object): + def on_get(self,req,resp): + db = db_connect() + cur = db.cursor() + # get event geojson Feature + cur.execute(""" +SELECT format('{"type":"Feature", "id": "'|| events_id::text ||'", "properties": '|| events_tags::text ||', "geometry":'|| st_asgeojson(geom)) ||' }' +FROM events +JOIN geo ON (hash=events_geo)"""); + standard_headers(resp) + resp.body = '{"type": "FeatureCollection","features": ['+','.join([x[0] for x in cur.fetchall()])+']}' resp.status = falcon.HTTP_200 class EventResource(object): @@ -39,9 +56,7 @@ FROM events JOIN geo ON (hash=events_geo) WHERE events_id=%s;""", (id,)) e = cur.fetchone() - resp.set_header('X-Powered-By', 'OpenEventDatabase') - resp.set_header('Access-Control-Allow-Origin', '*') - resp.set_header('Access-Control-Allow-Headers', 'X-Requested-With') + standard_headers(resp) if e is not None: resp.body = e[0] resp.status = falcon.HTTP_200 @@ -50,9 +65,7 @@ WHERE events_id=%s;""", (id,)) db.close() def on_post(self, req, resp): - resp.set_header('X-Powered-By', 'OpenEventDatabase') - resp.set_header('Access-Control-Allow-Origin', '*') - resp.set_header('Access-Control-Allow-Headers', 'X-Requested-With') + standard_headers(resp) # get request body payload (geojson Feature) body = req.stream.read().decode('utf-8') @@ -94,16 +107,25 @@ WHERE events_id=%s;""", (id,)) resp.body = """{"id":"%s"}""" % (e[0]) resp.status = falcon.HTTP_201 +class StaticResource(object): + def on_get(self, req, resp): + resp.status = falcon.HTTP_200 + resp.content_type = 'text/html' + with codecs.open('editor/index.html', 'r', 'utf-8') as f: + resp.body = f.read() # falcon.API instances are callable WSGI apps app = falcon.API() # Resources are represented by long-lived class instances +events = EventsResource() event = EventResource() stats = StatsResource() +editor = StaticResource() # things will handle all requests to the matching URL path +app.add_route('/events', events) app.add_route('/event/{id}', event) # handle single event requests app.add_route('/event', event) # handle single event requests app.add_route('/stats', stats) - +app.add_route('/editor', editor) diff --git a/editor/event-schema.json b/editor/event-schema.json new file mode 100644 index 0000000..f93009c --- /dev/null +++ b/editor/event-schema.json @@ -0,0 +1,17 @@ + +{ + "title": "Evenement", + "type": "object", + "id": "event", + "properties": { + "what" : { + "type":"string", + "title":"Libellé de l'événement" + }, + "when" : { + "title":"Date et heure de début", + "type" : "string", + "format" : "datetime-local" + } + } +} diff --git a/editor/index.html b/editor/index.html new file mode 100644 index 0000000..9c2bd6f --- /dev/null +++ b/editor/index.html @@ -0,0 +1,167 @@ + + + + + Détail d'un événement + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Events

+
+
+
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/examples/other.json b/examples/other.json new file mode 100644 index 0000000..b67f41e --- /dev/null +++ b/examples/other.json @@ -0,0 +1,69 @@ +{ + "geometry": + { + "type": "Polygon", + "coordinates": [ + [ + [ + 2.396119236946106, + 48.84943571607033 + ], + [ + 2.395314574241638, + 48.84936511598567 + ], + [ + 2.394644021987915, + 48.8490791846248 + ], + [ + 2.394316792488098, + 48.84860968884877 + ], + [ + 2.3943114280700684, + 48.84820020021693 + ], + [ + 2.3946386575698853, + 48.84773775644264 + ], + [ + 2.3950570821762085, + 48.84749064733159 + ], + [ + 2.3957008123397827, + 48.84733532098047 + ], + [ + 2.396720051765442, + 48.8474694664939 + ], + [ + 2.3973584175109863, + 48.84796368370562 + ], + [ + 2.39751398563385, + 48.84849672680203 + ], + [ + 2.3970580101013184, + 48.849114484881156 + ], + [ + 2.396119236946106, + 48.84943571607033 + ] + ] + ] + } + , + "properties":{ + "type":"protest" + ,"what":"Loi travail" + ,"start":"2016-06-10T21:00+01:00" + ,"stop":"2016-06-10T23:30+01:00" + } +} \ No newline at end of file