pygps/main.py
Klaus-Uwe Mitterer d29b5555e3 Fix access
2017-10-12 19:40:51 +02:00

197 lines
5 KiB
Python

import cgi
import datetime
import configparser
import pymysql
def getDatabase(path = "config.cfg"):
config = configparser.RawConfigParser()
config.read(path)
host = config.get("Database", "host")
user = config.get("Database", "user")
pwd = config.get("Database", "pass")
name = config.get("Database", "name")
conn = pymysql.connect(host, user, pwd, name)
cur = conn.cursor(pymysql.cursors.DictCursor)
return conn, cur
def application(env, re):
if env["REQUEST_METHOD"] == "POST":
args = cgi.parse_qs(env['wsgi.input'].readline().decode(), True)
elif env["REQUEST_METHOD"] == "GET":
args = cgi.parse_qs(env['QUERY_STRING'], True)
else:
re("405 Method Not Allowed", [])
return
if env["PATH_INFO"] in ("/endpoint", "/endpoint.php"):
try:
device = args["device"][0]
except:
re("400 Bad Request", [])
yield "<h1>400 Bad Request</h1>".encode()
yield "device is required.".encode()
return
try:
latitude = float(args["lat"][0].replace(",", "."))
longitude = float(args["lon"][0].replace(",", "."))
except Exception:
re("400 Bad Request", [])
yield "<h1>400 Bad Request</h1>".encode()
yield "lat and lon are required.".encode()
return
try:
altitude = float(args["alt"][0].replace(",", "."))
except:
altitude = None
try:
timestamp = datetime.datetime.fromtimestamp(float(args["t"][0]) / 1000)
except:
timestamp = datetime.datetime.now()
timestr = timestamp.strftime('%Y-%m-%d %H:%M:%S')
conn, cur = getDatabase()
sql = "INSERT INTO tracker(ts, device, lat, lon, alt) VALUES (%s, %s, %s, %s, %s);"
cur.execute(sql, (timestr, device, str(latitude), str(longitude), str(altitude) if altitude != None else None))
conn.commit()
cur.close()
conn.close()
re("200 OK", [])
yield "OK".encode()
return
if env["PATH_INFO"] in ("/location", "/location.php"):
try:
device = args["device"][0]
except:
re("400 Bad Request", [])
yield "<h1>400 Bad Request</h1>".encode()
yield "device is required.".encode()
return
conn, cur = getDatabase()
cur.execute("SELECT * FROM tracker WHERE device = %s ORDER BY ts DESC LIMIT 1;", device)
row = cur.fetchone()
cur.close()
conn.close()
re("200 OK", [["Content-Type", "text/html"]])
yield ("""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=utf-8>
<title>Current Location</title>
<link rel="stylesheet" href="https://npmcdn.com/leaflet@1.0.0-rc.3/dist/leaflet.css" />
<script src="https://npmcdn.com/leaflet@1.0.0-rc.3/dist/leaflet.js"></script>
</head>
<body>
<h1>My location at %s</h1>
<p>(last known position where I had a GPS signal, a network connection, and some battery power)</p>
<div id="map" style="height:500px;"></div>
<script>
var mymap = L.map("map").setView([%s, %s], 12);
L.tileLayer("https://b.tile.openstreetmap.org/{z}/{x}/{y}.png").addTo(mymap);
var marker = L.marker([%s, %s]).addTo(mymap);
</script>
</body>
</html>""" % (row["ts"], row["lat"], row["lon"], row["lat"], row["lon"])).encode()
return
if env["PATH_INFO"] in ("/access", "/access.php", "/export", "/export.php"):
try:
device = args["device"][0]
except:
re("400 Bad Request", [])
yield "<h1>400 Bad Request</h1>".encode()
yield "device is required.".encode()
return
on = args["on"][0] if "on" in args else None
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
frm = frm or datetime.datetime.now().strftime('%Y-%m-%d')
to = to or datetime.datetime.now().strftime('%Y-%m-%d')
for time in frm, to:
try:
datetime.datetime.strptime(time, "%Y-%m-%d")
except:
re("400 Bad Request", [])
yield "<h1>400 Bad Request</h1>".encode()
yield "Dates must be in YYYY-MM-DD format.".encode()
return
conn, cur = getDatabase()
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"']])
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["lat"], row["lon"])
output = "".join(output.rsplit(",", 1))
output += """ ]
}
}
]
}"""
cur.close()
conn.close()
yield output.encode()
return