diff --git a/main.py b/main.py
index 0f0b268..a655ed7 100644
--- a/main.py
+++ b/main.py
@@ -7,220 +7,176 @@ import workers.val
import workers.closest
import workers.radar
+from classes.request import *
+from classes.response import *
+
HTTP200 = "200 OK"
HTTP400 = "400 Bad Request"
+HTTP405 = "405 Method Not Allowed"
HTTP500 = "500 Internal Server Error"
HTML = "text/html"
JSON = "application/json"
XML = "text/xml"
-def doConn(args, cfrm = None, cto = None):
+def doConn(req):
+ try:
+ getfrm = req.cfrm if "cfrm" in dir(req) and req.cfrm else req.args["from"][0] if "from" in req.args else None
+ getto = req.cto if "cto" in dir(req) and req.cto else req.args["to"][0] if "to" in req.args else None
try:
- try:
- frm = (cfrm or args["from"][0]).encode("latin-1").decode("utf-8")
- to = (cto or args["to"][0]).encode("latin-1").decode("utf-8")
- except UnicodeDecodeError:
- frm = cfrm or args["from"][0]
- to = cto or args["to"][0]
+ frm = getfrm.encode("latin-1").decode("utf-8")
+ to = getto.encode("latin-1").decode("utf-8")
+ except UnicodeDecodeError:
+ frm = getfrm
+ to = getto
- if not frm or not to:
- raise ValueError()
+ if not frm or not to:
+ raise ValueError()
- except Exception:
- content = "
400 Bad Request
\n"
- content += "\"from\"and \"to\" values are required for this type of request.\n"
- return (HTTP400, HTML, content)
+ except Exception:
+ content = "400 Bad Request
\n"
+ content += "\"from\"and \"to\" values are required for this type of request."
+ return Response(HTTP400, HTML, content)
- count = args["count"][0] if "count" in args and args["count"] else 6
- date = args["date"][0] if "date" in args and args["date"] else datetime.datetime.strftime(datetime.datetime.now(pytz.timezone("Europe/Vienna")),"%d.%m.%Y")
- time = args["time"][0] if "time" in args and args["time"] else datetime.datetime.strftime(datetime.datetime.now(pytz.timezone("Europe/Vienna")),"%H:%M")
- mode = True if "mode" in args and args["mode"] and args["mode"][0].lower() == "arr" else False
- details = True if "details" in args else False
-
- try:
- count = int(count)
- if count < 0 or count > 10:
- raise ValueError()
- except:
- content = "400 Bad Request
\n"
- content += "The \"count\" value must be a value between 0 and 10."
- return (HTTP400, HTML, content)
-
- try:
- outtime = datetime.datetime.strptime("%s %s" % (date, time), "%d.%m.%Y %H:%M")
- except:
- content = "400 Bad Request
\n"
- content += "The \"date\" value must be in DD.MM.YYYY format, the \"time\" value must be in HH:MM format."
- return (HTTP400, HTML, content)
-
- via = list(args["via"]) if "via" in args else None
-
- if via and len(via) > 3:
- content = "400 Bad Request
\n"
- content += "It is not possible to route through more than three \"via\" stations."
- return (HTTP400, HTML, content)
-
- json = "json" in args
-
- try:
- content = workers.conn.worker(frm, to, count, outtime, mode, details, json, via)
- except Exception as e:
- content = "500 Internal Server Error
\n"
- if "debug" in args:
- content += str(e)
- return (HTTP500, HTML, content)
-
- return (HTTP200, JSON if json else XML, content)
-
-def doVal(args, cfrm):
- try:
- try:
- name = (cfrm or args["name"][0]).encode("latin-1").decode("utf-8")
- except UnicodeDecodeError:
- name = cfrm or args["name"][0]
-
- if not name:
- raise ValueError()
-
- except:
- content = "400 Bad Request
\n"
- content += "A \"name\" value is required for this type of request."
- return HTTP400, HTML, content
-
- json = "json" in args
-
- try:
- content = workers.val.worker(name, json)
-
- except Exception as e:
- content = "500 Internal Server Error
\n"
- if "debug" in args:
- content += str(e).encode()
- return HTTP500, HTML, content
-
- return HTTP200, JSON if json else XML, content
-
-def doNearby(args):
- try:
- lat = float(args["lat"][0].replace(",", "."))
- lon = float(args["lon"][0].replace(",", "."))
-
- if (not lat and not lat == float(0)) or (not lon and not lon == float(0)):
- raise ValueError()
-
- except:
- content = "400 Bad Request
\n"
- content += "\"lat\" and \"lon\" values are required for this type of request."
- return HTTP400, HTML, content
-
- distance = args["distance"][0] if "distance" in args and args["distance"] else 1000
-
- try:
- distance = int(distance)
- if distance < 0 or distance > 10000:
- raise ValueError()
- except:
- content = "400 Bad Request
\n"
- content += "\"distance\" must be a value between 0 and 10000."
- return HTTP400, HTML, content
-
- json = "json" in args
-
- try:
- content = workers.closest.worker(lat, lon, distance, json)
-
- except Exception as e:
- content = "500 Internal Server Error
"
- if "debug" in args:
- content += repr(e)
- return HTTP500, HTML, content
-
- return HTTP200, JSON if json else XML, content
-
-def doRadar(args):
- trains = args["train"] if "train" in args else None
- json = "json" in args
-
- try:
- content = workers.radar.worker(trains, json)
- except Exception as e:
- content = "500 Internal Server Error
\n"
- if "debug" in args:
- content += repr(e)
- return HTTP500, HTML, content
-
- return HTTP200, JSON if json else XML, content
-
-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
-
- conn = False
- val = False
- cfrm = None
- cto = None
-
- split = env["PATH_INFO"].split("/")
- split = [i.strip() for i in split]
-
- while "" in split:
- split.remove("")
-
- if len(split) > 2:
- re("400 Bad Request", [])
- yield "400 Bad Request
".encode()
- yield "Only one (validate) or two (conn) arguments may be passed as path.".encode()
- return
-
- if len(split) > 0:
- if len(split) == 1:
- val = True
- else:
- conn = True
- cto = split[1].encode("latin-1").decode("utf-8")
-
- cfrm = split[0].encode("latin-1").decode("utf-8")
+ count = req.args["count"][0] if "count" in req.args and req.args["count"] else 6
+ date = req.args["date"][0] if "date" in req.args and req.args["date"] else datetime.datetime.strftime(datetime.datetime.now(pytz.timezone("Europe/Vienna")),"%d.%m.%Y")
+ time = req.args["time"][0] if "time" in req.args and req.args["time"] else datetime.datetime.strftime(datetime.datetime.now(pytz.timezone("Europe/Vienna")),"%H:%M")
+ mode = True if "mode" in req.args and req.args["mode"] and req.args["mode"][0].lower() == "arr" else False
+ details = True if "details" in req.args else False
try:
- rtype = "conn" if conn else "val" if val else args["type"][0]
+ count = int(count)
+ if count < 0 or count > 10:
+ raise ValueError()
except:
- re("400 Bad Request", [])
- yield "400 Bad Request
".encode()
- yield "A request type must be provided.".encode()
- return
+ content = "400 Bad Request
\n"
+ content += "The \"count\" value must be a value between 0 and 10."
+ return Response(HTTP400, HTML, content)
- if rtype.lower() in ["conn", "connection"]:
- status, ctype, content = doConn(args, cfrm, cto)
- re(status, [("Content-Type", ctype)])
- yield content.encode()
- return
+ try:
+ outtime = datetime.datetime.strptime("%s %s" % (date, time), "%d.%m.%Y %H:%M")
+ except:
+ content = "400 Bad Request
\n"
+ content += "The \"date\" value must be in DD.MM.YYYY format, the \"time\" value must be in HH:MM format."
+ return Response(HTTP400, HTML, content)
- elif rtype.lower() in ["val", "validate"]:
- status, ctype, content = doVal(args, cfrm)
- re(status, [("Content-Type", ctype)])
- yield content.encode()
- return
+ via = list(req.args["via"]) if "via" in req.args else None
- elif rtype.lower() in ["closest", "close", "near", "nearby"]:
- status, ctype, content = doNearby(args)
- re(status, [("Content-Type", ctype)])
- yield content.encode()
- return
+ if via and len(via) > 3:
+ content = "400 Bad Request
\n"
+ content += "It is not possible to route through more than three \"via\" stations."
+ return Response(HTTP400, HTML, content)
- elif rtype.lower() in ["radar", "live"]:
- status, ctype, content = doRadar(args)
- re(status, [("Content-Type", ctype)])
- yield content.encode()
- return
+ try:
+ content = workers.conn.worker(frm, to, count, outtime, mode, details, req.json, via)
+ except Exception as e:
+ content = "500 Internal Server Error
\n"
+ if "debug" in req.args:
+ content += str(e)
+ return Response(HTTP500, HTML, content)
+
+ return Response(HTTP200, JSON if req.json else XML, content)
+
+def doVal(req):
+ try:
+ try:
+ name = (req.cfrm or req.args["name"][0]).encode("latin-1").decode("utf-8")
+ except UnicodeDecodeError:
+ name = req.cfrm or req.args["name"][0]
+
+ if not name:
+ raise ValueError()
+
+ except Exception:
+ content = "400 Bad Request
\n"
+ content += "A \"name\" value is required for this type of request."
+ return Response(HTTP400, HTML, content)
+
+ try:
+ content = workers.val.worker(name, req.json)
+
+ except Exception as e:
+ content = "500 Internal Server Error
\n"
+ if "debug" in req.args:
+ content += str(e).encode()
+ return Response(HTTP500, HTML, content)
+
+ return Response(HTTP200, JSON if req.json else XML, content)
+
+def doNearby(req):
+ try:
+ lat = float(req.args["lat"][0].replace(",", "."))
+ lon = float(req.args["lon"][0].replace(",", "."))
+
+ if (not lat and not lat == float(0)) or (not lon and not lon == float(0)):
+ raise ValueError()
+
+ except:
+ content = "400 Bad Request
\n"
+ content += "\"lat\" and \"lon\" values are required for this type of request."
+ return Response(HTTP400, HTML, content)
+
+ distance = req.args["distance"][0] if "distance" in req.args and req.args["distance"] else 1000
+
+ try:
+ distance = int(distance)
+ if distance < 0 or distance > 10000:
+ raise ValueError()
+ except:
+ content = "400 Bad Request
\n"
+ content += "\"distance\" must be a value between 0 and 10000."
+ return Response(HTTP400, HTML, content)
+
+ try:
+ content = workers.closest.worker(lat, lon, distance, req.json)
+
+ except Exception as e:
+ content = "500 Internal Server Error
"
+ if "debug" in req.args:
+ content += repr(e)
+ return Response(HTTP500, HTML, content)
+
+ return Response(HTTP200, JSON if req.json else XML, content)
+
+def doRadar(req):
+ trains = req.args["train"] if "train" in req.args else None
+
+ try:
+ content = workers.radar.worker(trains, req.json)
+ except Exception as e:
+ content = "500 Internal Server Error
\n"
+ if "debug" in req.args:
+ content += repr(e)
+ return Response(HTTP500, HTML, content)
+
+ return Response(HTTP200, JSON if req.json else XML, content)
+
+def doNot(req):
+ content = "400 Bad Request
"
+ content += "The request type you submitted is invalid."
+ return Response(HTTP400, HTML, content)
+
+def application(env, re):
+ try:
+ req = Request(env)
+
+ if req.rtype in ["conn", "connection"]:
+ res = doConn(req)
+ elif req.rtype in ["val", "validate"]:
+ res = doVal(req)
+ elif req.rtype in ["closest", "close", "near", "nearby"]:
+ res = doNearby(req)
+ elif req.rtype in ["radar", "live"]:
+ res = doRadar(req)
+ else:
+ res = doNot(req)
+
+ except IllegalMethodException as e:
+ res = Response(HTTP405, HTML, str(e))
+ except InvalidArgumentException as e:
+ res = Response(HTTP400, HTML, str(e))
+
+ re(res.status, [("Content-Type", res.ctype)])
+ yield res.content.encode()
+ return
- else:
- re("400 Bad Request", [])
- yield "400 Bad Request
".encode()
- yield "The request type you submitted is invalid.".encode()
- return