aboutsummaryrefslogtreecommitdiff
path: root/src/Enmarcha.Backend/Services/Processors
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2026-03-16 13:01:36 +0100
committerAriel Costas Guerrero <ariel@costas.dev>2026-03-16 13:01:36 +0100
commit3ce586243a49f34b36d0fe4099bbfb2631610f11 (patch)
treee1a654141bd8aef1852883aeef25392409c73891 /src/Enmarcha.Backend/Services/Processors
parent99005bce74288a415ac748414e0f8b522e207c93 (diff)
New marquee generation logic for Xunta
Diffstat (limited to 'src/Enmarcha.Backend/Services/Processors')
-rw-r--r--src/Enmarcha.Backend/Services/Processors/FeedConfigProcessor.cs2
-rw-r--r--src/Enmarcha.Backend/Services/Processors/MarqueeProcessor.cs28
-rw-r--r--src/Enmarcha.Backend/Services/Processors/NextStopsProcessor.cs99
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]);
+ }
}