oebb_py/workers/conn.py
2017-09-23 16:57:24 +02:00

223 lines
7.2 KiB
Python

from bs4 import BeautifulSoup
import requests
import datetime
import pytz
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")
url = "http://fahrplan.oebb.at/bin/query.exe/dn?start=1&S=%s&Z=%s&REQ0JourneyDate=%s&time=%s&REQ0HafasNumCons0=%s%s" % (frm.extid if frm.extid else frm.name, to.extid if to.extid else to.name, outdate, outtime, count, "&timesel=arrive" if mode else "")
source = requests.get(url).text
if "GO_conViewMode=outward" not in source:
raise ValueError("No connection found.")
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")
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
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 = list(det.find("td", { "class": "date" }).strings)
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, json = False):
conns = connRequest(getStation(frm), getStation(to), count, time, mode, details)
i = 0
output = """<?xml version="1.0" encoding="UTF-8"?>
<connections>
"""
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 += """ <connection id='%i'>
<from>
<name>%s</name>
<id>%s</id>
</from>
<to>
<name>%s</name>
<id>%s</id>
</to>
<details>
<departure>
<date>%s</date>
<time>%s</time>
</departure>
<arrival>
<date>%s</date>
<time>%s</time>
</arrival>
<duration>%s</duration>
<changes>%i</changes>
</details>
<services>
""" % (i, conn.depst().name, conn.depst().useId(), conn.arrst().name, conn.arrst().useId(), ddt, dtm, adt, atm, "%i:%s" % (hrs, str(int(mns)).zfill(2)), chg)
j = 0
for service in conn.services:
output += """ <service id='%i'>
<name>%s</name>
<departure>
<station>
<name>%s</name>
<id>%s</id>
</station>
<date>%s</date>
<time>%s</time>
""" % (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 += " <current>%s</current>\n" % service.currdep
if service.deppf:
output += " <platform>%s</platform>\n" % service.deppf
output += """ </departure>
<arrival>
<station>
<name>%s</name>
<id>%s</id>
</station>
<date>%s</date>
<time>%s</time>
""" % (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 += " <current>%s</current>\n" % service.curarr
if service.arrpf:
output += " <platform>%s</platform>\n" % service.arrpf
output += """ </arrival>
</service>
"""
j += 1
output += """ </services>
</connection>
"""
i += 1
output += """</connections>"""
return output