diff options
| author | Ariel Costas Guerrero <ariel@costas.dev> | 2026-03-16 13:01:36 +0100 |
|---|---|---|
| committer | Ariel Costas Guerrero <ariel@costas.dev> | 2026-03-16 13:01:36 +0100 |
| commit | 3ce586243a49f34b36d0fe4099bbfb2631610f11 (patch) | |
| tree | e1a654141bd8aef1852883aeef25392409c73891 /src/Enmarcha.Backend/Services/Processors | |
| parent | 99005bce74288a415ac748414e0f8b522e207c93 (diff) | |
New marquee generation logic for Xunta
Diffstat (limited to 'src/Enmarcha.Backend/Services/Processors')
3 files changed, 95 insertions, 34 deletions
diff --git a/src/Enmarcha.Backend/Services/Processors/FeedConfigProcessor.cs b/src/Enmarcha.Backend/Services/Processors/FeedConfigProcessor.cs index 196091a..9fc46c7 100644 --- a/src/Enmarcha.Backend/Services/Processors/FeedConfigProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/FeedConfigProcessor.cs @@ -20,7 +20,7 @@ public class FeedConfigProcessor : IArrivalsProcessor foreach (var arrival in context.Arrivals) { arrival.Route.ShortName = _feedService.NormalizeRouteShortName(feedId, arrival.Route.ShortName); - arrival.Headsign.Destination = _feedService.NormalizeStopName(feedId, arrival.Headsign.Destination); + arrival.Headsign.Destination = FeedService.NormalizeStopName(feedId, arrival.Headsign.Destination); // Apply Vitrasa-specific line formatting if (feedId == "vitrasa") diff --git a/src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs b/src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs deleted file mode 100644 index d5ff58e..0000000 --- a/src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace Enmarcha.Backend.Services.Processors; - -public class MarqueeProcessor : IArrivalsProcessor -{ - private readonly FeedService _feedService; - - public MarqueeProcessor(FeedService feedService) - { - _feedService = feedService; - } - - public Task ProcessAsync(ArrivalsContext context) - { - if (context.IsNano) return Task.CompletedTask; - - var feedId = context.StopId.Split(':')[0]; - - foreach (var arrival in context.Arrivals) - { - if (string.IsNullOrEmpty(arrival.Headsign.Marquee)) - { - arrival.Headsign.Marquee = _feedService.GenerateMarquee(feedId, arrival.NextStops); - } - } - - return Task.CompletedTask; - } -} diff --git a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs index 5bdb5bb..84e0d0f 100644 --- a/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs +++ b/src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs @@ -1,3 +1,4 @@ +using System.Text; using Enmarcha.Sources.OpenTripPlannerGql.Queries; namespace Enmarcha.Backend.Services.Processors; @@ -20,17 +21,105 @@ public class NextStopsProcessor : IArrivalsProcessor foreach (var arrival in context.Arrivals) { if (arrival.RawOtpTrip is not ArrivalsAtStopResponse.Arrival otpArrival) continue; + if (arrival.Headsign.Marquee is not null) continue; // Filter stoptimes that are after the current stop's departure var currentStopDeparture = otpArrival.ScheduledDepartureSeconds; - arrival.NextStops = otpArrival.Trip.Stoptimes - .Where(s => s.ScheduledDeparture > currentStopDeparture) - .OrderBy(s => s.ScheduledDeparture) - .Select(s => _feedService.NormalizeStopName(feedId, s.Stop.Name)) - .ToList(); + if (feedId == "xunta") + { + arrival.NextStops = otpArrival.Trip.Stoptimes + .Where(s => s.ScheduledDeparture > currentStopDeparture) + .OrderBy(s => s.ScheduledDeparture) + .Select(s => s.Stop.Description) + .Distinct() + .ToList(); + } + else + { + arrival.NextStops = otpArrival.Trip.Stoptimes + .Where(s => s.ScheduledDeparture > currentStopDeparture) + .OrderBy(s => s.ScheduledDeparture) + .Select(s => FeedService.NormalizeStopName(feedId, s.Stop.Name)) + .ToList(); + } + + arrival.Headsign.Marquee = GenerateMarquee(feedId, arrival.NextStops); } return Task.CompletedTask; } + + private static string? GenerateMarquee(string feedId, List<string> nextStops) + { + if (nextStops.Count == 0) return null; + + if (feedId is "vitrasa" or "tranvias" or "tussa" or "ourense") + { + var streets = nextStops + .Select(FeedService.GetStreetName) + .Where(s => !string.IsNullOrWhiteSpace(s)) + .Distinct() + .ToList(); + + return string.Join(" - ", streets); + } + + if (feedId == "xunta") + { + var points = nextStops + .Select(SplitXuntaStopDescription) + .ToList(); + + List<string> seenConcellos = new(); + List<string> seenParroquias = new(); + List<string> items = []; + + foreach (var (parroquia, concello) in points) + { + // Santiago de Compostela -- Santiago de Compostela > Conxo -- Santiago de Compostela > BiduĂdo -- Ames > Calo -- Teo > Bugallido -- Ames + // Santiago de Compostela -> Conxo -> Bidueiro (Ames) -> Calo (Teo) -> Bugallido + string item = ""; + + if (!seenParroquias.Contains(parroquia)) + { + seenParroquias.Add(parroquia); + item += $"{parroquia}"; + + if (parroquia == concello) + { + seenConcellos.Add(concello); + } + + if (!seenConcellos.Contains(concello)) + { + seenConcellos.Add(concello); + item += $" ({concello})"; + } + + items.Add(item); + } + + } + + return string.Join(" > ", items); + } + + return feedId switch + { + "renfe" => string.Join(" - ", nextStops), + _ => string.Join(", ", nextStops.Take(4)) + }; + } + + private static (string parroquia, string concello) SplitXuntaStopDescription(string stopName) + { + var parts = stopName.Split(" -- ", 2); + if (parts.Length != 2) + { + return ("", ""); // TODO: Throw + } + + return (parts[0], parts[1]); + } } |
