From a304c24b32c0327436bbd8c2853e60668e161b42 Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero Date: Mon, 29 Dec 2025 00:41:52 +0100 Subject: Rename a lot of stuff, add Santiago real time --- src/Costasdev.Busurbano.ServiceViewer/.gitignore | 264 ---------- .../AppDbContextDesignTimeFactory.cs | 41 -- .../Controllers/ServicesController.cs | 358 -------------- .../Controllers/StylesheetController.cs | 39 -- .../Costasdev.Busurbano.ServiceViewer.csproj | 17 - .../Data/AppDbContext.cs | 59 --- .../Data/Extensions/TimeExtensions.cs | 20 - .../Data/Gtfs/Enums/DirectionId.cs | 7 - .../Data/Gtfs/Enums/ExceptionType.cs | 7 - .../Data/Gtfs/Enums/RouteType.cs | 15 - .../Data/Gtfs/Enums/TripBikesAllowed.cs | 8 - .../Data/Gtfs/Enums/TripWheelchairAccessible.cs | 8 - .../Data/Gtfs/Enums/WheelchairBoarding.cs | 8 - .../Data/Gtfs/Feed.cs | 21 - .../Data/Gtfs/GtfsAgency.cs | 46 -- .../Data/Gtfs/GtfsCalendar.cs | 45 -- .../Data/Gtfs/GtfsCalendarDate.cs | 24 - .../Data/Gtfs/GtfsRoute.cs | 70 --- .../Data/Gtfs/GtfsStop.cs | 51 -- .../Data/Gtfs/GtfsStopTime.cs | 44 -- .../Data/Gtfs/GtfsTrip.cs | 57 --- .../Migrations/20251211153852_Initial.Designer.cs | 547 --------------------- .../Data/Migrations/20251211153852_Initial.cs | 318 ------------ .../Data/Migrations/AppDbContextModelSnapshot.cs | 544 -------------------- .../QueryExtensions/GtfsCalendarQueryExtensions.cs | 21 - src/Costasdev.Busurbano.ServiceViewer/Program.cs | 35 -- .../Properties/launchSettings.json | 14 - .../Views/Services/DaysInFeed.cshtml | 22 - .../Views/Services/DaysInFeed.cshtml.cs | 7 - .../Views/Services/ServiceDetails.cshtml | 63 --- .../Views/Services/ServiceDetails.cshtml.cs | 29 -- .../Views/Services/ServicesInDay.cshtml | 40 -- .../Views/Services/ServicesInDay.cshtml.cs | 39 -- .../Views/Shared/_Layout.cshtml | 22 - .../Views/_ViewImports.cshtml | 2 - .../Views/_ViewStart.cshtml | 3 - .../appsettings.json | 9 - .../wwwroot/styles/common.css | 23 - .../wwwroot/styles/days_in_feed.css | 28 -- .../wwwroot/styles/service_details.css | 146 ------ .../wwwroot/styles/services_in_day.css | 70 --- 41 files changed, 3191 deletions(-) delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/.gitignore delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Controllers/StylesheetController.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/DirectionId.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/ExceptionType.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/RouteType.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripBikesAllowed.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripWheelchairAccessible.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/WheelchairBoarding.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Data/QueryExtensions/GtfsCalendarQueryExtensions.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Program.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Properties/launchSettings.json delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml.cs delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/Shared/_Layout.cshtml delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/_ViewImports.cshtml delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/Views/_ViewStart.cshtml delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/appsettings.json delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/common.css delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/days_in_feed.css delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/service_details.css delete mode 100644 src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/services_in_day.css (limited to 'src/Costasdev.Busurbano.ServiceViewer') diff --git a/src/Costasdev.Busurbano.ServiceViewer/.gitignore b/src/Costasdev.Busurbano.ServiceViewer/.gitignore deleted file mode 100644 index ff5b00c..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/.gitignore +++ /dev/null @@ -1,264 +0,0 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# Azure Functions localsettings file -local.settings.json - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ - -# Visual Studio 2015 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -project.fragment.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -#*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config -# NuGet v3's project.json files produces more ignoreable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# JetBrains Rider -.idea/ -*.sln.iml - -# CodeRush -.cr/ - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc \ No newline at end of file diff --git a/src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs b/src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs deleted file mode 100644 index 919c131..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/AppDbContextDesignTimeFactory.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Costasdev.ServiceViewer.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; - -namespace Costasdev.ServiceViewer; - -public class AppDbContextDesignTimeFactory : IDesignTimeDbContextFactory -{ - public AppDbContext CreateDbContext(string[] args) - { - IConfigurationRoot configuration = new ConfigurationBuilder() - .AddJsonFile("appsettings.json", optional: true) - .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", - optional: true) - .AddUserSecrets(typeof(AppDbContext).Assembly, optional: true) - .AddEnvironmentVariables() - .Build(); - - var builder = new DbContextOptionsBuilder(); - var connectionString = configuration.GetConnectionString("Database"); - if (string.IsNullOrEmpty(connectionString)) - { - throw new InvalidOperationException("Connection string 'Database' not found."); - } - - var loggerFactory = LoggerFactory.Create(lb => - { - lb - .AddConsole() - .SetMinimumLevel(LogLevel.Information); - }); - builder.UseLoggerFactory(loggerFactory); - - builder.UseNpgsql( - connectionString, - options => options.UseNetTopologySuite() - ); - - return new AppDbContext(builder.Options); - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs b/src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs deleted file mode 100644 index bfb2a99..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Controllers/ServicesController.cs +++ /dev/null @@ -1,358 +0,0 @@ -using Costasdev.ServiceViewer.Data; -using Costasdev.ServiceViewer.Data.Gtfs; -using Costasdev.ServiceViewer.Data.Gtfs.Enums; -using Costasdev.ServiceViewer.Data.QueryExtensions; -using Costasdev.ServiceViewer.Views.Services; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Controllers; - -[Route("")] -public class ServicesController : Controller -{ - private readonly AppDbContext _db; - - public ServicesController(AppDbContext db) - { - _db = db; - } - - [HttpGet("")] - public async Task DaysInFeed() - { - // FIXME: Use calendar too, but it requires getting the feed information - var days = await _db.CalendarDates - .Where(cd => cd.ExceptionType == ExceptionType.Added) - .Select(cd => cd.Date) - .Distinct() - .OrderBy(d => d) - .ToListAsync(); - - var model = new DaysInFeedModel - { - Days = days, - Today = DateOnly.FromDateTime(DateTime.Now), - }; - - return View(model); - } - - [HttpGet("{day}")] - public IActionResult ServicesInDay( - [FromRoute] string day - ) - { - var dateParsed = DateOnly.TryParseExact(day, "yyyy-MM-dd", out var dateOnly); - if (!dateParsed) - { - return BadRequest("Invalid date format. Please use 'yyyy-MM-dd'."); - } - - var dateTime = dateOnly.ToDateTime(TimeOnly.MinValue); - - // 1. Get all the calendars running that day - var dayOfWeek = dateOnly.DayOfWeek; - - var calendars = _db.Calendars - .WhereDayOfWeek(dayOfWeek) - .ToList(); - - var calendarDates = _db.CalendarDates - .Where(cd => cd.Date.Date == dateTime.Date) - .ToList(); - - // 2. Combine the two lists - HashSet activeServiceIds = []; - foreach (var calendar in calendars) - { - if (calendarDates.All(cd => - cd.ServiceId != calendar.ServiceId || cd.ExceptionType != ExceptionType.Removed)) - { - activeServiceIds.Add(calendar.ServiceId); - } - } - - foreach (var calendarDate in calendarDates.Where(cd => cd.ExceptionType == ExceptionType.Added)) - { - activeServiceIds.Add(calendarDate.ServiceId); - } - - // 3. Get the trips for those services - var tripsByService = _db.Trips - .AsSplitQuery() - .Include(t => t.Route) - .Where(t => activeServiceIds.Contains(t.ServiceId)) - .GroupBy(t => t.ServiceId) - .ToDictionary(g => g.Key, g => g.ToList()); - - /* - * For each shift, we extract the trip sequence number from the trip_id, order them ascending and take first - * one's first stop_time departure_time as shift start time and last one's last stop_time arrival_time as shift end time - * FIXME: Heuristic only for Vitrasa, not other feeds - * A 01LP001_008001_2, A 01LP001_008001_3, A 01LP001_008001_4, A 01LP001_008001_5... - */ - List serviceInformations = []; - List tripsWhoseFirstStopWeWant = []; - List tripsWhoseLastStopWeWant = []; - foreach (var (service, trips) in tripsByService) - { - var orderedTrips = trips - .Select(t => new - { - Trip = t, - Sequence = int.TryParse(t.Id.Split('_').LastOrDefault(), out var seq) ? seq : int.MaxValue - }) - .OrderBy(t => t.Sequence) - .ThenBy(t => t.Trip.TripHeadsign) // Secondary sort to ensure consistent ordering - .Select(t => t.Trip) - .ToList(); - - if (orderedTrips.Count == 0) - { - continue; - } - - tripsWhoseFirstStopWeWant.Add(orderedTrips.First().Id); - tripsWhoseLastStopWeWant.Add(orderedTrips.Last().Id); - serviceInformations.Add(new ServiceInformation( - service, - GetNameForServiceId(service), - orderedTrips, - orderedTrips.First(), - orderedTrips.Last() - )); - } - - var firstStopTimePerTrip = _db.StopTimes - .AsSplitQuery().AsNoTracking() - .Where(st => tripsWhoseFirstStopWeWant.Contains(st.TripId)) - .OrderBy(st => st.StopSequence) - .GroupBy(st => st.TripId) - .Select(g => g.First()) - .ToDictionary(st => st.TripId, st => st.Departure); - - var lastStopTimePerTrip = _db.StopTimes - .AsSplitQuery().AsNoTracking() - .Where(st => tripsWhoseLastStopWeWant.Contains(st.TripId)) - .OrderByDescending(st => st.StopSequence) - .GroupBy(st => st.TripId) - .Select(g => g.First()) - .ToDictionary(st => st.TripId, st => st.Arrival); - - // 4. Create a view model - List serviceCards = []; - foreach (var serviceInfo in serviceInformations) - { - // For lines 16-24 switching during the day we want (16, 2), (24,2), (16,1), (24,2)... in sequence - // TODO: Fix getting the trip sequence for any operator - var tripsOrdered = serviceInfo.Trips - .OrderBy(t => int.Parse(t.Id.Split('_').LastOrDefault() ?? string.Empty)) - .ToList(); - - List tripGroups = []; - GtfsRoute currentRoute = tripsOrdered.First().Route; - int currentRouteCount = 1; - foreach (var trip in tripsOrdered.Skip(1)) - { - if (trip.Route.Id == currentRoute.Id) - { - currentRouteCount++; - } - else - { - tripGroups.Add(new TripGroup(currentRoute, currentRouteCount)); - currentRoute = trip.Route; - currentRouteCount = 1; - } - } - - tripGroups.Add(new TripGroup(currentRoute, currentRouteCount)); - - serviceCards.Add(new ServicesInDayItem( - serviceInfo.ServiceId, - serviceInfo.ServiceName, - serviceInfo.Trips, - tripGroups, - firstStopTimePerTrip.TryGetValue(serviceInfo.FirstTrip.Id, out var shiftStart) - ? shiftStart - : string.Empty, - lastStopTimePerTrip.TryGetValue(serviceInfo.LastTrip.Id, out var shiftEnd) ? shiftEnd : string.Empty - )); - } - - return View(new ServiceInDayModel - { - Items = serviceCards, - Date = dateOnly - }); - } - - [HttpGet("{day}/{serviceId}")] - public IActionResult ServiceDetails( - [FromRoute] string day, - [FromRoute] string serviceId - ) - { - #region Validation - - var dateParsed = DateOnly.TryParseExact(day, "yyyy-MM-dd", out var dateOnly); - if (!dateParsed) - { - return BadRequest("Invalid date format. Please use 'yyyy-MM-dd'."); - } - - var dateTime = dateOnly.ToDateTime(TimeOnly.MinValue); - - // 1. Get all the calendars running that day - var dayOfWeek = dateOnly.DayOfWeek; - - var calendars = _db.Calendars - .WhereDayOfWeek(dayOfWeek) - .ToList(); - - var calendarDates = _db.CalendarDates - .Where(cd => cd.Date.Date == dateTime.Date) - .ToList(); - - // 2. Combine the two lists - HashSet activeServiceIds = []; - foreach (var calendar in calendars) - { - if (calendarDates.All(cd => - cd.ServiceId != calendar.ServiceId || cd.ExceptionType != ExceptionType.Removed)) - { - activeServiceIds.Add(calendar.ServiceId); - } - } - - foreach (var calendarDate in calendarDates.Where(cd => cd.ExceptionType == ExceptionType.Added)) - { - activeServiceIds.Add(calendarDate.ServiceId); - } - - if (!activeServiceIds.Contains(serviceId)) - { - return NotFound("Service not found for the given day."); - } - - #endregion - - var trips = _db.Trips - .AsSplitQuery() - .Include(t => t.Route) - .Where(t => t.ServiceId == serviceId) - .ToList(); - - var orderedTrips = trips - .Select(t => new - { - Trip = t, - Sequence = int.TryParse(t.Id.Split('_').LastOrDefault(), out var seq) ? seq : int.MaxValue - }) - .OrderBy(t => t.Sequence) - .ThenBy(t => t.Trip.TripHeadsign) // Secondary sort to ensure consistent ordering - .Select(t => t.Trip) - .ToList(); - - List items = []; - int totalDistance = 0; - TimeSpan totalDrivingMinutes = TimeSpan.Zero; - foreach (var trip in orderedTrips) - { - var stopTimes = _db.StopTimes - .AsSplitQuery().AsNoTracking() - .Include(gtfsStopTime => gtfsStopTime.GtfsStop) - .Where(st => st.TripId == trip.Id) - .OrderBy(st => st.StopSequence) - .ToList(); - - if (stopTimes.Count == 0) - { - continue; - } - - var firstStop = stopTimes.First(); - var lastStop = stopTimes.Last(); - - var tripDistance = (int?)(lastStop.ShapeDistTraveled - firstStop.ShapeDistTraveled); - totalDistance += tripDistance ?? 0; - totalDrivingMinutes += (lastStop.ArrivalTime - firstStop.DepartureTime); - - items.Add(new ServiceDetailsItem - { - TripId = trip.Id, - SafeRouteId = trip.Route.SafeId, - ShortName = trip.Route.ShortName, - LongName = trip.TripHeadsign ?? trip.Route.LongName, - TotalDistance = tripDistance.HasValue ? $"{tripDistance.Value/1_000:F2} km" : "N/A", - FirstStopName = firstStop.GtfsStop.Name, - FirstStopTime = firstStop.Departure, - LastStopName = lastStop.GtfsStop.Name, - LastStopTime = lastStop.Arrival - }); - } - - return View(new ServiceDetailsModel - { - Date = dateOnly, - ServiceId = serviceId, - ServiceName = GetNameForServiceId(serviceId), - TotalDrivingTime = totalDrivingMinutes, - TotalDistance = totalDistance, - Items = items - }); - } - - private string GetNameForServiceId(string serviceId) - { - var serviceIndicator = serviceId[^6..]; // "008001" or "202006" - if (string.IsNullOrEmpty(serviceIndicator)) - { - return serviceId; - } - - var lineNumber = int.Parse(serviceIndicator[..3]); // "008" - var shiftNumber = int.Parse(serviceIndicator[3..]); // "001" - var lineName = lineNumber switch - { - 1 => "C1", - 3 => "C3", - 30 => "N1", - 33 => "N4", - 8 => "A", - 101 => "H", - 201 => "U1", - 202 => "U2", - 150 => "REF", - 500 => "TUR", - _ => $"L{lineNumber}" - }; - - return $"Servicio {lineName}-{shiftNumber}º ({serviceId[^6..]})"; - } -} - -internal class ServiceInformation -{ - internal string ServiceId { get; } - public string ServiceName { get; set; } - internal List Trips { get; } - internal GtfsTrip FirstTrip { get; } - internal GtfsTrip LastTrip { get; } - - internal ServiceInformation( - string serviceId, - string serviceName, - List trips, - GtfsTrip firstTrip, - GtfsTrip lastTrip - ) - { - ServiceId = serviceId; - ServiceName = serviceName; - Trips = trips; - FirstTrip = firstTrip; - LastTrip = lastTrip; - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Controllers/StylesheetController.cs b/src/Costasdev.Busurbano.ServiceViewer/Controllers/StylesheetController.cs deleted file mode 100644 index 00654db..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Controllers/StylesheetController.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Text; -using Costasdev.ServiceViewer.Data; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Controllers; - -[Controller] -[Route("")] -public class StylesheetController : Controller -{ - private readonly AppDbContext _db; - public StylesheetController(AppDbContext db) - { - _db = db; - } - - [HttpGet("stylesheets/routecolours.css")] - public IActionResult GetRouteColoursSheet() - { - var routeColours = _db.Routes - .Select(r => new { Id = r.SafeId, r.Color, r.TextColor }) - .ToListAsync(); - - StringBuilder sb = new(); - foreach (var route in routeColours.Result) - { - sb.Append($".route-{route.Id} {{"); - sb.Append($"--route-color: #{route.Color};"); - sb.Append($"--route-text: #{route.TextColor};"); - sb.Append($"--route-color-semi: #{route.Color}4d;"); - sb.Append($"--route-text-semi: #{route.TextColor}4d;"); - sb.Append('}'); - } - sb.Append('}'); - - return Content(sb.ToString(), "text/css", Encoding.UTF8); - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj b/src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj deleted file mode 100644 index 426621c..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Costasdev.Busurbano.ServiceViewer.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net10.0 - enable - enable - Costasdev.ServiceViewer - 17600c95-53dd-43b7-9116-24ed4d24eae0 - - - - - - - - - diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs deleted file mode 100644 index 50f0791..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/AppDbContext.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Costasdev.ServiceViewer.Data.Gtfs; -using Costasdev.ServiceViewer.Data.Gtfs.Enums; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Data; - -public class AppDbContext : DbContext -{ - public AppDbContext(DbContextOptions options) : base(options) - { - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - // Route -> Agency - modelBuilder.Entity() - .HasOne(r => r.Agency) - .WithMany() - .HasForeignKey(r => new { r.AgencyId, r.FeedId }) - .HasPrincipalKey(a => new { a.Id, a.FeedId }); - - // Trip -> Route - modelBuilder.Entity() - .HasOne(t => t.Route) - .WithMany() - .HasForeignKey(t => new { t.RouteId, t.FeedId }) - .HasPrincipalKey(a => new { a.Id, a.FeedId }); - - // Relación StopTimes -> Trip - modelBuilder.Entity() - .HasOne(st => st.GtfsTrip) - .WithMany() - .HasForeignKey(st => new { st.TripId, st.FeedId }) - .HasPrincipalKey(a => new { a.Id, a.FeedId }); - - // Relación StopTimes -> Stop - modelBuilder.Entity() - .HasOne(st => st.GtfsStop) - .WithMany() - .HasForeignKey(st => new { st.StopId, st.FeedId }) - .HasPrincipalKey(a => new { a.Id, a.FeedId }); - - modelBuilder.Entity() - .Property(t => t.TripWheelchairAccessible) - .HasDefaultValue(TripWheelchairAccessible.Empty); - - modelBuilder.Entity() - .Property(t => t.TripBikesAllowed) - .HasDefaultValue(TripBikesAllowed.Empty); - } - - public DbSet Agencies { get; set; } - public DbSet Calendars { get; set; } - public DbSet CalendarDates { get; set; } - public DbSet Routes { get; set; } - public DbSet Stops { get; set; } - public DbSet StopTimes { get; set; } - public DbSet Trips { get; set; } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs deleted file mode 100644 index 7fa487d..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Extensions/TimeExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace Costasdev.ServiceViewer.Data.Extensions; - -public static class TimeExtensions -{ - extension(TimeSpan) { - public static TimeSpan FromGtfsTime(string gtfsTime) - { - var parts = gtfsTime.Split(":", 3); - - var hours = int.Parse(parts[0]); - var minutes = int.Parse(parts[1]); - var seconds = int.Parse(parts[2]); - - int days = hours / 24; - int leftoverHours = hours % 24; - - return new TimeSpan(days, leftoverHours, minutes, seconds); - } - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/DirectionId.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/DirectionId.cs deleted file mode 100644 index cbcf80b..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/DirectionId.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Costasdev.ServiceViewer.Data.Gtfs.Enums; - -public enum DirectionId -{ - Outbound = 0, - Inbound = 1 -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/ExceptionType.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/ExceptionType.cs deleted file mode 100644 index 0ad0345..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/ExceptionType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Costasdev.ServiceViewer.Data.Gtfs.Enums; - -public enum ExceptionType -{ - Added = 1, - Removed = 2 -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/RouteType.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/RouteType.cs deleted file mode 100644 index e19d02a..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/RouteType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Costasdev.ServiceViewer.Data.Gtfs.Enums; - -public enum RouteType -{ - Tram = 0, - Subway = 1, - Rail = 2, - Bus = 3, - Ferry = 4, - CableTram = 5, - AerialLift = 6, - Funicular = 7, - Trolleybus = 11, - Monorail = 12 -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripBikesAllowed.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripBikesAllowed.cs deleted file mode 100644 index 838bc81..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripBikesAllowed.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Costasdev.ServiceViewer.Data.Gtfs.Enums; - -public enum TripBikesAllowed -{ - Empty = 0, - CanAccommodate = 1, - NotAllowed = 2 -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripWheelchairAccessible.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripWheelchairAccessible.cs deleted file mode 100644 index e84b699..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/TripWheelchairAccessible.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Costasdev.ServiceViewer.Data.Gtfs.Enums; - -public enum TripWheelchairAccessible -{ - Empty = 0, - CanAccommodate = 1, - NotAccessible = 2 -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/WheelchairBoarding.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/WheelchairBoarding.cs deleted file mode 100644 index 3cc550f..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Enums/WheelchairBoarding.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Costasdev.ServiceViewer.Data.Gtfs.Enums; - -public enum WheelchairBoarding -{ - Unknown = 0, - SomeVehicles = 1, - NotPossible = 2 -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs deleted file mode 100644 index 065250b..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/Feed.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("feeds")] -public class Feed -{ - /// - /// Auto-incrementing ID value for each feed, to identify it and its version - /// - [Key] - public int Id { get; set; } - - [MaxLength(32)] public string ShortName { get; set; } - [MaxLength(32)] public string LongName { get; set; } - [MaxLength(255)] public string DownloadUrl { get; set; } - [MaxLength(32)] public string Etag { get; set; } - - public DateTime InsertedAt { get; set; } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs deleted file mode 100644 index 89b5518..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsAgency.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("gtfs_agencies")] -[PrimaryKey(nameof(Id), nameof(FeedId))] -public class GtfsAgency -{ - [Key] - [Column("agency_id")] - [MaxLength(255)] - public required string Id { get; set; } - - [Column("feed_id")] public int FeedId { get; set; } - [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } - - [Column("agency_name")] - [MaxLength(255)] - public string Name { get; set; } = string.Empty; - - [Column("agency_url")] - [MaxLength(255)] - public string Url { get; set; } = string.Empty; - - [Column("agency_timezone")] - [MaxLength(50)] - public string Timezone { get; set; } = string.Empty; - - [Column("agency_lang")] - [MaxLength(5)] - public string Language { get; set; } = string.Empty; - - [Column("agency_phone")] - [MaxLength(30)] - public string? Phone { get; set; } = string.Empty; - - [Column("agency_email")] - [MaxLength(255)] - public string? Email { get; set; } = string.Empty; - - [Column("agency_fare_url")] - [MaxLength(255)] - public string? FareUrl { get; set; } = string.Empty; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs deleted file mode 100644 index cfb144c..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendar.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("gtfs_calendar")] -[PrimaryKey(nameof(ServiceId), nameof(FeedId))] -public class GtfsCalendar -{ - [Key] - [Column("service_id")] - [MaxLength(32)] - public string ServiceId { get; set; } = null!; - - [Column("feed_id")] public int FeedId { get; set; } - [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } - - [Column("monday")] - public bool Monday { get; set; } - - [Column("tuesday")] - public bool Tuesday { get; set; } - - [Column("wednesday")] - public bool Wednesday { get; set; } - - [Column("thursday")] - public bool Thursday { get; set; } - - [Column("friday")] - public bool Friday { get; set; } - - [Column("saturday")] - public bool Saturday { get; set; } - - [Column("sunday")] - public bool Sunday { get; set; } - - [Column("start_date")] - public DateOnly StartDate { get; set; } - - [Column("end_date")] - public DateOnly EndDate { get; set; } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs deleted file mode 100644 index 1543ef5..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsCalendarDate.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Costasdev.ServiceViewer.Data.Gtfs.Enums; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("gtfs_calendar_dates")] -[PrimaryKey(nameof(ServiceId), nameof(Date), nameof(FeedId))] -public class GtfsCalendarDate -{ - [Column("service_id")] - [MaxLength(32)] - public required string ServiceId { get; set; } - - [Column("date")] - public required DateTime Date { get; set; } - - [Column("feed_id")] public int FeedId { get; set; } - [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } - - [Column("exception_type")] - public required ExceptionType ExceptionType { get; set; } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs deleted file mode 100644 index c34353c..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsRoute.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Costasdev.ServiceViewer.Data.Gtfs.Enums; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("gtfs_routes")] -[PrimaryKey(nameof(Id), nameof(FeedId))] -public class GtfsRoute -{ - [Column("route_id")] - [MaxLength(255)] - public required string Id { get; set; } - - public string SafeId => Id.Replace(" ", "_").Replace("-", "_"); - - [Column("feed_id")]public int FeedId { get; set; } - [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } - - [Column("agency_id")] - [ForeignKey(nameof(Agency))] - [MaxLength(255)] - public required string AgencyId { get; set; } - - [ForeignKey(nameof(AgencyId))] - public GtfsAgency Agency { get; set; } = null!; - - /// - /// Short name of a route. Often a short, abstract identifier (e.g., "32", "100X", "Green") - /// that riders use to identify a route. Both route_short_name and route_long_name may be defined. - /// - [Column("route_short_name")] - [MaxLength(32)] - public string ShortName { get; set; } = string.Empty; - - /// - /// Full name of a route. This name is generally more descriptive than the route_short_name and often - /// includes the route's destination or stop. Both route_short_name and route_long_name may be defined. - /// - [Column("route_long_name")] - [MaxLength(255)] - public string LongName { get; set; } = string.Empty; - - [Column("route_desc")] - [MaxLength(255)] - public string? Description { get; set; } = string.Empty; - - [Column("route_type")] - public RouteType Type { get; set; } = RouteType.Bus; - - [Column("route_url")] - [MaxLength(255)] - public string? Url { get; set; } = string.Empty; - - [Column("route_color")] - [MaxLength(7)] - public string? Color { get; set; } = string.Empty; - - [Column("route_text_color")] - [MaxLength(7)] - public string? TextColor { get; set; } = string.Empty; - - /// - /// Orders the routes in a way which is ideal for presentation to customers. - /// Routes with smaller route_sort_order values should be displayed first. - /// - [Column("route_sort_order")] - public int SortOrder { get; set; } = 1; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs deleted file mode 100644 index f604c5f..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStop.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Costasdev.ServiceViewer.Data.Gtfs.Enums; -using Microsoft.EntityFrameworkCore; -using NetTopologySuite.Geometries; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("gtfs_stops")] -[PrimaryKey(nameof(Id), nameof(FeedId))] -public class GtfsStop -{ - [Column("stop_id")] - [MaxLength(32)] - public required string Id { get; set; } - - [Column("feed_id")]public int FeedId { get; set; } - [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } - - [Column("stop_code")] - [MaxLength(32)] - public string Code { get; set; } = string.Empty; - - [Column("stop_name")] - [MaxLength(255)] - public string Name { get; set; } = string.Empty; - - [Column("stop_desc")] - [MaxLength(255)] - public string? Description { get; set; } - - [Column("stop_pos")] - public Point? Position { get; set; } - - [Column("stop_url")] - [MaxLength(255)] - public string? Url { get; set; } - - [Column("stop_timezone")] - [MaxLength(50)] - public string? Timezone { get; set; } - - [Column("wheelchair_boarding")] - public WheelchairBoarding WheelchairBoarding { get; set; } = WheelchairBoarding.Unknown; - - // [Column("location_type")] - // public int LocationType { get; set; } - // - // [Column("parent_station")] - // public int? ParentStationId { get; set; } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs deleted file mode 100644 index 9599947..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsStopTime.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Costasdev.ServiceViewer.Data.Extensions; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("gtfs_stop_times")] -[PrimaryKey(nameof(TripId), nameof(StopSequence), nameof(FeedId))] -public class GtfsStopTime -{ - [Column("trip_id")] - [ForeignKey("TripId")] - [MaxLength(32)] - public string TripId { get; set; } = null!; - - [Column("feed_id")]public int FeedId { get; set; } - [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } - - [ForeignKey(nameof(TripId))] public GtfsTrip GtfsTrip { get; set; } = null!; - - [Column("arrival_time")] public string Arrival { get; set; } - public TimeSpan ArrivalTime => TimeSpan.FromGtfsTime(Arrival); - - [Column("departure_time")] public string Departure { get; set; } - public TimeSpan DepartureTime => TimeSpan.FromGtfsTime(Departure); - - [Column("stop_id")] - [ForeignKey(nameof(GtfsStop))] - [MaxLength(32)] - public required string StopId { get; set; } - - [ForeignKey(nameof(StopId))] public GtfsStop GtfsStop { get; set; } = null!; - - [Column("stop_sequence")] public int StopSequence { get; set; } = 0; - - // [Column("pickup_type")] - // public int? PickupType { get; set; } - // - // [Column("drop_off_type")] - // public int? DropOffType { get; set; } - - [Column("shape_dist_traveled")] public double? ShapeDistTraveled { get; set; } = null!; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs deleted file mode 100644 index 3614120..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Gtfs/GtfsTrip.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using Costasdev.ServiceViewer.Data.Gtfs.Enums; -using Microsoft.EntityFrameworkCore; - -namespace Costasdev.ServiceViewer.Data.Gtfs; - -[Table("gtfs_trips")] -[PrimaryKey(nameof(Id), nameof(FeedId))] -public class GtfsTrip -{ - [Column("trip_id")] [MaxLength(32)] public string Id { get; set; } = null!; - - [Column("feed_id")] public int FeedId { get; set; } - [ForeignKey(nameof(FeedId))] public required Feed Feed { get; set; } - - [Column("route_id")] - [MaxLength(32)] - [ForeignKey(nameof(Route))] - public string RouteId { get; set; } = null!; - - [ForeignKey(nameof(RouteId))] public GtfsRoute Route { get; set; } = null!; - - [Column("service_id")] [MaxLength(32)] public string ServiceId { get; set; } = null!; - - [Column("trip_headsign")] - [MaxLength(255)] - public string? TripHeadsign { get; set; } - - [Column("trip_short_name")] - [MaxLength(255)] - public string? TripShortName { get; set; } - - [Column("direction_id")] public DirectionId DirectionId { get; set; } = DirectionId.Outbound; - - /// - /// Identifies the block to which the trip belongs. A block consists of a single trip or many - /// sequential trips made using the same vehicle, defined by shared service days and block_id. - /// A block_id may have trips with different service days, making distinct blocks. - /// - [Column("block_id")] - [MaxLength(32)] - public string? BlockId { get; set; } - - /// - /// Identifies a geospatial shape describing the vehicle travel path for a trip. - /// - /// To be implemented: will be stored as a GeoJSON file instead of database records. - [Column("shape_id")] - [MaxLength(32)] - public string? ShapeId { get; set; } - - [Column("trip_wheelchair_accessible")] - public TripWheelchairAccessible TripWheelchairAccessible { get; set; } = TripWheelchairAccessible.Empty; - - [Column("trip_bikes_allowed")] public TripBikesAllowed TripBikesAllowed { get; set; } = TripBikesAllowed.Empty; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs deleted file mode 100644 index 79f3e87..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.Designer.cs +++ /dev/null @@ -1,547 +0,0 @@ -// -using System; -using Costasdev.ServiceViewer.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using NetTopologySuite.Geometries; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace Data.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20251211153852_Initial")] - partial class Initial - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.1") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.Feed", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("DownloadUrl") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)"); - - b.Property("Etag") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)"); - - b.Property("InsertedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("LongName") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)"); - - b.Property("ShortName") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)"); - - b.HasKey("Id"); - - b.ToTable("feeds"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => - { - b.Property("Id") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("Email") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_email"); - - b.Property("FareUrl") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_fare_url"); - - b.Property("Language") - .IsRequired() - .HasMaxLength(5) - .HasColumnType("character varying(5)") - .HasColumnName("agency_lang"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_name"); - - b.Property("Phone") - .HasMaxLength(30) - .HasColumnType("character varying(30)") - .HasColumnName("agency_phone"); - - b.Property("Timezone") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("agency_timezone"); - - b.Property("Url") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_url"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_agencies"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => - { - b.Property("ServiceId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("service_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("EndDate") - .HasColumnType("date") - .HasColumnName("end_date"); - - b.Property("Friday") - .HasColumnType("boolean") - .HasColumnName("friday"); - - b.Property("Monday") - .HasColumnType("boolean") - .HasColumnName("monday"); - - b.Property("Saturday") - .HasColumnType("boolean") - .HasColumnName("saturday"); - - b.Property("StartDate") - .HasColumnType("date") - .HasColumnName("start_date"); - - b.Property("Sunday") - .HasColumnType("boolean") - .HasColumnName("sunday"); - - b.Property("Thursday") - .HasColumnType("boolean") - .HasColumnName("thursday"); - - b.Property("Tuesday") - .HasColumnType("boolean") - .HasColumnName("tuesday"); - - b.Property("Wednesday") - .HasColumnType("boolean") - .HasColumnName("wednesday"); - - b.HasKey("ServiceId", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_calendar"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => - { - b.Property("ServiceId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("service_id"); - - b.Property("Date") - .HasColumnType("timestamp with time zone") - .HasColumnName("date"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("ExceptionType") - .HasColumnType("integer") - .HasColumnName("exception_type"); - - b.HasKey("ServiceId", "Date", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_calendar_dates"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => - { - b.Property("Id") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("AgencyId") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_id"); - - b.Property("Color") - .HasMaxLength(7) - .HasColumnType("character varying(7)") - .HasColumnName("route_color"); - - b.Property("Description") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_desc"); - - b.Property("LongName") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_long_name"); - - b.Property("ShortName") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("route_short_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("route_sort_order"); - - b.Property("TextColor") - .HasMaxLength(7) - .HasColumnType("character varying(7)") - .HasColumnName("route_text_color"); - - b.Property("Type") - .HasColumnType("integer") - .HasColumnName("route_type"); - - b.Property("Url") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_url"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.HasIndex("AgencyId", "FeedId"); - - b.ToTable("gtfs_routes"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => - { - b.Property("Id") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("stop_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("stop_code"); - - b.Property("Description") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("stop_desc"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("stop_name"); - - b.Property("Position") - .HasColumnType("geometry") - .HasColumnName("stop_pos"); - - b.Property("Timezone") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("stop_timezone"); - - b.Property("Url") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("stop_url"); - - b.Property("WheelchairBoarding") - .HasColumnType("integer") - .HasColumnName("wheelchair_boarding"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_stops"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => - { - b.Property("TripId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("trip_id"); - - b.Property("StopSequence") - .HasColumnType("integer") - .HasColumnName("stop_sequence"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("Arrival") - .IsRequired() - .HasColumnType("text") - .HasColumnName("arrival_time"); - - b.Property("Departure") - .IsRequired() - .HasColumnType("text") - .HasColumnName("departure_time"); - - b.Property("ShapeDistTraveled") - .HasColumnType("double precision") - .HasColumnName("shape_dist_traveled"); - - b.Property("StopId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("stop_id"); - - b.HasKey("TripId", "StopSequence", "FeedId"); - - b.HasIndex("FeedId"); - - b.HasIndex("StopId", "FeedId"); - - b.HasIndex("TripId", "FeedId"); - - b.ToTable("gtfs_stop_times"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => - { - b.Property("Id") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("trip_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("BlockId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("block_id"); - - b.Property("DirectionId") - .HasColumnType("integer") - .HasColumnName("direction_id"); - - b.Property("RouteId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("route_id"); - - b.Property("ServiceId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("service_id"); - - b.Property("ShapeId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("shape_id"); - - b.Property("TripBikesAllowed") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("trip_bikes_allowed"); - - b.Property("TripHeadsign") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("trip_headsign"); - - b.Property("TripShortName") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("trip_short_name"); - - b.Property("TripWheelchairAccessible") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("trip_wheelchair_accessible"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.HasIndex("RouteId", "FeedId"); - - b.ToTable("gtfs_trips"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", "Agency") - .WithMany() - .HasForeignKey("AgencyId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Agency"); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", "GtfsStop") - .WithMany() - .HasForeignKey("StopId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", "GtfsTrip") - .WithMany() - .HasForeignKey("TripId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - - b.Navigation("GtfsStop"); - - b.Navigation("GtfsTrip"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", "Route") - .WithMany() - .HasForeignKey("RouteId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - - b.Navigation("Route"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs deleted file mode 100644 index 5a75d40..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/20251211153852_Initial.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using NetTopologySuite.Geometries; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace Data.Migrations -{ - /// - public partial class Initial : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterDatabase() - .Annotation("Npgsql:PostgresExtension:postgis", ",,"); - - migrationBuilder.CreateTable( - name: "feeds", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ShortName = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - LongName = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - DownloadUrl = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - Etag = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - InsertedAt = table.Column(type: "timestamp with time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_feeds", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "gtfs_agencies", - columns: table => new - { - agency_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - feed_id = table.Column(type: "integer", nullable: false), - agency_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - agency_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - agency_timezone = table.Column(type: "character varying(50)", maxLength: 50, nullable: false), - agency_lang = table.Column(type: "character varying(5)", maxLength: 5, nullable: false), - agency_phone = table.Column(type: "character varying(30)", maxLength: 30, nullable: true), - agency_email = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - agency_fare_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_gtfs_agencies", x => new { x.agency_id, x.feed_id }); - table.ForeignKey( - name: "FK_gtfs_agencies_feeds_feed_id", - column: x => x.feed_id, - principalTable: "feeds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "gtfs_calendar", - columns: table => new - { - service_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - feed_id = table.Column(type: "integer", nullable: false), - monday = table.Column(type: "boolean", nullable: false), - tuesday = table.Column(type: "boolean", nullable: false), - wednesday = table.Column(type: "boolean", nullable: false), - thursday = table.Column(type: "boolean", nullable: false), - friday = table.Column(type: "boolean", nullable: false), - saturday = table.Column(type: "boolean", nullable: false), - sunday = table.Column(type: "boolean", nullable: false), - start_date = table.Column(type: "date", nullable: false), - end_date = table.Column(type: "date", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_gtfs_calendar", x => new { x.service_id, x.feed_id }); - table.ForeignKey( - name: "FK_gtfs_calendar_feeds_feed_id", - column: x => x.feed_id, - principalTable: "feeds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "gtfs_calendar_dates", - columns: table => new - { - service_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - date = table.Column(type: "timestamp with time zone", nullable: false), - feed_id = table.Column(type: "integer", nullable: false), - exception_type = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_gtfs_calendar_dates", x => new { x.service_id, x.date, x.feed_id }); - table.ForeignKey( - name: "FK_gtfs_calendar_dates_feeds_feed_id", - column: x => x.feed_id, - principalTable: "feeds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "gtfs_stops", - columns: table => new - { - stop_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - feed_id = table.Column(type: "integer", nullable: false), - stop_code = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - stop_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - stop_desc = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - stop_pos = table.Column(type: "geometry", nullable: true), - stop_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - stop_timezone = table.Column(type: "character varying(50)", maxLength: 50, nullable: true), - wheelchair_boarding = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_gtfs_stops", x => new { x.stop_id, x.feed_id }); - table.ForeignKey( - name: "FK_gtfs_stops_feeds_feed_id", - column: x => x.feed_id, - principalTable: "feeds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "gtfs_routes", - columns: table => new - { - route_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - feed_id = table.Column(type: "integer", nullable: false), - agency_id = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - route_short_name = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - route_long_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: false), - route_desc = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - route_type = table.Column(type: "integer", nullable: false), - route_url = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - route_color = table.Column(type: "character varying(7)", maxLength: 7, nullable: true), - route_text_color = table.Column(type: "character varying(7)", maxLength: 7, nullable: true), - route_sort_order = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_gtfs_routes", x => new { x.route_id, x.feed_id }); - table.ForeignKey( - name: "FK_gtfs_routes_feeds_feed_id", - column: x => x.feed_id, - principalTable: "feeds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_gtfs_routes_gtfs_agencies_agency_id_feed_id", - columns: x => new { x.agency_id, x.feed_id }, - principalTable: "gtfs_agencies", - principalColumns: new[] { "agency_id", "feed_id" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "gtfs_trips", - columns: table => new - { - trip_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - feed_id = table.Column(type: "integer", nullable: false), - route_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - service_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - trip_headsign = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - trip_short_name = table.Column(type: "character varying(255)", maxLength: 255, nullable: true), - direction_id = table.Column(type: "integer", nullable: false), - block_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - shape_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: true), - trip_wheelchair_accessible = table.Column(type: "integer", nullable: false, defaultValue: 0), - trip_bikes_allowed = table.Column(type: "integer", nullable: false, defaultValue: 0) - }, - constraints: table => - { - table.PrimaryKey("PK_gtfs_trips", x => new { x.trip_id, x.feed_id }); - table.ForeignKey( - name: "FK_gtfs_trips_feeds_feed_id", - column: x => x.feed_id, - principalTable: "feeds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_gtfs_trips_gtfs_routes_route_id_feed_id", - columns: x => new { x.route_id, x.feed_id }, - principalTable: "gtfs_routes", - principalColumns: new[] { "route_id", "feed_id" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "gtfs_stop_times", - columns: table => new - { - trip_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - feed_id = table.Column(type: "integer", nullable: false), - stop_sequence = table.Column(type: "integer", nullable: false), - arrival_time = table.Column(type: "text", nullable: false), - departure_time = table.Column(type: "text", nullable: false), - stop_id = table.Column(type: "character varying(32)", maxLength: 32, nullable: false), - shape_dist_traveled = table.Column(type: "double precision", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_gtfs_stop_times", x => new { x.trip_id, x.stop_sequence, x.feed_id }); - table.ForeignKey( - name: "FK_gtfs_stop_times_feeds_feed_id", - column: x => x.feed_id, - principalTable: "feeds", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_gtfs_stop_times_gtfs_stops_stop_id_feed_id", - columns: x => new { x.stop_id, x.feed_id }, - principalTable: "gtfs_stops", - principalColumns: new[] { "stop_id", "feed_id" }, - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_gtfs_stop_times_gtfs_trips_trip_id_feed_id", - columns: x => new { x.trip_id, x.feed_id }, - principalTable: "gtfs_trips", - principalColumns: new[] { "trip_id", "feed_id" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_agencies_feed_id", - table: "gtfs_agencies", - column: "feed_id"); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_calendar_feed_id", - table: "gtfs_calendar", - column: "feed_id"); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_calendar_dates_feed_id", - table: "gtfs_calendar_dates", - column: "feed_id"); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_routes_agency_id_feed_id", - table: "gtfs_routes", - columns: new[] { "agency_id", "feed_id" }); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_routes_feed_id", - table: "gtfs_routes", - column: "feed_id"); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_stop_times_feed_id", - table: "gtfs_stop_times", - column: "feed_id"); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_stop_times_stop_id_feed_id", - table: "gtfs_stop_times", - columns: new[] { "stop_id", "feed_id" }); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_stop_times_trip_id_feed_id", - table: "gtfs_stop_times", - columns: new[] { "trip_id", "feed_id" }); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_stops_feed_id", - table: "gtfs_stops", - column: "feed_id"); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_trips_feed_id", - table: "gtfs_trips", - column: "feed_id"); - - migrationBuilder.CreateIndex( - name: "IX_gtfs_trips_route_id_feed_id", - table: "gtfs_trips", - columns: new[] { "route_id", "feed_id" }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "gtfs_calendar"); - - migrationBuilder.DropTable( - name: "gtfs_calendar_dates"); - - migrationBuilder.DropTable( - name: "gtfs_stop_times"); - - migrationBuilder.DropTable( - name: "gtfs_stops"); - - migrationBuilder.DropTable( - name: "gtfs_trips"); - - migrationBuilder.DropTable( - name: "gtfs_routes"); - - migrationBuilder.DropTable( - name: "gtfs_agencies"); - - migrationBuilder.DropTable( - name: "feeds"); - } - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs deleted file mode 100644 index feb3813..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/Migrations/AppDbContextModelSnapshot.cs +++ /dev/null @@ -1,544 +0,0 @@ -// -using System; -using Costasdev.ServiceViewer.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using NetTopologySuite.Geometries; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace Data.Migrations -{ - [DbContext(typeof(AppDbContext))] - partial class AppDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.1") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis"); - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.Feed", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("DownloadUrl") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)"); - - b.Property("Etag") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)"); - - b.Property("InsertedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("LongName") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)"); - - b.Property("ShortName") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)"); - - b.HasKey("Id"); - - b.ToTable("feeds"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => - { - b.Property("Id") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("Email") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_email"); - - b.Property("FareUrl") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_fare_url"); - - b.Property("Language") - .IsRequired() - .HasMaxLength(5) - .HasColumnType("character varying(5)") - .HasColumnName("agency_lang"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_name"); - - b.Property("Phone") - .HasMaxLength(30) - .HasColumnType("character varying(30)") - .HasColumnName("agency_phone"); - - b.Property("Timezone") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("agency_timezone"); - - b.Property("Url") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_url"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_agencies"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => - { - b.Property("ServiceId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("service_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("EndDate") - .HasColumnType("date") - .HasColumnName("end_date"); - - b.Property("Friday") - .HasColumnType("boolean") - .HasColumnName("friday"); - - b.Property("Monday") - .HasColumnType("boolean") - .HasColumnName("monday"); - - b.Property("Saturday") - .HasColumnType("boolean") - .HasColumnName("saturday"); - - b.Property("StartDate") - .HasColumnType("date") - .HasColumnName("start_date"); - - b.Property("Sunday") - .HasColumnType("boolean") - .HasColumnName("sunday"); - - b.Property("Thursday") - .HasColumnType("boolean") - .HasColumnName("thursday"); - - b.Property("Tuesday") - .HasColumnType("boolean") - .HasColumnName("tuesday"); - - b.Property("Wednesday") - .HasColumnType("boolean") - .HasColumnName("wednesday"); - - b.HasKey("ServiceId", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_calendar"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => - { - b.Property("ServiceId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("service_id"); - - b.Property("Date") - .HasColumnType("timestamp with time zone") - .HasColumnName("date"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("ExceptionType") - .HasColumnType("integer") - .HasColumnName("exception_type"); - - b.HasKey("ServiceId", "Date", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_calendar_dates"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => - { - b.Property("Id") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("AgencyId") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("agency_id"); - - b.Property("Color") - .HasMaxLength(7) - .HasColumnType("character varying(7)") - .HasColumnName("route_color"); - - b.Property("Description") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_desc"); - - b.Property("LongName") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_long_name"); - - b.Property("ShortName") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("route_short_name"); - - b.Property("SortOrder") - .HasColumnType("integer") - .HasColumnName("route_sort_order"); - - b.Property("TextColor") - .HasMaxLength(7) - .HasColumnType("character varying(7)") - .HasColumnName("route_text_color"); - - b.Property("Type") - .HasColumnType("integer") - .HasColumnName("route_type"); - - b.Property("Url") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("route_url"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.HasIndex("AgencyId", "FeedId"); - - b.ToTable("gtfs_routes"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => - { - b.Property("Id") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("stop_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("Code") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("stop_code"); - - b.Property("Description") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("stop_desc"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("stop_name"); - - b.Property("Position") - .HasColumnType("geometry") - .HasColumnName("stop_pos"); - - b.Property("Timezone") - .HasMaxLength(50) - .HasColumnType("character varying(50)") - .HasColumnName("stop_timezone"); - - b.Property("Url") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("stop_url"); - - b.Property("WheelchairBoarding") - .HasColumnType("integer") - .HasColumnName("wheelchair_boarding"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.ToTable("gtfs_stops"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => - { - b.Property("TripId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("trip_id"); - - b.Property("StopSequence") - .HasColumnType("integer") - .HasColumnName("stop_sequence"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("Arrival") - .IsRequired() - .HasColumnType("text") - .HasColumnName("arrival_time"); - - b.Property("Departure") - .IsRequired() - .HasColumnType("text") - .HasColumnName("departure_time"); - - b.Property("ShapeDistTraveled") - .HasColumnType("double precision") - .HasColumnName("shape_dist_traveled"); - - b.Property("StopId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("stop_id"); - - b.HasKey("TripId", "StopSequence", "FeedId"); - - b.HasIndex("FeedId"); - - b.HasIndex("StopId", "FeedId"); - - b.HasIndex("TripId", "FeedId"); - - b.ToTable("gtfs_stop_times"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => - { - b.Property("Id") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("trip_id"); - - b.Property("FeedId") - .HasColumnType("integer") - .HasColumnName("feed_id"); - - b.Property("BlockId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("block_id"); - - b.Property("DirectionId") - .HasColumnType("integer") - .HasColumnName("direction_id"); - - b.Property("RouteId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("route_id"); - - b.Property("ServiceId") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("service_id"); - - b.Property("ShapeId") - .HasMaxLength(32) - .HasColumnType("character varying(32)") - .HasColumnName("shape_id"); - - b.Property("TripBikesAllowed") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("trip_bikes_allowed"); - - b.Property("TripHeadsign") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("trip_headsign"); - - b.Property("TripShortName") - .HasMaxLength(255) - .HasColumnType("character varying(255)") - .HasColumnName("trip_short_name"); - - b.Property("TripWheelchairAccessible") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("trip_wheelchair_accessible"); - - b.HasKey("Id", "FeedId"); - - b.HasIndex("FeedId"); - - b.HasIndex("RouteId", "FeedId"); - - b.ToTable("gtfs_trips"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendar", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsCalendarDate", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsAgency", "Agency") - .WithMany() - .HasForeignKey("AgencyId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Agency"); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsStopTime", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsStop", "GtfsStop") - .WithMany() - .HasForeignKey("StopId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", "GtfsTrip") - .WithMany() - .HasForeignKey("TripId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - - b.Navigation("GtfsStop"); - - b.Navigation("GtfsTrip"); - }); - - modelBuilder.Entity("Costasdev.ServiceViewer.Data.Gtfs.GtfsTrip", b => - { - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.Feed", "Feed") - .WithMany() - .HasForeignKey("FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Costasdev.ServiceViewer.Data.Gtfs.GtfsRoute", "Route") - .WithMany() - .HasForeignKey("RouteId", "FeedId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Feed"); - - b.Navigation("Route"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Data/QueryExtensions/GtfsCalendarQueryExtensions.cs b/src/Costasdev.Busurbano.ServiceViewer/Data/QueryExtensions/GtfsCalendarQueryExtensions.cs deleted file mode 100644 index f5fc2bb..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Data/QueryExtensions/GtfsCalendarQueryExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Costasdev.ServiceViewer.Data.Gtfs; - -namespace Costasdev.ServiceViewer.Data.QueryExtensions; - -public static class GtfsCalendarQueryExtensions -{ - public static IQueryable WhereDayOfWeek(this IQueryable query, DayOfWeek dayOfWeek) - { - return dayOfWeek switch - { - DayOfWeek.Monday => query.Where(c => c.Monday), - DayOfWeek.Tuesday => query.Where(c => c.Tuesday), - DayOfWeek.Wednesday => query.Where(c => c.Wednesday), - DayOfWeek.Thursday => query.Where(c => c.Thursday), - DayOfWeek.Friday => query.Where(c => c.Friday), - DayOfWeek.Saturday => query.Where(c => c.Saturday), - DayOfWeek.Sunday => query.Where(c => c.Sunday), - _ => query - }; - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Program.cs b/src/Costasdev.Busurbano.ServiceViewer/Program.cs deleted file mode 100644 index 847f9d5..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Program.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Costasdev.ServiceViewer; -using Costasdev.ServiceViewer.Data; -using Microsoft.EntityFrameworkCore; - -var builder = WebApplication.CreateBuilder(args); - -builder.Services.AddControllersWithViews(); - -builder.Services.AddDbContext(db => -{ - var connectionString = builder.Configuration.GetConnectionString("Database"); - if (string.IsNullOrEmpty(connectionString)) - { - throw new InvalidOperationException("Connection string 'Database' is not configured."); - } - db.UseNpgsql(connectionString, npg => - { - npg.UseNetTopologySuite(); - }); -}); - -builder.Services.AddHttpClient(); -builder.Services.AddMemoryCache(); - -var app = builder.Build(); - -app.UseHttpsRedirection(); -app.UseRouting(); - -app.UseStaticFiles(); -app.MapStaticAssets(); - -app.MapControllers(); - -app.Run(); diff --git a/src/Costasdev.Busurbano.ServiceViewer/Properties/launchSettings.json b/src/Costasdev.Busurbano.ServiceViewer/Properties/launchSettings.json deleted file mode 100644 index 34eab40..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Properties/launchSettings.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/launchsettings.json", - "profiles": { - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:7265;http://localhost:5154", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml b/src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml deleted file mode 100644 index 84f30a3..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml +++ /dev/null @@ -1,22 +0,0 @@ -@model Costasdev.ServiceViewer.Views.Services.DaysInFeedModel -@{ - ViewData["Title"] = "Fechas con datos"; -} - -@section Head -{ - -} - -
-

Fechas con datos

-
- -
- @foreach (var day in Model.Days) - { - - } -
diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml.cs b/src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml.cs deleted file mode 100644 index 02fe5b0..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/DaysInFeed.cshtml.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Costasdev.ServiceViewer.Views.Services; - -public class DaysInFeedModel -{ - public List Days { get; set; } = []; - public DateOnly Today { get; set; } -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml b/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml deleted file mode 100644 index 8eae631..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml +++ /dev/null @@ -1,63 +0,0 @@ -@using Costasdev.ServiceViewer.Data.Gtfs -@using Humanizer -@using Humanizer.Localisation -@model Costasdev.ServiceViewer.Views.Services.ServiceDetailsModel -@{ - ViewData["Title"] = Model.ServiceName; -} - -@section Head -{ - - - -} - -
-

@ViewData["Title"]

-
- - - -
- @foreach (ServiceDetailsItem item in Model.Items) - { -
-
-
@item.ShortName
-
@item.LongName
-
- @item.TotalDistance -
-
-
-
-
@item.FirstStopTime
-
@item.FirstStopName
-
-
-
@item.LastStopTime
-
@item.LastStopName
-
-
- -
- } -
- -
- Tiempo de conducción: @Model.TotalDrivingTime.Hours horas y @Model.TotalDrivingTime.Minutes minutos.
- Distancia total: @Model.TotalDistanceKm -
diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml.cs b/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml.cs deleted file mode 100644 index a89efae..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServiceDetails.cshtml.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Costasdev.ServiceViewer.Views.Services; - -public class ServiceDetailsModel -{ - public DateOnly Date { get; set; } - public string ServiceId { get; set; } = string.Empty; - public string ServiceName { get; set; } = string.Empty; - - public List Items { get; set; } = []; - public TimeSpan TotalDrivingTime { get; set; } - - public int TotalDistance { get; set; } - public string TotalDistanceKm => (TotalDistance / 1000.0).ToString("0.00 km"); -} - -public class ServiceDetailsItem -{ - public string TripId { get; set; } = string.Empty; - public string SafeRouteId { get; set; } = string.Empty; - public string ShortName { get; set; } = string.Empty; - public string LongName { get; set; } = string.Empty; - public string TotalDistance { get; set; } = string.Empty; - - public string FirstStopTime { get; set; } = string.Empty; - public string FirstStopName { get; set; } = string.Empty; - - public string LastStopTime { get; set; } = string.Empty; - public string LastStopName { get; set; } = string.Empty; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml b/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml deleted file mode 100644 index a5ac66f..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml +++ /dev/null @@ -1,40 +0,0 @@ -@model Costasdev.ServiceViewer.Views.Services.ServiceInDayModel -@{ - ViewData["Title"] = "Servicios a realizar en " + Model.Date.ToString("dd 'de' MMMM 'de' yyyy"); -} - -@section Head -{ - - -} - -
-

- @ViewData["Title"] -

-
- -
- @foreach (ServicesInDayItem card in Model.Items) - { -
-
- - @card.ServiceName - -
-
- @card.ShiftStart → @card.ShiftEnd -
-
- @foreach (var cardTripGroup in card.TripGroups) - { - - @cardTripGroup.route.ShortName (@cardTripGroup.count) - - } -
-
- } -
diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml.cs b/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml.cs deleted file mode 100644 index b0c57c3..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/Services/ServicesInDay.cshtml.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Costasdev.ServiceViewer.Data.Gtfs; - -namespace Costasdev.ServiceViewer.Views.Services; - -public class ServiceInDayModel -{ - public List Items { get; set; } = []; - public DateOnly Date { get; set; } -} - -public class ServicesInDayItem -{ - public string ServiceId { get; set; } - public string ServiceName { get; set; } - public List Trips { get; set; } - public List TripGroups { get; set; } - - public string ShiftStart { get; set; } - public string ShiftEnd { get; set; } - - public ServicesInDayItem( - string serviceId, - string serviceName, - List trips, - List tripGroups, - string shiftStart, - string shiftEnd - ) { - ServiceId = serviceId; - ServiceName = serviceName; - Trips = trips; - TripGroups = tripGroups; - - ShiftStart = shiftStart; - ShiftEnd = shiftEnd; - } -} - -public record TripGroup(GtfsRoute route, int count); diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/Shared/_Layout.cshtml b/src/Costasdev.Busurbano.ServiceViewer/Views/Shared/_Layout.cshtml deleted file mode 100644 index 88d5b83..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/Shared/_Layout.cshtml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - @ViewData["Title"] - VentaSync - - - - @await RenderSectionAsync("Head", required: false) - - - - -@RenderBody() - - diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/_ViewImports.cshtml b/src/Costasdev.Busurbano.ServiceViewer/Views/_ViewImports.cshtml deleted file mode 100644 index 785dc40..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/_ViewImports.cshtml +++ /dev/null @@ -1,2 +0,0 @@ -@using Costasdev.ServiceViewer.Views.Services -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/Costasdev.Busurbano.ServiceViewer/Views/_ViewStart.cshtml b/src/Costasdev.Busurbano.ServiceViewer/Views/_ViewStart.cshtml deleted file mode 100644 index a5f1004..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/Views/_ViewStart.cshtml +++ /dev/null @@ -1,3 +0,0 @@ -@{ - Layout = "_Layout"; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/appsettings.json b/src/Costasdev.Busurbano.ServiceViewer/appsettings.json deleted file mode 100644 index 10f68b8..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning" - } - }, - "AllowedHosts": "*" -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/common.css b/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/common.css deleted file mode 100644 index a0e0750..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/common.css +++ /dev/null @@ -1,23 +0,0 @@ -body { - font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - padding: 2rem; - background-color: #fff; - max-width: 800px; - margin: 0 auto; - line-height: 1.5; -} - -h1 { - font-size: 1.75rem; - margin-bottom: 1.5rem; - text-align: center; -} - -body > footer { - text-align: center; - font-size: 0.85rem; - color: #666; - margin-top: 2rem; - padding-top: 1rem; - border-top: 1px solid #ddd; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/days_in_feed.css b/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/days_in_feed.css deleted file mode 100644 index b3c46d1..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/days_in_feed.css +++ /dev/null @@ -1,28 +0,0 @@ -main article { - background: #f9f9f9; - border: 1px solid #ddd; - border-radius: 4px; - padding: 0.75rem 1rem; - margin: 0.5rem 0; - text-align: center; -} - -main article.current-day { - background: #e3f2fd; - border-color: #0074d9; -} - -main article.current-day a { - font-weight: 700; -} - -main article a { - font-size: 1rem; - font-weight: 500; - color: #0074d9; - text-decoration: none; -} - -main article a:hover { - text-decoration: underline; -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/service_details.css b/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/service_details.css deleted file mode 100644 index 570de3a..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/service_details.css +++ /dev/null @@ -1,146 +0,0 @@ -.navigation-bar { - margin-bottom: 1.5rem; - font-size: 0.9rem; -} - -.trip-container { - border: 1px solid #ddd; - border-radius: 0.25rem; - background-color: var(--route-color-semi, #fafafa); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); - margin-bottom: 1.5rem; - overflow: hidden; -} - -.trip-header { - display: flex; - background-color: #fff; - border-bottom: 1px solid #eee; - padding: 0.6rem 0.8rem; -} - -.trip-header .route { - font-weight: bold; - font-size: 1.1rem; - min-width: 60px; - display: flex; - align-items: center; - justify-content: center; - border-right: 1px solid #ddd; - margin-right: 0.5rem; - padding-right: 0.5rem; -} - -.trip-header .headsign { - flex-grow: 1; - font-weight: 500; -} - -.trip-header .distance { - min-width: 80px; - text-align: right; - font-weight: 500; -} - -.trip-details { - display: flex; - flex-wrap: wrap; -} - -.trip-leg { - flex: 1; - min-width: 280px; - padding: 0.75rem; -} - -.trip-leg:first-child { - border-right: 1px solid #ddd; -} - -.trip-time { - font-weight: 600; - font-family: 'Consolas', monospace; - font-size: 1.1rem; -} - -.trip-stop { - margin-top: 0.25rem; - color: #333; -} - -.trip-footer { - text-align: right; - margin: 0.5em 1em 0.5em 0; -} - -.trip-details-link { - color: #0074d9; - text-decoration: underline; - font-size: 0.98em; -} - -/* Day change marker */ -.day-change-marker { - background-color: #fff3cd; - border: 2px solid #f5c86a; - color: #856404; - text-align: center; - padding: 0.75rem; - margin: 1rem 0; - border-radius: 4px; - font-weight: bold; -} - -/* Total distance counter */ -.total-distance { - text-align: right; - font-weight: bold; - padding: 0.75rem; - margin-top: 1.5rem; - border-top: 1px solid #ddd; - background-color: #f9f9f9; - border-radius: 4px; -} - -/* Highlight current trip */ -.trip-container.highlight { - box-shadow: 0 0 8px rgba(0, 116, 217, 0.6); - border-color: #0074d9; - padding: 1rem; -} - -/* Media query for print */ -@media print { - body { - padding: 0; - margin: 0; - } - - .trip-container { - page-break-inside: avoid; - border: 1px solid #000; - margin-bottom: 0.5rem; - } - - .trip-header { - background-color: #f5f5f5 !important; - } - - .day-change-marker { - border: 1px solid #000; - background-color: #f5f5f5 !important; - color: #000; - } - - .navigation { - display: none; - } -} - -.trip-line--N1 { - background-color: rgba(191, 191, 191, 0.30); -} - -.trip-line-VITRASA { - background-color: rgba(0, 153, 0, 0.30); -} diff --git a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/services_in_day.css b/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/services_in_day.css deleted file mode 100644 index ce847ef..0000000 --- a/src/Costasdev.Busurbano.ServiceViewer/wwwroot/styles/services_in_day.css +++ /dev/null @@ -1,70 +0,0 @@ -a { - color: #0074d9; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - -#service-cards { - list-style: none; - padding: 0; - margin: 0; -} - -#service-cards article { - background: #f9f9f9; - border: 1px solid #ddd; - border-radius: 4px; - margin: 0.5rem 0; - padding: 1rem; -} - -#service-cards article header { - font-weight: 600; - font-size: 1.1rem; - margin-bottom: 0.5rem; -} - -#service-cards article main { - font-size: 0.9rem; - margin-bottom: 0.75rem; - color: #555; -} - -#service-cards article footer { - margin-top: 0.5rem; - display: flex; - flex-wrap: wrap; - gap: 0.125rem 0.75rem; -} - -#service-cards article footer span.route-group { - display: inline-block; - padding: 0.3rem 0.6rem; - margin: 0.25rem 0.1rem; - font-size: 0.85rem; - font-weight: 600; - - background: #FFF; - border-bottom: 4px solid var(--route-color, #000); - color: var(--route-text, #000); -} - -/* Filter button styles */ -.filter-btn { - padding: 0.4rem 0.8rem; - margin: 0.2rem; - border: 1px solid #0074d9; - border-radius: 4px; - background: #fff; - color: #0074d9; - cursor: pointer; - transition: background 0.2s, color 0.2s; -} - -.filter-btn.active { - background: #0074d9; - color: #fff; -} -- cgit v1.3