public void AddRunner(Runner runner)
 {
     lock (dbLock)
     {
         dbRoot.runnerFirstNameIndex.Put(runner.FirstName, runner);
         dbRoot.runnerLastNameIndex.Put(runner.LastName, runner);
         db.Commit();
     }
 }
        /// <summary>
        /// Loads a CSV file containing race entrant information.
        /// </summary>
        public dynamic LoadCsvFile(string filename)
        {
            // ToDo: Long term, make this more configurable. At the moment we're only interested
            //       in Runner's World files.

            dynamic result = new ExpandoObject();
            result.Imported = 0;
            result.AlreadyExisting = 0;
            result.Ignored = 0;

            using (var reader = new StreamReader(File.OpenRead(filename)))
            {
                string line;
                // Count number of lines - can specify which line throws error
                var lineCount = 0;

                // Do process while line is not empty
                while ((line = reader.ReadLine()) != null)
                {
                    lineCount++;

                    // If line throws exception then skip
                    try
                    {
                        // Split line into array of info (\\s* removes space around object)
                        var runnerInfo = SplitCSV( line ).ToArray();

                        var runner = new Runner
                        {
                            FirstName = runnerInfo[0].ToUpper(),
                            LastName = runnerInfo[1].ToUpper(),
                            Gender = ( runnerInfo[2] == "F" ) ? GenderEnum.Female : GenderEnum.Male,
                            DateOfBirth = DateParser.ParseRwDate( runnerInfo[4] ),
                            Club = RemoveUnwantedAttributes( runnerInfo[5] ),
                            Team = RemoveUnwantedAttributes( runnerInfo[6] ),
                            Email = ( runnerInfo.Count() > 15 ) ? RemoveUnwantedAttributes( runnerInfo[15] ) : null,
                            Urn = ( runnerInfo.Count() > 33 ) ? RemoveUnwantedAttributes( runnerInfo[33] ) : null,
                            Number = db.GetNextNumber(),
                        };

                        var addressFields = runnerInfo
                                .Skip( 8 ).Take( 6 )
                                .Where( s => !string.IsNullOrEmpty( s ) ).ToList();

                        if ( addressFields.Any() )
                        {
                            runner.Address = addressFields.Aggregate( ( current, next ) => current + ", " + next );
                        }

                        // If a club is given, then assume the runner is affiliated
                        runner.Affiliated = !string.IsNullOrEmpty( runner.Club );

                        // ToDo: Check for invalid team names - 'NONE' or 'N/A'.

                        // Check that they don't already exist in the DB (use firstname, lastname and DoB)
                        if (!db.TestDuplicate(runner))
                        {
                            db.AddRunner(runner);
                            result.Imported++;
                        }
                        else
                        {
                            result.AlreadyExisting++;
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLineIf( traceSwitch.TraceWarning,
                            string.Format( "Error with line {0}: {1}. Line is '{2} ", lineCount, ex.Message, line ) );
                        result.Ignored++;
                    }
                }
            }
            return result;
        }
Beispiel #3
0
        public ApiModule( ControllerFactory controllerFactory )
            : base("/api")
        {
            Get["/raceinfo"] = parameters =>
            {
                try
                {
                    return Response.AsJson( GetRaceInfo( controllerFactory ) );
                }
                catch ( Exception ex )
                {
                    return Response.AsJson(ex.Message, HttpStatusCode.InternalServerError);
                }
            };

            Get["/runner"] = parameters =>
            {
                var number = Request.Query["number"];
                var runner = GetRunner( controllerFactory, number );
                var statusCode = HttpStatusCode.OK;
                if ( runner == null )
                {
                    statusCode = HttpStatusCode.InternalServerError;
                }
                return Response.AsJson( new {runner = runner}, statusCode);
            };

            Get["/runners"] = parameters => Response.AsJson( GetRunners( controllerFactory ) );

            Get["/results"] = parameters =>
            {
                try
                {
                    var resultsToList = 0;
                    int.TryParse( Request.Query["resultsToList"], out resultsToList );
                    if ( resultsToList == 0 )
                    {
                        resultsToList = int.MaxValue;
                    }
                    return Response.AsJson( GetResults( controllerFactory, resultsToList ) );
                }
                catch ( Exception ex )
                {
                    return HandleException(ex);
                }
            };

            Get["/result"] = parameters =>
            {
                var position = Request.Query["position"];
                var raceResult = GetResult(controllerFactory, position);
                var statusCode = HttpStatusCode.OK;
                if (raceResult == null)
                {
                    statusCode = HttpStatusCode.InternalServerError;
                }
                return Response.AsJson(new { raceResult = raceResult }, statusCode);
            };

            Post["/updateresult"] = ( x ) =>
            {
                var appController = controllerFactory.AppController;
                var message = "";
                var statusCode = HttpStatusCode.OK;

                try
                {
                    var newResult = this.Bind<NewResult>();

                    var result = new Result()
                    {
                        Position = newResult.Position,
                        RaceNumber = newResult.RaceNumber,
                        Time = new TimeSpan( newResult.Hours, newResult.Minutes, newResult.Seconds ),
                    };
                    appController.UpdateResult( result );
                    return Response.AsJson(message, statusCode);
                }
                catch (Exception ex)
                {
                    return HandleException(ex);
                }
            };

            Post["/addresult"] = ( x ) =>
            {
                var appController = controllerFactory.AppController;
                var message = "";
                var statusCode = HttpStatusCode.OK;

                try
                {
                    var newResult = this.Bind<NewResult>();

                    var result = new Result()
                    {
                        Position = newResult.Position,
                        RaceNumber = newResult.RaceNumber,
                        Time = new TimeSpan( newResult.Hours, newResult.Minutes, newResult.Seconds ),
                    };
                    appController.InsertResult( result );

                    return Response.AsJson( message, statusCode );
                }
                catch ( Exception ex )
                {
                    return HandleException( ex );
                }
            };

            Post["/deleteresult"] = ( x ) =>
            {
                var appController = controllerFactory.AppController;
                var message = "";
                var statusCode = HttpStatusCode.OK;

                try
                {
                    var deleteResult = this.Bind<DeleteResult>();

                    // Neither selected
                    if ( !deleteResult.DeleteNumber && !deleteResult.DeleteTime )
                    {
                        throw new Exception("Nothing selected to delete...");
                    }

                    // Both selected
                    if ( deleteResult.DeleteNumber && deleteResult.DeleteTime )
                    {
                        appController.DeleteResultAtPosition( deleteResult.Position );
                    }

                    // Delete just the number - shifting numbers down
                    else if ( deleteResult.DeleteNumber && !deleteResult.DeleteTime )
                    {
                        appController.DeleteRunnerNumberShiftDown(deleteResult.Position);
                    }

                    // Delete the result time, shifting times down
                    else if (!deleteResult.DeleteNumber && deleteResult.DeleteTime)
                    {
                        appController.DeleteTimeShiftDown(deleteResult.Position);
                    }

                    return Response.AsJson(message, statusCode);
                }
                catch (Exception ex)
                {
                    return HandleException( ex );
                }
            };

            Get["/finishers"] = parameters => Response.AsJson( GetFinishers( controllerFactory ) );

            Get["/winners"] = parameters => Response.AsJson( GetWinners( controllerFactory ) );

            Get["/teams"] = parameters => Response.AsJson( GetTeams( controllerFactory ) );

            Post["/addrunner"] = ( x ) =>
            {
                var appController = controllerFactory.AppController;
                var message = "";
                var statusCode = HttpStatusCode.OK;

                try
                {
                    var newRunner = this.Bind<NewRunner>();

                    // Check fields
                    CheckField( newRunner.FirstName, "First Name" );
                    CheckField( newRunner.LastName, "Last Name" );
                    CheckField( newRunner.Gender, "Gender" );
                    CheckField( newRunner.DoB, "DoB" );

                    int number;
                    if ( !int.TryParse( newRunner.Number, out number ) )
                    {
                        throw new Exception( "Race number format is incorrect." );
                    }

                    var runners = appController.GetRunners();
                    if ( runners.Any( r => r.Number == number ) )
                    {
                        throw new Exception("A runner with this number already exists.");
                    }

                    var runner = new Runner
                    {
                        FirstName = newRunner.FirstName,
                        LastName = newRunner.LastName,
                        Gender = ( newRunner.Gender == "F" ) ? GenderEnum.Female : GenderEnum.Male,
                        DateOfBirth = DateTime.Parse( newRunner.DoB ),
                        Email = newRunner.Email,
                        Number = number,
                        Club = newRunner.Club,
                        Team = newRunner.Team,
                        Urn = newRunner.Urn,
                    };
                    runner.ToUpperCase();

                    var db = appController.DbService;
                    if ( !db.TestDuplicate( runner ) )
                    {
                        db.AddRunner( runner );
                        message = string.Format( "'{0}' added to database OK.", runner.ToString() );
                    }
                    else
                    {
                        throw new Exception(string.Format("'{0}' with this DoB already exists in database.", runner.ToString()));
                    }
                    return Response.AsJson( message, statusCode );
                }
                catch ( Exception ex )
                {
                    return HandleException(ex);
                }
            };

            Post["/updaterunner"] = ( x ) =>
            {
                var appController = controllerFactory.AppController;
                var message = "";
                var statusCode = HttpStatusCode.OK;

                try
                {
                    var newRunner = this.Bind<NewRunner>();

                    // Check fields
                    CheckField( newRunner.FirstName, "First Name" );
                    CheckField( newRunner.LastName, "Last Name" );
                    CheckField( newRunner.Gender, "Gender" );
                    CheckField( newRunner.DoB, "DoB" );

                    int number;
                    if ( !int.TryParse( newRunner.Number, out number ) )
                    {
                        throw new Exception( "Race number format is incorrect." );
                    }

                    int newNumber = 0;
                    var haveNewNumber = false;
                    if ( !string.IsNullOrEmpty( newRunner.NewNumber ) )
                    {
                        if ( !int.TryParse( newRunner.NewNumber, out newNumber ) )
                        {
                            throw new Exception( "The format of the new race number is not correct." );
                        }
                        haveNewNumber = true;
                    }

                    // Update
                    var runner = new Runner
                    {
                        Number = number,
                        FirstName = newRunner.FirstName,
                        LastName = newRunner.LastName,
                        Gender = ( newRunner.Gender == "Female" ) ? GenderEnum.Female : GenderEnum.Male,
                        DateOfBirth = DateTime.Parse( newRunner.DoB ),
                        Email = newRunner.Email,
                        Club = newRunner.Club,
                        Team = newRunner.Team,
                        Urn = newRunner.Urn,
                        HaveNewNumber = haveNewNumber,
                        NewNumber = newNumber,
                    };
                    runner.ToUpperCase();

                    appController.DbService.UpdateRunner( runner );

                    return Response.AsJson( message, statusCode );
                }
                catch ( Exception ex )
                {
                    return HandleException( ex );
                }
            };

            Post["/deleterunner"] = ( x ) =>
            {
                var appController = controllerFactory.AppController;
                var message = "";
                var statusCode = HttpStatusCode.OK;

                try
                {
                    var number = this.Bind<RunnerNumber>();

                    appController.DbService.DeleteRunner(number.Number);
                    Trace.WriteLineIf( AppController.traceSwitch.TraceInfo,
                        string.Format( "Runner with number {0} deleted.", number.Number ) );

                    return Response.AsJson( message, statusCode );
                }
                catch ( Exception ex )
                {
                    return HandleException(ex);
                }
            };

            Post["/addfinishposition"] = ( x ) =>
            {
                var appController = controllerFactory.AppController;
                var message = "";
                var statusCode = HttpStatusCode.OK;
                try
                {
                    var posResult = this.Bind<PositionResult>();

                    if ( !appController.IsClockRunning )
                    {
                        throw new Exception( "Race is not in progress (clock not running)." );
                    }

                    if ( posResult.Position <= 0 )
                    {
                        message = "Race number must be > 0";
                        statusCode = HttpStatusCode.BadRequest;
                    }
                    else
                    {
                        appController.AddResultRunnerNumber( posResult.Position );
                        Trace.WriteLineIf( AppController.traceSwitch.TraceInfo, "Runner number added: " + posResult.Position );
                    }
                    return Response.AsJson( message, statusCode );
                }
                catch ( Exception ex )
                {
                    return HandleException( ex );
                }
            };
        }