diff --git a/main.py b/main.py index 2e87fce..6104d33 100644 --- a/main.py +++ b/main.py @@ -4,6 +4,8 @@ import configparser import pymysql +GJSON = 0 + def getDatabase(path = "config.cfg"): config = configparser.RawConfigParser() config.read(path) @@ -18,6 +20,83 @@ def getDatabase(path = "config.cfg"): return conn, cur +def buildGJSON(data): + output = """{ + "type": "FeatureCollection", + "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, + "features": [ + { "type": "Feature", + "properties": { + "Name": null, + "description": null, + "timestamp": null, + "begin": null, + "end": null, + "altitudeMode": null, + "tessellate": -1, + "extrude": 0, + "visibility": -1, + "drawOrder": null, + "icon": null, + "styleUrl": "#style", + "styleHash": "1a1ac94e", + "stroke": "#ffff00", + "stroke_opacity": "0.4980392156862745", + "stroke_width": "4", + "fill": "#00ff00", + "fill_opacity": "0.4980392156862745" + }, + "geometry": { + "type": "LineString", + "coordinates": [ +""" + + for row in data: + output += " [ %s, %s ],\n" % (row["lon"], row["lat"]) + + output = "".join(output.rsplit(",", 1)) + + output += """ ] + } + } + ] +}""" + + headers = [["Content-Type", "application/vnd.geo+json"], ['Content-Disposition', 'attachment; filename="export.geojson"']] + + return headers, output + +def buildGPX(data): + output = """ + + + export.gpx + GPS Data Export + + pygps + + + + +""" + + for row in data: + output += """ + + +""" % (row["lat"], row["lon"], row["ts"].isoformat()) + + + output += """ + + +""" + + headers = [["Content-Type", "application/gpx+xml"], ['Content-Disposition', 'attachment; filename="export.gpx"']] + return headers, output + def application(env, re): if env["REQUEST_METHOD"] == "POST": args = cgi.parse_qs(env['wsgi.input'].readline().decode(), True) @@ -127,6 +206,19 @@ def application(env, re): frm = on if on else args["from"][0] if "from" in args else None to = on if on else args["to"][0] if "to" in args else None + if "format" in args: + if args["format"][0] in ("json", "gjson", "geojson", "gj") or not args["format"]: + builder = buildGJSON + elif args["format"][0] == "gpx": + builder = buildGPX + else: + re("400 Bad Request", []) + yield "

400 Bad Request

".encode() + yield "Unknown format: %s" % args["format"] + return + else: + builder = buildGJSON + frm = frm or "2000-01-01" to = to or datetime.datetime.now().strftime('%Y-%m-%d') @@ -144,49 +236,11 @@ def application(env, re): sql = "SELECT ts, lat, lon FROM tracker WHERE device=%s AND DATE(ts)>=%s and DATE(ts)<=%s ORDER BY ts ASC;"; cur.execute(sql, (device, frm, to)) - re("200 OK", [["Content-Type", "application/vnd.geo+json"], ['Content-Disposition', 'attachment; filename="export.geojson"']]) + data = cur.fetchall() - output = """{ - "type": "FeatureCollection", - "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } }, - "features": [ - { "type": "Feature", - "properties": { - "Name": null, - "description": null, - "timestamp": null, - "begin": null, - "end": null, - "altitudeMode": null, - "tessellate": -1, - "extrude": 0, - "visibility": -1, - "drawOrder": null, - "icon": null, - "styleUrl": "#style", - "styleHash": "1a1ac94e", - "stroke": "#ffff00", - "stroke_opacity": "0.4980392156862745", - "stroke_width": "4", - "fill": "#00ff00", - "fill_opacity": "0.4980392156862745" - }, - "geometry": { - "type": "LineString", - "coordinates": [ -""" - - for row in cur.fetchall(): - output += " [ %s, %s ],\n" % (row["lon"], row["lat"]) - - output = "".join(output.rsplit(",", 1)) - - output += """ ] - } - } - ] -}""" + headers, output = builder(data) + re("200 OK", headers) cur.close() conn.close()