@@ -51,22 +51,44 @@ public async Task<IActionResult> Run(
5151 riders . AddRange ( ridersPortion ) ;
5252 }
5353
54- var ridersTaskResult = await GetRacesResults ( riders , request . Urls , cancellationToken ) ;
54+ var racesResults = await GetRacesResults ( [ .. riders ] , request . Urls , cancellationToken ) ;
5555
56- var result = ridersTaskResult
57- . Select ( x => new
56+ var isITT = racesResults . All ( x => x . Key . Event . IsITT ) ;
57+ var bestTimeOverAll = racesResults
58+ . SelectMany ( x => x . Value )
59+ . Min ( x => x . ActivityData . DurationInMilliseconds ) ;
60+
61+ var result = racesResults
62+ . Where ( kv => kv . Value . Count > 0 )
63+ . SelectMany ( kv =>
5864 {
59- RiderId = x . ProfileId ,
60- FullName = $ "{ x . ProfileData . FirstName } { x . ProfileData . LastName } ",
61- Duration = TimeSpan . FromMilliseconds ( x . ActivityData . DurationInMilliseconds ) ,
62- CritivalPower = x . CriticalP ,
63- AvgPower = x . SensorData . AvgWatts ,
64- AvgPowerPerKg = x . SensorData . AvgWatts / ( x . ProfileData . WeightInGrams / 1000.0 ) ,
65+ var raceResults = kv . Value ;
66+
67+ var bestTime = isITT
68+ ? bestTimeOverAll
69+ : raceResults . Min ( x => x . ActivityData . DurationInMilliseconds ) ;
70+
71+ var bestTimeSpan = TimeSpan . FromMilliseconds ( bestTime ) ;
72+
73+ return raceResults . Select ( x =>
74+ {
75+ var duration = TimeSpan . FromMilliseconds ( x . ActivityData . DurationInMilliseconds ) ;
76+
77+ return new
78+ {
79+ RiderId = x . ProfileId ,
80+ FullName = $ "{ x . ProfileData . FirstName } { x . ProfileData . LastName } ",
81+ Duration = duration ,
82+ CritivalPower = x . CriticalP ,
83+ AvgPower = x . SensorData . AvgWatts ,
84+ AvgPowerPerKg = x . SensorData . AvgWatts / ( x . ProfileData . WeightInGrams / 1000.0 ) ,
85+ EGap = duration - bestTimeSpan ,
86+ } ;
87+ } ) ;
6588 } )
66- . OrderBy ( x => x . Duration )
89+ . OrderBy ( x => x . EGap )
6790 . ToList ( ) ;
6891
69-
7092 return new OkObjectResult ( result ) ;
7193 }
7294
@@ -84,13 +106,12 @@ private IEnumerable<FlammeRougeRacingCategory> ParseCategories(StringValues cate
84106 }
85107 }
86108
87- private async Task < List < ZwiftRaceResultEntryResponse > > GetRacesResults (
88- List < long > riders ,
89- string [ ] urls ,
109+ private async Task < Dictionary < ZwiftEventEventSubgroupKey , List < ZwiftRaceResultEntryResponse > > > GetRacesResults (
110+ HashSet < long > riders ,
111+ HashSet < string > urls ,
90112 CancellationToken cancellationToken )
91113 {
92- var ridersSet = riders . ToHashSet ( ) ;
93- List < ZwiftRaceResultEntryResponse > acc = [ ] ;
114+ Dictionary < ZwiftEventEventSubgroupKey , List < ZwiftRaceResultEntryResponse > > result = [ ] ;
94115
95116 foreach ( var url in urls )
96117 {
@@ -108,22 +129,41 @@ private async Task<List<ZwiftRaceResultEntryResponse>> GetRacesResults(
108129 // early exit if no results
109130 if ( subgroupResults . Entries . Count == 0 )
110131 {
111- return acc ;
132+ return result ;
112133 }
113134
114135 var resultsPortion = subgroupResults . Entries
115- . Where ( x => ridersSet . Contains ( x . ProfileId ) )
136+ . Where ( x => riders . Contains ( x . ProfileId ) )
116137 . ToList ( ) ;
117138
118- acc . AddRange ( resultsPortion ) ;
139+ if ( resultsPortion . Count == 0 )
140+ {
141+ continue ;
142+ }
143+
144+ var key = new ZwiftEventEventSubgroupKey
145+ {
146+ Event = @event ,
147+ Subgroup = zwiftEventSubgroup ,
148+ SubgroupResults = subgroupResults
149+ } ;
150+
151+ result . Add ( key , resultsPortion ) ;
119152 }
120153 }
121154
122- return acc ;
155+ return result ;
156+ }
157+
158+ private record ZwiftEventEventSubgroupKey
159+ {
160+ public required ZwiftEventResponse Event { get ; init ; }
161+ public required ZwiftEventSubgroupResponse Subgroup { get ; init ; }
162+ public required ZwiftRaceResultResponse SubgroupResults { get ; init ; }
123163 }
124164}
125165
126166public sealed record ZwiftFRRTourStageResultsRequest
127167{
128- public required string [ ] Urls { get ; init ; }
168+ public required HashSet < string > Urls { get ; init ; }
129169}
0 commit comments