private static List<GoogleRouteSchedule> ParseScheduleCSV(ZipArchiveEntry entry)
{
using (var reader = new StreamReader(entry.Open()))
{
// skip format line
reader.ReadLine();
var lines = ReadLines(reader).ToList();
var flatSchedule = lines.Select(line => line.Split(','))
.Where(line => !string.IsNullOrWhiteSpace(line[1]))
.Select(line => new
{
route = s_routePattern.Match(line[0]).Groups[1].Value,
stop = line[3],
order = line[4],
days = DaysOfWeekUtils.GetDaysOfWeek(line[0]),
time = ToTimeSpan(line[1].Replace("\"", string.Empty))
});
// Time to turn some totally flat data into totally structured data.
var routeDayStopSchedules = flatSchedule.GroupBy(line => new
{
route = line.route,
stop = line.stop,
// stops can appear more than once in a route (particularly at the very beginning and very end)
// we want to separate each section of the schedule in which the same stop appears.
order = line.order,
days = line.days
})
.Select(grouping => grouping.Aggregate(new List<TimeSpan>(),
(times, time) => { times.Add(time.time); return times; },
times => new
{
route = grouping.Key.route,
days = grouping.Key.days,
stopSchedules = new GoogleStopSchedule
{
Name = grouping.Key.stop,
Times = times.Distinct().OrderBy(time => time).ToList()
}
}));
var routeDaySchedules = routeDayStopSchedules
.GroupBy(line => new { route = line.route, days = line.days })
.Select(grouping => grouping.Aggregate(new
{
route = grouping.Key.route,
daySchedule = new GoogleDaySchedule
{
Days = grouping.Key.days,
StopSchedules = new List<GoogleStopSchedule>()
}
}, (result, line) => { result.daySchedule.StopSchedules.Add(line.stopSchedules); return result; }));
// the aristocrats!
IList<GoogleRouteSchedule> routeSchedules = routeDaySchedules
.GroupBy(line => line.route)
.Select(grouping => grouping.Aggregate(new GoogleRouteSchedule
{
RouteNo = grouping.Key,
Days = new List<GoogleDaySchedule>()
}, (result, line) => { result.Days.Add(line.daySchedule); return result; })).ToList();
if(!routeSchedules.Any(x => x.RouteNo == "C1R"))
{
routeSchedules.Add(GetC1RSchedule());
}
return routeSchedules.ToList();
}
}