/// <summary> /// Parses an API response from the STATION API /// </summary> /// <param name="response">API response to parse</param> /// <returns>IEnumerable of ParserStatements</returns> public static IEnumerable <ParserStatement> Parse(APIResponse response) { if (!response.RequestSucceded) { yield return(new ErrorStatement(response, ErrorTypes.RequestUnsuccessful)); yield break; } if (response.Result != null) { HtmlDocument document = new HtmlDocument(); document.LoadHtml(HttpUtility.HtmlDecode(response.Result.ToString())); var table = document.DocumentNode.Descendants("table").Where(d => d.HasClass("af")).FirstOrDefault(); if (table != null) { var stationName = table.Descendants("th").Where(d => d.HasClass("title")).FirstOrDefault().ChildNodes.FirstOrDefault().InnerText; var stationId = new StationIdStatement(response, stationName, null); yield return(stationId); foreach (HtmlNode tr in table.ChildNodes.Where(n => n.Name == "tr" && n.Attributes["onmouseover"] != null && n.Attributes["onmouseout"] != null)) { var tds = tr.ChildNodes.Where(n => n.Name == "td").ToArray(); var arrival = TimeTuple.Parse(tds[0]); var departure = TimeTuple.Parse(tds[1]); var trainReference = tds[tds.Length > 3 ? 3 : 2]; var trainRefStatements = ParseTrainReference(response, trainReference, stationId, arrival?.Scheduled, departure?.Scheduled).ToList(); foreach (var s in trainRefStatements) { yield return(s); } if (!(trainRefStatements.First() is TrainIdStatement trainId)) { yield break; } var trainStationId = new TrainStationStatement(response, trainId, stationId, arrival, departure); yield return(trainStationId); var platform = tds.Length > 3 ? tds[2].InnerText.Trim() : null; if (platform?.Length == 0) { platform = null; } yield return(new TrainStationPlatformStatement(response, trainStationId, platform)); } } else { yield return(new ErrorStatement(response, ErrorTypes.NoTable)); } } else { yield return(new ErrorStatement(response, ErrorTypes.NoResult)); } }
/// <summary> /// Processes the station rows in the HTML response /// </summary> /// <param name="response">API response</param> /// <param name="row">Station row tr</param> /// <param name="number">Number of the train station (ordinal)</param> /// <param name="id">Identifies the train</param> /// <param name="lastStation">Last station (to link sequential stations together)</param> /// <returns>Parser statements</returns> private static List <ParserStatement> ProcessStationTableRow(APIResponse response, HtmlNode row, TrainIdStatement id, ref StationIdStatement?lastStation) { List <ParserStatement> ret = new List <ParserStatement>(); var tds = row.ChildNodes.Where(n => n.Name == "td").ToArray(); var stationLink = tds[1].Descendants("a").FirstOrDefault(); var stationId = StationIdStatement.FromScript(response, stationLink?.Attributes["onclick"]?.Value); if (stationId != null) { ret.Add(stationId); } else { ret.Add(new ErrorStatement(response, ErrorTypes.StationLinkUnparsable)); ret.Add(stationId = new StationIdStatement(response, stationLink?.InnerText.Trim(), null)); } var hit = row.HasClass("row_past_odd") || row.HasClass("row_past_even"); var distance = CSExtensions.ParseInt(tds[0].InnerText); var arrival = TimeTuple.Parse(tds[2]); var departure = TimeTuple.Parse(tds[3]); var platform = (tds.Length > 4) ? tds[4].InnerText.Trim() : null; if (platform?.Length == 0) { platform = null; } var trainStationId = new TrainStationStatement(response, id, stationId, arrival, departure); ret.Add(trainStationId); if (lastStation != null) { ret.Add(new TrainStationLinkStatement(response, id, lastStation, stationId, true)); } lastStation = stationId; ret.Add(new TrainStationDistanceStatement(response, trainStationId, distance)); ret.Add(new TrainStationPlatformStatement(response, trainStationId, platform)); ret.Add(new TrainStationHitStatement(response, trainStationId, hit)); return(ret); }