public IActionResult Get(string[] ids, [ModelBinder(Name = "include-stations")] bool includeStations) { List <TrainInstance> trainInstances = new List <TrainInstance>(); if (includeStations) { Database.Instance.StationMapper.BeginSelect(); Database.Instance.TrainStationMapper.BeginSelect(); Database.Instance.TrainInstanceStationMapper.ByTrainInstanceID.BeginSelect(); } Database.Instance.TraceMapper.ByTrainInstanceID.BeginSelect(); Database.Instance.TrainMapper.BeginSelect(); Database.Instance.TrainInstanceMapper.BeginSelect(); foreach (var id in ids) { if (!TrainInstance.TryGetInstanceID(id, out long lid)) { trainInstances.Add(new TrainInstance() { Filled = false }); } else { trainInstances.Add(Database.Instance.TrainInstanceMapper.GetByKey(lid)); } } Database.Instance.TrainInstanceMapper.EndSelect(); Database.Instance.TrainMapper.EndSelect(); Database.Instance.TraceMapper.ByTrainInstanceID.EndSelect(); if (includeStations) { Database.Instance.TrainInstanceStationMapper.ByTrainInstanceID.EndSelect(); Database.Instance.TrainStationMapper.EndSelect(); Database.Instance.StationMapper.EndSelect(); } JObject dictionary = new JObject(); for (int i = 0; i < ids.Length; i++) { dictionary[ids[i]] = trainInstances[i].Filled ? trainInstances[i].ToJObject() : null; } return(Success(dictionary)); }
private void HandleTrainHeader(HtmlNode topHeader, ref Train train, TrainInstance trainInstance) { using (IEnumerator <HtmlNode> header = topHeader.ChildNodes.AsEnumerable().GetEnumerator()) { if (!header.MoveNext()) { throw new MAVParseException("No train header."); } string[] nameType = header.Current.InnerText.Split(new char[] { ' ', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (nameType.Length < 1) { throw new MAVParseException("Train header is not in the correct format."); } if (!int.TryParse(nameType.First(), out int number)) { throw new MAVParseException("Train header does not contain a number."); } train = train ?? DbContext.Trains.Where(t => t.Number == number).Include(t => t.TrainStations).FirstOrDefault() ?? new Train() { Number = number }; if (trainInstance?.Id == 0) { trainInstance.Train = train; } train.Type = nameType.Length > 1 ? nameType.Last() : null; train.Name = nameType.Length > 2 ? string.Join(" ", nameType.Skip(1).SkipLast(1)) : null; header.MoveNext(); if (header.Current.Name == "ul") { train.Type = FigureOutTypeUl(header.Current); header.MoveNext(); } if (header.Current.HasClass("viszszam2")) { train.Name = header.Current.InnerText; } } }
public void Handle() { TrainInstance trainInstance = elviraId != null ? DbContext.TrainInstances.Where(t => t.ElviraId == elviraId).Include(t => t.TrainInstanceStations).FirstOrDefault() ?? new TrainInstance() { ElviraId = elviraId } : null; Train train = trainInstance?.Train; var table = html.DocumentNode.Descendants("table").FirstOrDefault(tb => tb.HasClass("vt")); if (table == null) { throw new MAVParseException("No train table."); } HtmlNode headerTr = table.Descendants("tr").FirstOrDefault(); if (headerTr == null) { throw new MAVParseException("No train table."); } IEnumerable <HtmlNode> ths = headerTr.Descendants("th"); var topHeader = ths.FirstOrDefault(); if (topHeader == null) { throw new MAVParseException("No train header."); } HandleTrainHeader(topHeader, ref train, trainInstance); if (!train.IsValid) { IList <List <HtmlNode> > rows = table.Descendants("tr").Where(tr => !tr.Descendants("th").Any() && tr.Attributes.Contains("onmouseover")) .Select(tr => tr.Descendants("td").ToList()).ToList(); HandleStationsRecreate(rows, train, trainInstance); HandleExpiryDate(train); train.Polyline = polyline; if (trainInstance != null) { DbContext.Update(trainInstance); } DbContext.Update(train); } else if (trainInstance?.Id == 0) { IList <List <HtmlNode> > rows = table.Descendants("tr").Where(tr => !tr.Descendants("th").Any() && tr.Attributes.Contains("onmouseover")) .Select(tr => tr.Descendants("td").ToList()).ToList(); HandleStationsFromExisting(rows, train, trainInstance); DbContext.Update(trainInstance); } DbContext.SaveChanges(); DbContext.Dispose(); }
private void HandleStationsFromExisting(IList <List <HtmlNode> > rows, Train train, TrainInstance trainInstance) { if (trainInstance.Id != 0) { trainInstance?.TrainInstanceStations.Clear(); } DbContext.Entry(train).Collection(t => t.TrainStations).Query().Include(st => st.Station).Load(); Dictionary <string, TrainStation> trainStations = train.TrainStations.ToDictionary(st => st.Station.NormName, st => st); foreach (IList <HtmlNode> row in rows) { var(_, actualArrival) = Parsing.GetCellTimes(row[2]); var(_, actualDeparture) = Parsing.GetCellTimes(row[3]); var trainInstanceStation = new TrainInstanceStation { TrainInstance = trainInstance, TrainStation = trainStations[Station.NormalizeName(row[1].InnerText.Trim())], ActualArrival = actualArrival, ActualDeparture = actualDeparture }; trainInstance.TrainInstanceStations.Add(trainInstanceStation); } }
private void HandleStationsRecreate(IList <List <HtmlNode> > rows, Train train, TrainInstance trainInstance) { List <string> stationNames = new List <string>(); train.TrainStations.Clear(); trainInstance?.TrainInstanceStations.Clear(); foreach (IList <HtmlNode> row in rows) { string stationName = row[1].InnerText.Trim(); string normName = Station.NormalizeName(stationName); stationNames.Add(normName); var(arrival, actualArrival) = Parsing.GetCellTimes(row[2]); var(departure, actualDeparture) = Parsing.GetCellTimes(row[3]); var platform = row.Count == 5 ? row[4].InnerText.Trim() : null; var trainStation = new TrainStation { Train = train, Ordinal = train.TrainStations.Count, Station = new Station() { Name = stationName, NormName = normName }, Arrival = arrival, Departure = departure, Platform = string.IsNullOrEmpty(platform) ? null : platform }; train.TrainStations.Add(trainStation); if (trainInstance != null) { var trainInstanceStation = new TrainInstanceStation { TrainInstance = trainInstance, TrainStation = trainStation, ActualArrival = actualArrival, ActualDeparture = actualDeparture }; trainInstance.TrainInstanceStations.Add(trainInstanceStation); } } IDictionary <string, Station> stations = DbContext.Stations.Where(s => stationNames.Contains(s.NormName)).ToDictionary(s => s.NormName, s => s); foreach (TrainStation trainStation in train.TrainStations) { trainStation.Station = stations[trainStation.Station.NormName]; } var relativeDistances = GetRelativeDistances(train.TrainStations.Select(s => s.Station).ToList()); for (int i = 0; i < train.TrainStations.Count; i++) { train.TrainStations[i].RelativeDistance = relativeDistances[i]; } }