예제 #1
0
        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));
        }
예제 #2
0
        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;
                }
            }
        }
예제 #3
0
        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();
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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];
            }
        }