Update to new SVV Backend

This commit is contained in:
Laura Hausmann 2020-03-21 20:58:31 +01:00
parent 05dd171e6b
commit 9aeece1664
Signed by: zotan
GPG Key ID: 5EC1D38FFC321311
10 changed files with 428 additions and 62 deletions

View File

@ -1,9 +0,0 @@
using dirkj.hafas.net;
namespace ZTravel.API.HAFAS {
public class HafasApi {
public void test() {
var provider = new HafasProvider(HafasEndpoints.DSB);
}
}
}

View File

@ -0,0 +1,276 @@
// <auto-generated />
//
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using ZTravel.API.HAFAS;
//
// var hafasDepartureRawResponse = HafasDepartureRawResponse.FromJson(jsonString);
namespace ZTravel.API.HAFAS
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using J = Newtonsoft.Json.JsonPropertyAttribute;
using R = Newtonsoft.Json.Required;
using N = Newtonsoft.Json.NullValueHandling;
public partial class HafasDepartureRawResponse
{
[J("ver")] public string Ver { get; set; }
[J("ext")] public string Ext { get; set; }
[J("lang")] public string Lang { get; set; }
[J("id")] public string Id { get; set; }
[J("err")] public string Err { get; set; }
[J("cInfo")] public CInfo CInfo { get; set; }
[J("svcResL")] public List<SvcResL> SvcResL { get; set; }
}
public partial class CInfo
{
[J("code")] public string Code { get; set; }
[J("url")] public string Url { get; set; }
[J("msg")] public string Msg { get; set; }
}
public partial class SvcResL
{
[J("meth")] public string Meth { get; set; }
[J("err")] public string Err { get; set; }
[J("res")] public Res Res { get; set; }
}
public partial class Res
{
[J("common")] public Common Common { get; set; }
[J("type")] public string Type { get; set; }
[J("jnyL")] public List<JnyL> JnyL { get; set; }
[J("fpB")] public string FpB { get; set; }
[J("fpE")] public string FpE { get; set; }
[J("planrtTS")] public string PlanrtTs { get; set; }
[J("sD")] public string SD { get; set; }
[J("sT")] public string ST { get; set; }
[J("locRefL")] public List<long> LocRefL { get; set; }
}
public partial class Common
{
[J("locL")] public List<LocL> LocL { get; set; }
[J("prodL")] public List<CommonProdL> ProdL { get; set; }
[J("polyL")] public List<object> PolyL { get; set; }
[J("layerL")] public List<LayerL> LayerL { get; set; }
[J("crdSysL")] public List<CrdSysL> CrdSysL { get; set; }
[J("opL")] public List<OpL> OpL { get; set; }
[J("remL")] public List<RemL> RemL { get; set; }
[J("txtInstL")] public List<object> TxtInstL { get; set; }
[J("icoL")] public List<IcoL> IcoL { get; set; }
}
public partial class CrdSysL
{
[J("id")] public string Id { get; set; }
[J("index")] public long Index { get; set; }
[J("type")] public string Type { get; set; }
}
public partial class IcoL
{
[J("res", NullValueHandling = N.Ignore)] public string Res { get; set; }
[J("txtS", NullValueHandling = N.Ignore)] public string TxtS { get; set; }
[J("fg", NullValueHandling = N.Ignore)] public Bg Fg { get; set; }
[J("bg", NullValueHandling = N.Ignore)] public Bg Bg { get; set; }
[J("txt", NullValueHandling = N.Ignore)] public string Txt { get; set; }
}
public partial class Bg
{
[J("r")] public long R { get; set; }
[J("g")] public long G { get; set; }
[J("b")] public long B { get; set; }
}
public partial class LayerL
{
[J("id")] public string Id { get; set; }
[J("name")] public string Name { get; set; }
[J("index")] public long Index { get; set; }
[J("annoCnt")] public long AnnoCnt { get; set; }
}
public partial class LocL
{
[J("lid")] public string Lid { get; set; }
[J("type")] public string Type { get; set; }
[J("name")] public string Name { get; set; }
[J("nameFormatted")] public NameFormatted NameFormatted { get; set; }
[J("icoX")] public long IcoX { get; set; }
[J("extId")] public string ExtId { get; set; }
[J("state")] public string State { get; set; }
[J("crd")] public Crd Crd { get; set; }
[J("pCls")] public long PCls { get; set; }
[J("pRefL", NullValueHandling = N.Ignore)] public List<long> PRefL { get; set; }
[J("entry", NullValueHandling = N.Ignore)] public bool? Entry { get; set; }
[J("mMastLocX", NullValueHandling = N.Ignore)] public long? MMastLocX { get; set; }
[J("meta", NullValueHandling = N.Ignore)] public bool? Meta { get; set; }
[J("isMainMast", NullValueHandling = N.Ignore)] public bool? IsMainMast { get; set; }
}
public partial class Crd
{
[J("x")] public long X { get; set; }
[J("y")] public long Y { get; set; }
[J("layerX")] public long LayerX { get; set; }
[J("crdSysX")] public long CrdSysX { get; set; }
}
public partial class NameFormatted
{
[J("text")] public string Text { get; set; }
[J("textInstructionIntervalL")] public List<object> TextInstructionIntervalL { get; set; }
}
public partial class OpL
{
[J("name")] public string Name { get; set; }
[J("icoX")] public long IcoX { get; set; }
[J("street")] public string Street { get; set; }
[J("id")] public string Id { get; set; }
}
public partial class CommonProdL
{
[J("pid", NullValueHandling = N.Ignore)] public string Pid { get; set; }
[J("name")] public string Name { get; set; }
[J("nameS")] public string NameS { get; set; }
[J("number", NullValueHandling = N.Ignore)] public string Number { get; set; }
[J("icoX")] public long IcoX { get; set; }
[J("cls")] public long Cls { get; set; }
[J("oprX", NullValueHandling = N.Ignore)] public long? OprX { get; set; }
[J("prodCtx")] public ProdCtx ProdCtx { get; set; }
[J("himIdL", NullValueHandling = N.Ignore)] public List<string> HimIdL { get; set; }
}
public partial class ProdCtx
{
[J("name")] public string Name { get; set; }
[J("num", NullValueHandling = N.Ignore)] public string Num { get; set; }
[J("line")] public string Line { get; set; }
[J("lineId")] public string LineId { get; set; }
[J("matchId", NullValueHandling = N.Ignore)] public string MatchId { get; set; }
[J("catOutS")] public string CatOutS { get; set; }
[J("catOutL")] public string CatOutL { get; set; }
[J("catIn", NullValueHandling = N.Ignore)] public string CatIn { get; set; }
[J("catCode", NullValueHandling = N.Ignore)] public string CatCode { get; set; }
[J("admin", NullValueHandling = N.Ignore)] public string Admin { get; set; }
[J("catOut", NullValueHandling = N.Ignore)] public string CatOut { get; set; }
}
public partial class RemL
{
[J("type")] public string Type { get; set; }
[J("code")] public string Code { get; set; }
[J("prio", NullValueHandling = N.Ignore)] public long? Prio { get; set; }
[J("icoX")] public long IcoX { get; set; }
[J("txtN")] public string TxtN { get; set; }
}
public partial class JnyL
{
[J("jid")] public string Jid { get; set; }
[J("date")] public string Date { get; set; }
[J("prodX")] public long ProdX { get; set; }
[J("dirTxt")] public string DirTxt { get; set; }
[J("dirFlg")] public string DirFlg { get; set; }
[J("status")] public string Status { get; set; }
[J("isRchbl")] public bool IsRchbl { get; set; }
[J("stbStop")] public StbStop StbStop { get; set; }
[J("stopL")] public List<StopL> StopL { get; set; }
[J("msgL")] public List<JnyLMsgL> MsgL { get; set; }
[J("subscr")] public string Subscr { get; set; }
[J("prodL")] public List<JnyLProdL> ProdL { get; set; }
}
public partial class JnyLMsgL
{
[J("type")] public string Type { get; set; }
[J("remX")] public long RemX { get; set; }
[J("fLocX")] public long FLocX { get; set; }
[J("tLocX")] public long TLocX { get; set; }
[J("tagL")] public List<string> TagL { get; set; }
}
public partial class JnyLProdL
{
[J("prodX")] public long ProdX { get; set; }
[J("fLocX")] public long FLocX { get; set; }
[J("tLocX")] public long TLocX { get; set; }
[J("fIdx")] public long FIdx { get; set; }
[J("tIdx")] public long TIdx { get; set; }
}
public partial class StbStop
{
[J("locX")] public long LocX { get; set; }
[J("idx")] public long Idx { get; set; }
[J("dProdX")] public long DProdX { get; set; }
[J("dPlatfS")] public string DPlatfS { get; set; }
[J("dInR")] public bool DInR { get; set; }
[J("dTimeS")] public string DTimeS { get; set; }
[J("dTimeR")] public string DTimeR { get; set; }
[J("dProgType")] public string DProgType { get; set; }
[J("type")] public string Type { get; set; }
}
public partial class StopL
{
[J("locX")] public long LocX { get; set; }
[J("idx")] public long Idx { get; set; }
[J("dPlatfS", NullValueHandling = N.Ignore)] public string DPlatfS { get; set; }
[J("dInR", NullValueHandling = N.Ignore)] public bool? DInR { get; set; }
[J("dTimeS", NullValueHandling = N.Ignore)] public string DTimeS { get; set; }
[J("dTimeR", NullValueHandling = N.Ignore)] public string DTimeR { get; set; }
[J("dProgType", NullValueHandling = N.Ignore)] public string DProgType { get; set; }
[J("type")] public string Type { get; set; }
[J("aOutR", NullValueHandling = N.Ignore)] public bool? AOutR { get; set; }
[J("aTimeS", NullValueHandling = N.Ignore)] public string ATimeS { get; set; }
[J("isImp", NullValueHandling = N.Ignore)] public bool? IsImp { get; set; }
[J("aOutS", NullValueHandling = N.Ignore)] public bool? AOutS { get; set; }
[J("aCncl", NullValueHandling = N.Ignore)] public bool? ACncl { get; set; }
[J("msgL", NullValueHandling = N.Ignore)] public List<StopLMsgL> MsgL { get; set; }
[J("aTimeSCh", NullValueHandling = N.Ignore)] public bool? ATimeSCh { get; set; }
}
public partial class StopLMsgL
{
[J("type")] public string Type { get; set; }
[J("remX")] public long RemX { get; set; }
[J("tagL")] public List<string> TagL { get; set; }
[J("persist")] public bool Persist { get; set; }
}
public partial class HafasDepartureRawResponse
{
public static HafasDepartureRawResponse FromJson(string json) => JsonConvert.DeserializeObject<HafasDepartureRawResponse>(json, ZTravel.API.HAFAS.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this HafasDepartureRawResponse self) => JsonConvert.SerializeObject(self, ZTravel.API.HAFAS.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}

View File

@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
namespace ZTravel.API.HAFAS {
public class HafasEndpoint {
private readonly string _endpoint;
private readonly string _client;
private readonly string _version;
private readonly string _auth;
private readonly string _lang;
public HafasEndpoint(string endpoint, string client, string version, string auth, string lang) {
_endpoint = endpoint;
_client = client;
_version = version;
_auth = auth;
_lang = lang;
}
public List<HafasDeparture> GetDepartures(string station, int count) {
var client = new WebClient();
var data =
$"{{\"ver\":\"{_version}\",\"lang\":\"{_lang}\",\"auth\":{_auth},\"client\":{_client},\"formatted\":false,\"ext\":\"VAO.11\",\"svcReqL\":[{{\"req\":{{\"stbLoc\":{{\"lid\":\"A=1@O={station}\"}},\"type\":\"DEP\",\"sort\":\"PT\",\"maxJny\":{count}}},\"meth\":\"StationBoard\"}}]}}";
var resp = client.UploadString(_endpoint, data);
var parsed = HafasDepartureRawResponse.FromJson(resp);
System.IO.File.WriteAllText("last_request.json", parsed.ToJson());
var departures = new List<HafasDeparture>();
var journeys = parsed.SvcResL[0].Res.JnyL;
var infos = parsed.SvcResL[0].Res.Common.ProdL;
foreach (var jny in parsed.SvcResL[0].Res.JnyL) {
if (departures.Any(p => p.Jid == jny.Jid))
continue;
var info = infos[(Index) jny.ProdX];
var planDep = DateTime.ParseExact($"{jny.Date} {jny.StbStop.DTimeS}", "yyyyMMdd HHmmss", CultureInfo.InvariantCulture);
DateTime realDep;
try {
realDep = DateTime.ParseExact($"{jny.Date} {jny.StbStop.DTimeR}", "yyyyMMdd HHmmss", CultureInfo.InvariantCulture);
}
catch {
realDep = planDep;
}
var dep = new HafasDeparture(info.Number, jny.DirTxt, jny.StbStop.DPlatfS, planDep, realDep, jny.Jid);
departures.Add(dep);
}
return departures;
}
}
public class HafasDeparture {
public readonly string Line;
public readonly string Destination;
public readonly string Platform;
public readonly DateTime PlannedDeparture;
public readonly DateTime RealDeparture;
public readonly string Jid;
public HafasDeparture(string line, string destination, string platform, DateTime plannedDeparture, DateTime realDeparture, string jid) {
Line = line;
Destination = destination;
Platform = platform;
PlannedDeparture = plannedDeparture;
RealDeparture = realDeparture;
Jid = jid;
}
}
public class Endpoints {
public static HafasEndpoint SvvEndpoint = new HafasEndpoint("https://fahrplan.salzburg-verkehr.at/bin/mgate.exe",
"{\"id\":\"VAO\",\"type\":\"WEB\",\"name\":\"webapp\",\"l\":\"vs_svv\"}", "1.20",
"{\"type\":\"AID\",\"aid\":\"wf7mcf9bv3nv8g5f\"}", "deu");
}
}

View File

@ -9,7 +9,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="dirkj.hafas.net" Version="1.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>

View File

@ -1,12 +1,15 @@
using System;
using ZTravel.API.DBF;
using System.Linq;
using ZTravel.API.HAFAS;
namespace ZTravel.CLI {
public class TestMain {
private static void Main(string[] args) {
var deps = DbfAjaxParser.GetDepartures("München Hbf");
foreach (var dep in deps) {
Console.WriteLine(dep.Line);
foreach (var dep in Endpoints.SvvEndpoint.GetDepartures("Salzburg Justizgebäude", 20).OrderBy(p => p.PlannedDeparture)) {
if (int.Parse(dep.Line) >= 20)
continue;
var delay = (dep.RealDeparture - dep.PlannedDeparture).TotalMinutes;
Console.WriteLine($"{dep.Platform} {dep.PlannedDeparture:HH:mm} ({(delay > 0 ? "+" : "")}{delay}) {dep.Line} {dep.Destination}");
}
}
}

View File

@ -1,5 +1,6 @@
@page
@using System.Globalization
@using ZTravel.API.HAFAS
@using ZTravel.API.VRRF
<!DOCTYPE html>
<html lang="en">
@ -20,31 +21,42 @@
</div>
<div class="app applight">
<ul>
@foreach (var dep in VrrfApi.GetDepartures("vrrf.finalrewind.org", "efa.SVV", "salzburg", "cebotari", platform: "2").Raw) {
var rawtime = DateTime.ParseExact($"{dep.SchedDate} {dep.Time}", "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
var countdownRaw = rawtime - DateTime.Now;
@foreach (var dep in Endpoints.SvvEndpoint.GetDepartures("Salzburg Maria-Cebotari-Straße", 20)
.OrderBy(p => p.RealDeparture)
.Where(p => p.Destination != "Parsch")) {
var countdownRaw = dep.RealDeparture - DateTime.Now;
var countdown = Math.Round(countdownRaw.TotalMinutes);
var time = countdown <= 60 ? $"{countdown} min" : dep.Time;
var time = dep.RealDeparture.ToString("HH:mm");
var displaytime = countdown <= 60 ? $"{countdown} min" : time;
var delay = (int)(dep.RealDeparture - dep.PlannedDeparture).TotalMinutes;
var abstime = time;
if (delay > 0) {
abstime += $" (+{delay})";
}
if (delay < 0) {
abstime += $" ({delay})";
}
if (countdown <= 0) {
time = "now";
displaytime = "now";
}
if (countdown <= -1) {
continue;
}
<li>
@if (int.Parse(dep.Line) < 14) {
@if (int.Parse(dep.Line) <= 14) {
<div class="line obus obus-line-@dep.Line">@dep.Line</div>
}
else {
<div class="line bus">@dep.Line</div>
}
<div class="dest">@dep.Destination</div>
<span class="route">@dep.Lineref.Route</span>
<span class="route">Salzburg AG - Obus Linie @dep.Line</span>
<span class="countdown">
<span class="platform">@time</span>
<span class="platform">@displaytime</span>
</span>
<span class="time">@dep.Time</span>
<span class="time">@abstime</span>
</li>
}
</ul>

View File

@ -1,5 +1,6 @@
@page
@using System.Globalization
@using ZTravel.API.HAFAS
@using ZTravel.API.VRRF
<!DOCTYPE html>
<html lang="en">
@ -27,34 +28,34 @@
-->
<div class="app appdark">
<ul>
@{
var counter = 0;
}
@foreach (var dep in VrrfApi.GetDepartures("vrrf.finalrewind.org", "efa.SVV", "salzburg", "maria-cebotari-straße", platform: "2").Raw) {
if (int.Parse(dep.Line) >= 20) {
@foreach (var dep in Endpoints.SvvEndpoint.GetDepartures("Salzburg Maria-Cebotari-Straße", 20).OrderBy(p => p.RealDeparture).Where(p => p.Destination != "Parsch")) {
if (int.Parse(dep.Line) > 14) {
continue;
}
counter++;
var rawtime = DateTime.ParseExact($"{dep.Date} {dep.Time}", "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
var countdownRaw = rawtime - DateTime.Now;
var countdownRaw = dep.RealDeparture - DateTime.Now;
var countdown = Math.Round(countdownRaw.TotalMinutes);
var time = countdown <= 60 ? $"{countdown} min" : dep.Time;
if (countdown <= 0) {
time = "now";
var time = dep.RealDeparture.ToString("HH:mm");
var displaytime = countdown <= 60 ? $"{countdown} min" : time;
var rawdelay = (int) (dep.RealDeparture - dep.PlannedDeparture).TotalMinutes;
var delay = "";
if (rawdelay < 0) {
delay = $"({rawdelay})";
}
if (countdown <= 5) {
if (rawdelay > 0) {
delay = $"(+{rawdelay})";
}
if (countdown <= 0) {
displaytime = "now";
}
if (countdown <= -1) {
continue;
}
<li>
@if (int.Parse(dep.Line) < 14) {
<div class="line obus">@dep.Line</div>
}
else {
<div class="line bus">@dep.Line</div>
}
<div class="dest">@dep.Destination</div>
<span class="countdown">
<span class="platform">@time</span>
<span class="platform">@delay @displaytime</span>
</span>
</li>
}

View File

@ -35,7 +35,10 @@
</div>
<div class="app applight">
<ul>
@foreach (var dep in DbfApi.GetDepartures("dbf.finalrewind.org", station, via)) {
@{
var deps = DbfApi.GetDepartures("dbf.finalrewind.org", station, via) ?? new List<Departure>();
}
@foreach (var dep in deps) {
if (fernverkehrOnly && !dep.TrainClasses.Contains("F") && dep.Destination != andShowDestination) {
continue;
}

View File

@ -1,5 +1,6 @@
@page
@using System.Globalization
@using ZTravel.API.HAFAS
@using ZTravel.API.VRRF
<!DOCTYPE html>
<html lang="en">
@ -22,34 +23,34 @@
-->
<div class="app appdark">
<ul>
@{
var counter = 0;
}
@foreach (var dep in VrrfApi.GetDepartures("vrrf.finalrewind.org", "efa.SVV", "salzburg", "justizgebäude").Raw) {
if (int.Parse(dep.Line) >= 20) {
@foreach (var dep in Endpoints.SvvEndpoint.GetDepartures("Salzburg Justizgebäude", 20).OrderBy(p => p.RealDeparture)) {
if (int.Parse(dep.Line) > 14) {
continue;
}
counter++;
var rawtime = DateTime.ParseExact($"{dep.Date} {dep.Time}", "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture);
var countdownRaw = rawtime - DateTime.Now;
var countdownRaw = dep.RealDeparture - DateTime.Now;
var countdown = Math.Round(countdownRaw.TotalMinutes);
var time = countdown <= 60 ? $"{countdown} min" : dep.Time;
if (countdown <= 0) {
time = "now";
var time = dep.RealDeparture.ToString("HH:mm");
var displaytime = countdown <= 60 ? $"{countdown} min" : time;
var rawdelay = (int) (dep.RealDeparture - dep.PlannedDeparture).TotalMinutes;
var delay = "";
if (rawdelay < 0) {
delay = $"({rawdelay})";
}
if (countdown <= 5) {
if (rawdelay > 0) {
delay = $"(+{rawdelay})";
}
if (countdown <= 0) {
displaytime = "now";
}
if (countdown <= -1) {
continue;
}
<li>
@if (int.Parse(dep.Line) < 14) {
<div class="line obus">@dep.Line</div>
}
else {
<div class="line bus">@dep.Line</div>
}
<div class="dest">@dep.Destination</div>
<span class="countdown">
<span class="platform">@time</span>
<span class="platform">@delay @displaytime</span>
</span>
</li>
}

File diff suppressed because one or more lines are too long