diff --git a/RaceLapTimer/Interfaces/ExportProviderDetails.cs b/RaceLapTimer/Interfaces/ExportProviderDetails.cs new file mode 100644 index 0000000..65bfddc --- /dev/null +++ b/RaceLapTimer/Interfaces/ExportProviderDetails.cs @@ -0,0 +1,7 @@ +namespace Interfaces +{ + public class ExportProviderDetails + { + public string Type { get; set; } + } +} \ No newline at end of file diff --git a/RaceLapTimer/Interfaces/IExportManager.cs b/RaceLapTimer/Interfaces/IExportManager.cs new file mode 100644 index 0000000..1a0f8d7 --- /dev/null +++ b/RaceLapTimer/Interfaces/IExportManager.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.IO; + +namespace Interfaces +{ + public interface IExportManager + { + List GetExporters(); + + Stream Export(string fileContent, string baseUrl); + + List GetExporterDetails(); + } +} diff --git a/RaceLapTimer/Interfaces/IFileExporter.cs b/RaceLapTimer/Interfaces/IFileExporter.cs new file mode 100644 index 0000000..8b017ae --- /dev/null +++ b/RaceLapTimer/Interfaces/IFileExporter.cs @@ -0,0 +1,11 @@ +using System.IO; + +namespace Interfaces +{ + public interface IFileExporter + { + Stream Export(string fileContent, string baseUrl); + + ExportProviderDetails GetDetails(); + } +} diff --git a/RaceLapTimer/Interfaces/Interfaces.csproj b/RaceLapTimer/Interfaces/Interfaces.csproj index c8ac22f..07646dd 100644 --- a/RaceLapTimer/Interfaces/Interfaces.csproj +++ b/RaceLapTimer/Interfaces/Interfaces.csproj @@ -40,10 +40,13 @@ + + + diff --git a/RaceLapTimer/Interfaces/RaceSession.cs b/RaceLapTimer/Interfaces/RaceSession.cs index 0b5e946..dc2a5f8 100644 --- a/RaceLapTimer/Interfaces/RaceSession.cs +++ b/RaceLapTimer/Interfaces/RaceSession.cs @@ -16,5 +16,8 @@ namespace Interfaces public int TimePenaltyPerSatellite { get; set; } public bool HotSeatEnabled { get; set; } public int IdleTimeSeconds { get; set; } + public double FastestLap { get; set; } + public int FastestPilotId { get; set; } + public string FastestPilotName { get; set; } } } diff --git a/RaceLapTimer/Interfaces/SatelliteLog.cs b/RaceLapTimer/Interfaces/SatelliteLog.cs index 7c435f8..241d709 100644 --- a/RaceLapTimer/Interfaces/SatelliteLog.cs +++ b/RaceLapTimer/Interfaces/SatelliteLog.cs @@ -2,7 +2,9 @@ { public class SatelliteLog { + public int RaceSessionId { get; set; } public int TransponderToken { get; set; } public int LapTimeMs { get; set; } + public int UserId { get; set; } } } \ No newline at end of file diff --git a/RaceLapTimer/RaceLapTimer/ApiControllers/SatelliteApiModule.cs b/RaceLapTimer/RaceLapTimer/ApiControllers/SatelliteApiModule.cs index f9a26b4..4e396e7 100644 --- a/RaceLapTimer/RaceLapTimer/ApiControllers/SatelliteApiModule.cs +++ b/RaceLapTimer/RaceLapTimer/ApiControllers/SatelliteApiModule.cs @@ -7,10 +7,12 @@ namespace RaceLapTimer.ApiControllers public class SatelliteApiModule:NancyModule { private readonly IDbProvider _provider; - public SatelliteApiModule(IDbProvider provider) : base("/api/satellite") + private readonly ILoggerService _logger; + + public SatelliteApiModule(IDbProvider provider, ILoggerService logger) : base("/api/v1/satellite") { _provider = provider; - + _logger = logger; Get[""] = args => LogNewLapSatelliteTime(); } @@ -23,6 +25,7 @@ namespace RaceLapTimer.ApiControllers TransponderToken = transponderToken, LapTimeMs = lapTimeMs }; + _logger.Trace("New Lap Time for Transponder Token: {0}. Lap Time: {1}", transponderToken, lapTimeMs); _provider.StoreTransponderLog(logObj); return HttpStatusCode.OK; } diff --git a/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs b/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs index d159351..da73ca1 100644 --- a/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs +++ b/RaceLapTimer/RaceLapTimer/AuthenticationBootstrapper.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Collections.Generic; +using System.IO; using Interfaces; using Nancy; using Nancy.Authentication.Forms; @@ -6,8 +7,10 @@ using Nancy.Bootstrapper; using Nancy.Bootstrappers.Ninject; using Nancy.Conventions; using Nancy.Diagnostics; +using Nancy.ViewEngines.Razor; using Ninject; using RaceLapTimer.Extensions; +using RaceLapTimer.Extensions.FileExport; using RaceLapTimer.Extensions.Notifications; using RaceLapTimer.Extensions.SystemControl; using RaceLapTimer.Extensions.TransponderUtilities; @@ -41,8 +44,22 @@ namespace RaceLapTimer container.Bind().To().InSingletonScope(); container.Bind().To().InSingletonScope(); - var tu = container.Get(); - var id = tu.GetLastScannedId(); + //unused code, trying to get a friggin html to pdf converter working well. :( + container.Bind().To().InSingletonScope(); + + //var testHtml = "\"Syncfusion_logo\"

Hello World

"; + //var tu = container.Get(); + //var id = tu.Export(testHtml, "http://localhost:8800"); + //File.Delete("testpdf.pdf"); + //using (FileStream fs = new FileStream("testpdf.pdf", FileMode.CreateNew)) + //{ + // id.Seek(0, SeekOrigin.Begin); + // id.CopyTo(fs); + // id.Close(); + // id.Dispose(); + // fs.Flush(true); + // fs.Close(); + //} } protected override void ConfigureRequestContainer(IKernel container, NancyContext context) @@ -98,4 +115,21 @@ namespace RaceLapTimer ); } } + public class RazorConfig : IRazorConfiguration + { + public IEnumerable GetAssemblyNames() + { + yield return "Interfaces"; + } + + public IEnumerable GetDefaultNamespaces() + { + yield return "Interfaces"; + } + + public bool AutoIncludeModelNamespace + { + get { return true; } + } + } } diff --git a/RaceLapTimer/RaceLapTimer/Extensions/FileExport/FileExportManager.cs b/RaceLapTimer/RaceLapTimer/Extensions/FileExport/FileExportManager.cs new file mode 100644 index 0000000..b848860 --- /dev/null +++ b/RaceLapTimer/RaceLapTimer/Extensions/FileExport/FileExportManager.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Interfaces; + +namespace RaceLapTimer.Extensions.FileExport +{ + class FileExportManager:IExportManager + { + private readonly List _exporters; + + public FileExportManager(IPluginLocator locator) + { + _exporters = locator.Locate(); + } + + public List GetExporters() + { + return _exporters; + } + + public Stream Export(string fileContent, string baseUrl) + { + if(_exporters.Any()) + return _exporters.First().Export(fileContent, baseUrl); + return new MemoryStream(); + } + + public List GetExporterDetails() + { + var ret = new List(); + foreach (var exporter in _exporters) + { + ret.Add(exporter.GetDetails()); + } + return ret; + } + } +} diff --git a/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs b/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs index 3a1a9cc..64e72ab 100644 --- a/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs +++ b/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs @@ -1,15 +1,20 @@ using System; +using System.Collections.Generic; using System.Dynamic; using System.IO; +using Interfaces; using Nancy; +using Nancy.Responses; using Nancy.ViewEngines; namespace RaceLapTimer.Modules { public class HistoryModule:NancyModule { - public HistoryModule():base("/history") + private IContainerHelper _helper; + public HistoryModule(IContainerHelper helper):base("/history") { + _helper = helper; Get[""] = args => GetHistoryHomePage(); Get["/pdf/{id}"] = args => GetPdfFile(args); } @@ -34,14 +39,19 @@ namespace RaceLapTimer.Modules content = reader.ReadToEnd(); } }; + var filePath = string.Empty; throw new NotImplementedException(); + return Response.AsFile(filePath); } private dynamic GetHistoryHomePage() { + dynamic model = new ExpandoObject(); + var eM = _helper.Get(); + model.ExportTypes = eM.GetExporterDetails();//new List {new ExportProviderDetails {Type="PDF"} }; - return View["HistoryIndex.cshtml"]; + return View["HistoryIndex.cshtml", model]; } } } diff --git a/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj b/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj index 6785be2..946a220 100644 --- a/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj +++ b/RaceLapTimer/RaceLapTimer/RaceLapTimer.csproj @@ -114,6 +114,7 @@
+ diff --git a/RaceLapTimer/RaceLapTimer/TestProvider.cs b/RaceLapTimer/RaceLapTimer/TestProvider.cs index 7f49f6b..2ef1edc 100644 --- a/RaceLapTimer/RaceLapTimer/TestProvider.cs +++ b/RaceLapTimer/RaceLapTimer/TestProvider.cs @@ -9,6 +9,7 @@ namespace RaceLapTimer { private readonly List _pilots; private readonly List _sessions; + private readonly List _transponderLogs; public TestProvider() { @@ -55,7 +56,7 @@ namespace RaceLapTimer #region Session 2 new RaceSession { - Active = true, + Active = false, CreatedAt = DateTime.UtcNow, HotSeatEnabled = false, Id = 2, @@ -100,20 +101,21 @@ namespace RaceLapTimer #region Session 5 new RaceSession { - Active = false, - CreatedAt = DateTime.UtcNow, - HotSeatEnabled = false, - Id = 4, - IdleTimeSeconds = 400, - Mode = RaceMode.STANDARD, - MaxLaps = 10, - SatelliteCount = 1, - TimePenaltyPerSatellite = 100, - Title = "TEST Session 4" - } + Active = false, + CreatedAt = DateTime.UtcNow, + HotSeatEnabled = false, + Id = 4, + IdleTimeSeconds = 400, + Mode = RaceMode.STANDARD, + MaxLaps = 10, + SatelliteCount = 1, + TimePenaltyPerSatellite = 100, + Title = "TEST Session 4" + } #endregion }; #endregion + _transponderLogs = new List(); } public List GetRaceSessions(bool getActive) @@ -121,6 +123,11 @@ namespace RaceLapTimer return getActive ? _sessions.Where(x => x.Active == getActive).ToList() : _sessions; } + public RaceSession GetRaceSession(int id) + { + return _sessions.FirstOrDefault(x => x.Id == id); + } + public bool CreateRaceSession(RaceSession session) { _sessions.Add(session); @@ -209,7 +216,39 @@ namespace RaceLapTimer public void StoreTransponderLog(SatelliteLog log) { - //do nothing. + var sessionId = GetCurrentRaceSessionId(); + var session = GetRaceSession(sessionId); + log.RaceSessionId = sessionId; + //Store the log.. + _transponderLogs.Add(log); + // check fastest pilot! + var fastestLapTime = GetFastestLapTimeMs(sessionId); + var user = GetUserByTransponder(fastestLapTime.TransponderToken); + session.FastestLap = fastestLapTime.LapTimeMs; + session.FastestPilotId = user.Id; + session.FastestPilotName = user.Name; + } + + private SatelliteLog GetFastestLapTimeMs(int sessionId) + { + var sessionLogs = _transponderLogs.Where(x => x.RaceSessionId == sessionId); + sessionLogs = sessionLogs.OrderByDescending(x => x.LapTimeMs); + var fastestLog = sessionLogs.First(); + return fastestLog; + } + + private int GetCurrentRaceSessionId() + { + var activeSessions = _sessions.Where(x => x.Active).ToList(); + if (activeSessions.Any() || activeSessions.Count > 1) + return -1; //either dont have any, or have more than 1!!! + var session = activeSessions.First(); + return session.Id; + } + + private Pilot GetUserByTransponder(int token) + { + return _pilots.FirstOrDefault(x => x.TransponderToken == token); } } } \ No newline at end of file diff --git a/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml b/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml index 31824ad..9816a1b 100644 --- a/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml +++ b/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml @@ -1,10 +1,11 @@ -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase + +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase @{ Layout = "razor-layout.cshtml"; ViewBag.Title = "History"; }

@ViewBag.Title

- + @@ -23,10 +24,28 @@ - + - - + + diff --git a/RaceLapTimer/RaceLapTimer/www/js/RaceSessionObject.js b/RaceLapTimer/RaceLapTimer/www/js/RaceSessionObject.js index 5c557ff..82286c5 100644 --- a/RaceLapTimer/RaceLapTimer/www/js/RaceSessionObject.js +++ b/RaceLapTimer/RaceLapTimer/www/js/RaceSessionObject.js @@ -15,4 +15,7 @@ self.timePenaltyPerSatellite = ko.observable(data.timePenaltyPerSatellite); self.hotSeatEnabled = ko.observable(data.hotSeatEnabled); self.idleTimeSeconds = ko.observable(data.idleTimeSeconds); + self.fastestLap = ko.observable(data.fastestLap); + self.fastestPilotName = ko.observable(data.fastestPilotName); + self.fastestPilotId = ko.observable(data.fastestPilotId); } \ No newline at end of file diff --git a/RaceLapTimer/RaceLapTimer/www/js/raceHistory.js b/RaceLapTimer/RaceLapTimer/www/js/raceHistory.js index e546a87..4d79fbc 100644 --- a/RaceLapTimer/RaceLapTimer/www/js/raceHistory.js +++ b/RaceLapTimer/RaceLapTimer/www/js/raceHistory.js @@ -15,6 +15,10 @@ }); self.toggleIcon = function(e) { $(e).toggleClass("glyphicon-plus glyphicon-minus"); - } + }; + self.CreateExport = function(sessionId, exportType) { + console.log(sessionId); + console.log(exportType); + }; }; ko.applyBindings(new ViewModel()); \ No newline at end of file diff --git a/RaceLapTimer/RaceLapTimerHost/RaceLapTimerHost.csproj b/RaceLapTimer/RaceLapTimerHost/RaceLapTimerHost.csproj index 5132c59..f832b65 100644 --- a/RaceLapTimer/RaceLapTimerHost/RaceLapTimerHost.csproj +++ b/RaceLapTimer/RaceLapTimerHost/RaceLapTimerHost.csproj @@ -93,7 +93,13 @@ copy /B /Y "$(SolutionDir)UdpNotifier\$(OutDir)UdpNotifier.dll" "$(TargetDir)Plugins\UdpNotifier.dll" copy /B /Y "$(SolutionDir)IrDaemonNotifier\$(OutDir)IrDaemonNotifier.dll" "$(TargetDir)Plugins\IrDaemonNotifier.dll" copy /B /Y "$(TargetDir)NLogConfig.xml" "$(TargetDir)Configs\NLogConfig.xml" -copy /B /Y "$(SolutionDir)RaceLapTimer\$(OutDir)Ninject.Extensions.Xml.dll" "$(TargetDir)Ninject.Extensions.Xml.dll" +copy /B /Y "$(SolutionDir)RaceLapTimer\$(OutDir)Ninject.Extensions.Xml.dll" "$(TargetDir)Ninject.Extensions.Xml.dll" +copy /B /Y "$(SolutionDir)PDFExporter\$(OutDir)PDFExporter.dll" "$(TargetDir)Plugins\PDFExporter.dll" +copy /B /Y "$(SolutionDir)PDFExporter\$(OutDir).dll" "$(TargetDir)Plugins\PDFExporter.dll" +copy /B /Y "$(SolutionDir)PDFExporter\$(OutDir)Syncfusion.HtmlConverter.Base.dll" "$(TargetDir)Syncfusion.HtmlConverter.Base.dll" +copy /B /Y "$(SolutionDir)PDFExporter\$(OutDir)Syncfusion.Pdf.Base.dll" "$(TargetDir)Syncfusion.Pdf.Base.dll" +copy /B /Y "$(SolutionDir)PDFExporter\$(OutDir)Syncfusion.Compression.Base.dll" "$(TargetDir)Syncfusion.Compression.Base.dll" +copy /B /Y "$(SolutionDir)PDFExporter\$(OutDir)Microsoft.mshtml.dll" "$(TargetDir)Microsoft.mshtml.dll"
Race Name 1 standard55 - +
+ + @if (Model.ExportTypes != null) + { + + } +
@@ -48,8 +67,8 @@
1230.0sa pilot30.0sa pilot 35.0s