diff --git a/classes/__init__.py b/classes/__init__.py
index 4c62a20..fd10124 100644
--- a/classes/__init__.py
+++ b/classes/__init__.py
@@ -17,9 +17,9 @@ class Station:
return self.xcoord
class Service:
- def __init__(self, name, svtype, depst, deptime, arrst, arrtime, deppf = None, currdep = None, arrpf = None, curarr = None, img = None, url = None):
+ def __init__(self, name, depst, deptime, arrst, arrtime, dest = None, deppf = None, currdep = None, arrpf = None, curarr = None):
self.name = name
- self.svtype = svtype
+ self.dest = dest
self.depst = depst
self.deptime = deptime
self.arrst = arrst
@@ -28,14 +28,14 @@ class Service:
self.currdep = currdep
self.arrpf = arrpf
self.curarr = curarr
- self.img = img
- self.url = url
+
+ def duration():
+ return self.arrtime - self.deptime
class Connection:
- def __init__(self, buyurl = None, statusurl = None):
+ def __init__(self, buyurl = None):
self.services = []
self.buyurl = buyurl
- self.statusurl = statusurl
def addService(self, service):
self.services.append(service)
@@ -75,3 +75,9 @@ class Connection:
return self.services[-1].currarr
except:
return None
+
+ def duration(self):
+ try:
+ return self.services[-1].arrtime - self.services[0].deptime
+ except:
+ return None
diff --git a/main.py b/main.py
index 6399ef8..919d311 100644
--- a/main.py
+++ b/main.py
@@ -1,5 +1,6 @@
import cgi
import datetime
+import pytz
import workers.conn
import workers.val
@@ -36,10 +37,11 @@ def application(env, re):
yield "\"from\" and \"to\" values are required for this type of request.".encode()
return
- count = args["count"][0] if "count" in args and args["count"] else 3
- date = args["date"][0] if "date" in args and args["date"] else datetime.datetime.strftime(datetime.datetime.now(),"%d.%m.%Y")
- time = args["time"][0] if "time" in args and args["time"] else datetime.datetime.strftime(datetime.datetime.now(),"%H:%M")
+ count = args["count"][0] if "count" in args and args["count"] else 1
+ 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)
@@ -60,16 +62,18 @@ def application(env, re):
return
try:
- output = workers.conn.worker(frm, to, count, outtime, mode)
+ output = workers.conn.worker(frm, to, count, outtime, mode, details)
except Exception as e:
re("500 Internal Server Error", [])
yield "
500 Internal Server Error
".encode()
if "debug" in args:
yield str(e).encode()
+ raise
return
re("200 OK", [])
- return output.encode()
+ yield output.encode()
+ return
elif rtype.lower() in ["val", "validate"]:
try:
diff --git a/workers/conn.py b/workers/conn.py
index 112587b..a425653 100644
--- a/workers/conn.py
+++ b/workers/conn.py
@@ -1,9 +1,15 @@
from bs4 import BeautifulSoup
import requests
import datetime
-import workers.val
+import pytz
-def connRequest(frm, to, count = 3, time = datetime.datetime.now(), mode = False):
+import workers.val
+from classes import *
+
+def getStation(name):
+ return list(workers.val.validateName(name))[0]
+
+def connRequest(frm, to, count = 3, time = datetime.datetime.now(), mode = False, details = False):
outdate = datetime.datetime.strftime(time,"%d.%m.%Y")
outtime = datetime.datetime.strftime(time,"%H:%M")
@@ -13,11 +19,204 @@ def connRequest(frm, to, count = 3, time = datetime.datetime.now(), mode = False
if "GO_conViewMode=outward" not in source:
raise ValueError("No connection found.")
- return source
+ juha = BeautifulSoup(source, "html5lib")
+
+ if details:
+ for a in juha.findAll("a"):
+ if a.get("href") and "HWAI=CONNECTION$" in a.get("href"):
+ dpage = a.get("href")
-def getStation(name):
- return list(workers.val.validateName(name))[0]
+ ssource = requests.get(dpage).text
+ suppe = BeautifulSoup(ssource, "html5lib")
+
+ for i in range(0, count):
+ cont = suppe.find("tr", id="trC0-%i" % i)
+ if not cont:
+ break
-def worker(frm, to, count = 3, time = datetime.datetime.now(), mode = False):
- source = connRequest(frm, to, count, time, mode)
- conns = dissem(source)
+ buyurl = None
+
+ for url in cont.findAll("a"):
+ if url.get("href") and "https://tickets.oebb.at/de/ticket/ticket?" in url.get("href"):
+ buyurl = url.get("href")
+
+ conn = Connection(buyurl)
+
+ lines = cont.findAll("tr", { "class": "tpDetails" })[1:]
+ cdate = None
+
+ for line in range(0, len(lines), 3):
+ serv = lines[line:line + 3]
+ dep = serv[0]
+ arr = serv[1]
+ det = serv[2]
+
+ depst = list(workers.val.validateName(dep.find("td", { "class": "station" }).findAll("a")[0].string))[0]
+ depdate = dep.find("td", { "class": "date" }).string.strip() or cdate
+ deptime = dep.find("td", { "class": "timeValue" }).find("span").string.split()[1].strip()
+ depprog = (dep.find("span", { "class": "prognosis" }).find("span") or dep.find("span", { "class": "prognosis" })).string.strip() or None
+ depplat = (dep.find("td", { "class": "platform" }).find("span") or dep.find("td", { "class": "platform" })).string.strip() or None
+
+ walk = dep.find("img", { "class": "product" }).get("src") == "/img/vs_oebb/fuss_pic.gif"
+ name = dep.find("img", { "class": "product" }).get("alt") if not walk else "Walk"
+
+ if not walk:
+ purl = dep.find("td", { "class": "product" }).find("a").get("href")
+ psource = requests.get(purl).text
+
+ zuppa = BeautifulSoup(psource, "html5lib")
+ dest = list(workers.val.validateName(zuppa.findAll("div", { "class": "block" })[2].text.split(":")[1].strip()))[0]
+
+ arrst = list(workers.val.validateName(arr.find("td", { "class": "station" }).findAll("a")[0].string))[0]
+ arrdate = (arr.find("td", { "class": "date" }).find("span") or arr.find("td", { "class": "date" })).string.strip() or depdate
+ arrtime = arr.find("td", { "class": "timeValue" }).find("span").string.split()[1].strip()
+ arrprog = (arr.find("span", { "class": "prognosis" }).find("span") or arr.find("span", { "class": "prognosis" })).string.strip() or None
+ arrplat = (arr.find("td", { "class": "platform" }).find("span") or arr.find("td", { "class": "platform" })).string.strip() or None
+
+ depts = datetime.datetime.strptime("%s %s" % (depdate, deptime), "%d.%m.%Y %H:%M")
+ arrts = datetime.datetime.strptime("%s %s" % (arrdate, arrtime), "%d.%m.%Y %H:%M")
+
+ depprog = deptime if depprog == "pünktlich" else depprog
+ arrprog = arrtime if arrprog == "pünktlich" else arrprog
+
+ cdate = arrdate
+
+ svc = Service(name, depst, depts, arrst, arrts, dest, depplat, depprog, arrplat, arrprog)
+ conn.addService(svc)
+
+ yield conn
+
+ else:
+ for i in range(0, count):
+ det = juha.find("tr", id="trOverviewC0-%i" % i)
+ if not det:
+ break
+
+ stations = det.find("td", { "class": "station" }).findAll("div")
+ depst = getStation(stations[0].text.strip())
+ arrst = getStation(stations[-1].text.strip())
+
+ dates = det.find("td", { "class": "date" }).text.split()
+ depdate = dates[0]
+ try:
+ arrdate = dates[1]
+ except:
+ arrdate = depdate
+
+ times = det.find("div", { "class": "planed" }).text
+ deptime = times.split()[0]
+ arrtime = times.split()[2]
+
+ projections = det.find("div", { "class": "prognosis" })
+ curdep = None
+ curarr = None
+
+ depts = datetime.datetime.strptime("%s %s" % (depdate, deptime), "%d.%m.%Y %H:%M")
+ arrts = datetime.datetime.strptime("%s %s" % (arrdate, arrtime), "%d.%m.%Y %H:%M")
+
+ name = "/".join([img.get("title") for img in det.findAll("img", { "class": "product" })])
+
+ ticketurl = det.find("td", { "class": "fares" }).find("a").get("href")
+
+ svc = Service(name, depst, depts, arrst, arrts, currdep = curdep, curarr = curarr)
+ con = Connection(ticketurl)
+
+ con.addService(svc)
+
+ yield con
+
+def worker(frm, to, count = 3, time = datetime.datetime.now(pytz.timezone("Europe/Vienna")), mode = False, details = False):
+ conns = connRequest(getStation(frm), getStation(to), count, time, mode, details)
+ i = 0
+
+ output = """
+
+"""
+
+ for conn in conns:
+ hrs, scs = divmod(conn.duration().total_seconds(), 3600)
+ mns, rmd = divmod(scs, 60)
+
+ chg = max(len([service for service in conn.services if service.name != "Walk"]) - 1, 0) if details else max(len([service for service in conn.services[0].name.split("/") if service != "Walk"]) - 1, 0)
+
+ ddt = datetime.datetime.strftime(conn.deptime(), "%d.%m.%Y")
+ dtm = datetime.datetime.strftime(conn.deptime(), "%H:%M")
+
+ adt = datetime.datetime.strftime(conn.arrtime(), "%d.%m.%Y")
+ atm = datetime.datetime.strftime(conn.arrtime(), "%H:%M")
+
+ output += """
+
+ %s
+ %s
+
+
+ %s
+ %s
+
+
+
+ %s
+
+
+
+ %s
+
+
+ %s
+ %i
+
+
+""" % (i, conn.depst().name, conn.depst().useId(), conn.arrst().name, conn.arrst().useId(), ddt, dtm, adt, atm, "%i:%i" % (hrs, mns), chg)
+
+ j = 0
+
+ for service in conn.services:
+ output += """
+ %s
+
+
+ %s
+ %s
+
+ %s
+
+""" % (j, service.name, service.depst.name, service.depst.useId(), datetime.datetime.strftime(service.deptime,"%d.%m.%Y"), datetime.datetime.strftime(service.deptime, "%H:%M"))
+
+ if service.currdep:
+ output += " %s\n" % service.currdep
+
+ if service.deppf:
+ output += " %s\n" % service.deppf
+
+ output += """
+
+
+ %s
+ %s
+
+ %s
+
+""" % (service.arrst.name, service.arrst.useId(), datetime.datetime.strftime(service.arrtime, "%d.%m.%Y"), datetime.datetime.strftime(service.arrtime, "%H:%M"))
+
+ if service.curarr:
+ output += " %s\n" % service.curarr
+
+ if service.arrpf:
+ output += " %s\n" % service.arrpf
+
+ output += """
+
+"""
+
+ j += 1
+
+ output += """
+
+"""
+
+ i += 1
+
+ output += """"""
+
+ return output