1+ using FLRC . Leaderboards . Core . Data ;
2+ using FLRC . Leaderboards . Data . Models ;
3+ using FLRC . Leaderboards . Web . Areas . Admin . Services ;
4+ using FLRC . Leaderboards . Web . Areas . Admin . ViewModels ;
5+ using Microsoft . AspNetCore . Mvc ;
6+
7+ namespace FLRC . Leaderboards . Web . Areas . Admin . Controllers ;
8+
9+ [ Area ( "Admin" ) ]
10+ public sealed class ResultsController ( IAthleteService athleteService , ICourseService courseService , IRaceService raceService , IResultService resultService , IDictionary < string , IResultsAPI > resultsAPI ) : Controller
11+ {
12+ private static readonly DateOnly UnknownDOB = new ( ) ;
13+ private const char UnknownCategory = ' ' ;
14+
15+ public async Task < ViewResult > Index ( Guid id )
16+ {
17+ var results = await resultService . Find ( id ) ;
18+ var vm = new ViewModel < Result [ ] > ( "Course Results" , results ) ;
19+ return View ( vm ) ;
20+ }
21+
22+ [ HttpGet ]
23+ public async Task < ViewResult > Import ( )
24+ {
25+ var races = await raceService . GetAllRaces ( ) ;
26+ var form = new ResultImportForm
27+ {
28+ Races = races ,
29+ Sources = resultsAPI . Keys . ToArray ( )
30+ } ;
31+ var vm = new ViewModel < ResultImportForm > ( "Results Importer" , form ) ;
32+ return View ( vm ) ;
33+ }
34+
35+ [ HttpPost ]
36+ public async Task < RedirectToActionResult > Import ( Guid courseID , string source , uint externalID )
37+ {
38+ var importer = resultsAPI [ source ] ;
39+ var response = importer . GetResults ( externalID ) ;
40+
41+ var legacyResults = importer . Source . ParseCourse ( null , await response , null ) ;
42+ var results = await ConvertLegacyResults ( courseID , source , legacyResults ) ;
43+
44+ await resultService . Import ( results ) ;
45+ return RedirectToAction ( nameof ( Index ) , courseID ) ;
46+ }
47+
48+ private async Task < Result [ ] > ConvertLegacyResults ( Guid courseID , string source , Core . Results . Result [ ] legacyResults )
49+ {
50+ var results = new List < Result > ( ) ;
51+ foreach ( var legacyResult in legacyResults . Where ( r => r . Duration is not null ) )
52+ {
53+ var result = await ConvertLegacyResult ( courseID , source , legacyResult ) ;
54+ results . Add ( result ) ;
55+ }
56+
57+ return results . ToArray ( ) ;
58+ }
59+
60+ private async Task < Result > ConvertLegacyResult ( Guid courseID , string source , Core . Results . Result result )
61+ {
62+ var athlete = await athleteService . Find ( source , result . Athlete . ID . ToString ( ) ) ;
63+ if ( athlete is null && result . Athlete . DateOfBirth . HasValue )
64+ athlete = await athleteService . Find ( result . Athlete . Name , DateOnly . FromDateTime ( result . Athlete . DateOfBirth . Value ) ) ;
65+
66+ var newAthlete = ConvertLegacyAthlete ( source , result . Athlete ) ;
67+ if ( athlete is null )
68+ {
69+ athlete = newAthlete ;
70+ await athleteService . AddAthlete ( athlete ) ;
71+ }
72+
73+ if ( ( athlete . DateOfBirth == UnknownDOB && newAthlete . DateOfBirth != UnknownDOB )
74+ || ( athlete . Category == UnknownCategory && newAthlete . Category != UnknownCategory ) )
75+ await athleteService . UpdateAthlete ( athlete , newAthlete ) ;
76+
77+ return new Result
78+ {
79+ ID = Guid . NewGuid ( ) ,
80+ AthleteID = athlete . ID ,
81+ CourseID = courseID ,
82+ StartTime = result . StartTime . Value . ToUniversalTime ( ) ,
83+ Duration = result . Duration . Value
84+ } ;
85+ }
86+
87+ private static Athlete ConvertLegacyAthlete ( string source , Core . Athletes . Athlete athlete )
88+ => new ( )
89+ {
90+ ID = Guid . NewGuid ( ) ,
91+ Name = athlete . Name ,
92+ DateOfBirth = athlete . DateOfBirth . HasValue ? DateOnly . FromDateTime ( athlete . DateOfBirth . Value ) : UnknownDOB ,
93+ Category = athlete . Category ? . Display [ 0 ] ?? UnknownCategory ,
94+ IsPrivate = athlete . Private ,
95+ LinkedAccounts = [ new LinkedAccount { ID = Guid . NewGuid ( ) , Type = source , Value = athlete . ID . ToString ( ) } ]
96+ } ;
97+ }
0 commit comments