From 3f0542ae1810116fd39ba3bac5e5368867d14270 Mon Sep 17 00:00:00 2001 From: "chris.watts90@outlook.com" Date: Wed, 28 Feb 2018 20:08:04 +0000 Subject: [PATCH] add functionality for exporting pdf pages and viewing the details page. (needs tidying) migrate history page to knockout bound pages add charts n bits for race details page. --- .../RaceLapTimer/Modules/HistoryModule.cs | 320 ++++++++++++++++-- .../www/Views/HistoricRaceDetails.cshtml | 255 ++++++++++++++ .../www/Views/HistoryIndex.cshtml | 34 +- RaceLapTimer/RaceLapTimer/www/js/Chart.min.js | 14 + .../RaceLapTimer/www/js/raceHistory.js | 10 +- RaceLapTimer/RaceLapTimer/www/js/site.js | 4 + .../RaceLapTimerHost/RaceLapTimerHost.csproj | 9 +- 7 files changed, 601 insertions(+), 45 deletions(-) create mode 100644 RaceLapTimer/RaceLapTimer/www/Views/HistoricRaceDetails.cshtml create mode 100644 RaceLapTimer/RaceLapTimer/www/js/Chart.min.js create mode 100644 RaceLapTimer/RaceLapTimer/www/js/site.js diff --git a/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs b/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs index 64e72ab..de57ceb 100644 --- a/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs +++ b/RaceLapTimer/RaceLapTimer/Modules/HistoryModule.cs @@ -1,7 +1,12 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Dynamic; using System.IO; +using System.Net; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; using Interfaces; using Nancy; using Nancy.Responses; @@ -9,48 +14,315 @@ using Nancy.ViewEngines; namespace RaceLapTimer.Modules { - public class HistoryModule:NancyModule + public class HistoryModule : NancyModule { private IContainerHelper _helper; - public HistoryModule(IContainerHelper helper):base("/history") + private readonly IExportManager _exporter; + private readonly IDocumentPathProvider _docPathProvider; + + public HistoryModule(IContainerHelper helper + , IExportManager exportManager + , IDocumentPathProvider docPathProvider) : base("/history") { _helper = helper; + _exporter = exportManager; + _docPathProvider = docPathProvider; + Get[""] = args => GetHistoryHomePage(); - Get["/pdf/{id}"] = args => GetPdfFile(args); + //make this async + Get["/pdf/{id}"] = (args) => GetPdfFile(args); + Get["/details/{id}"] = args => GetExportPage(args); + } + + private dynamic GetExportPage(dynamic args) + { + var rand = new Random(); + var model = new RaceSessionHistory + { + Title = "testmodel", + RaceMode = RaceMode.COMPETITION, + LapCount = 21 + }; + #region Pilots + var pilot1 = new Pilot + { + Id = 1, + ImageUrl = "/images/pilotPic.png", + Name = "testExportPilotName", + TeamName = "tstEx", + TransponderToken = 66 + }; + var pilot2 = new Pilot + { + Id = 2, + ImageUrl = "/images/pilotPic.png", + Name = "testExportPilot2Name", + TeamName = "tstEx2", + TransponderToken = 68 + }; + var pilot3 = new Pilot + { + Id = 3, + ImageUrl = "/images/pilotPic.png", + Name = "testExportPilot3Name", + TeamName = "tstEx2", + TransponderToken = 65 + }; + var pilot4 = new Pilot + { + Id = 4, + ImageUrl = "/images/pilotPic.png", + Name = "testExportPilot4Name", + TeamName = "tstEx4", + TransponderToken = 14 + }; + var pilot5 = new Pilot + { + Id = 2, + ImageUrl = "/images/pilotPic.png", + Name = "testExportPilot5Name", + TeamName = "tstEx", + TransponderToken = 17 + }; + var pilot6 = new Pilot + { + Id = 2, + ImageUrl = "/images/pilotPic.png", + Name = "testExportPilot6Name", + TeamName = "tstEx3", + TransponderToken = 15 + }; + var pilot7 = new Pilot + { + Id = 2, + ImageUrl = "/images/pilotPic.png", + Name = "testExportPilot7Name", + TeamName = "tstEx2", + TransponderToken = 14 + }; + #endregion + #region laps + model.LapTimes.Add(new RaceLap + { + LapNumber = 1, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 2, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 3, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 4, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 5, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 6, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 7, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 8, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 9, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 10, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 11, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 12, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 13, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 14, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 15, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 16, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 17, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 18, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 19, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 20, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + model.LapTimes.Add(new RaceLap + { + LapNumber = 21, + LapTimeMs = rand.Next(10000,80000), + OverallPositon = 1, + RacerDetails = pilot1 + }); + #endregion + model.Racers.Add(pilot1); + model.Racers.Add(pilot2); + model.Racers.Add(pilot3); + model.Racers.Add(pilot4); + model.Racers.Add(pilot5); + model.Racers.Add(pilot6); + model.Racers.Add(pilot7); + model.FastestPilot = pilot1; + return View["HistoricRaceDetails.cshtml", model]; } private dynamic GetPdfFile(dynamic args) { - var raceSessionId = (int)args.Id; - ViewLocationContext viewLocationContext = new ViewLocationContext() - { - Context = Context, - ModuleName = base.GetType().Name, - ModulePath = ModulePath - }; - var rendered = ViewFactory.RenderView("HistoryIndex.cshtml", null, viewLocationContext); - var content = ""; - using (var ms = new MemoryStream()) - { - rendered.Contents.Invoke(ms); - ms.Seek(0, SeekOrigin.Begin); - using (TextReader reader = new StreamReader(ms)) + #region old + //var raceSessionId = (int)args.Id; + //ViewLocationContext viewLocationContext = new ViewLocationContext() + //{ + // Context = Context, + // ModuleName = base.GetType().Name, + // ModulePath = ModulePath + //}; + //var rendered = ViewFactory.RenderView("HistoryIndex.cshtml", null, viewLocationContext); + //var content = ""; + //using (var ms = new MemoryStream()) + //{ + // rendered.Contents.Invoke(ms); + // ms.Seek(0, SeekOrigin.Begin); + // using (TextReader reader = new StreamReader(ms)) + // { + // content = reader.ReadToEnd(); + // } + //}; + //var filePath = string.Empty; + #endregion + + int raceId = args.id; + string exportType = Request.Query["exporttype"].Value; + var baseUrl = "http://localhost:8800"; + var exportFileName = "RaceSessionExport" + raceId + ".pdf"; + var exportFilePath = Path.Combine(_docPathProvider.GetPath(), exportFileName); + //TODO: replace testHTML with the actual exporthtml page! + var wc = new WebClient(); + var html = wc.DownloadString(string.Format("{0}/history/details/{1}", baseUrl, raceId)); + //Debug.WriteLine(html); + //TBD: check if export is available already + if (!File.Exists(exportFilePath)) { - content = reader.ReadToEnd(); + //if not..create the export + Stream stream; + _exporter.Export(exportType, html, baseUrl, out stream); + //then save it to the export to the documents folder + using (stream) + using (var fs = new FileStream(exportFilePath, FileMode.Create)) + { + stream.Seek(0, SeekOrigin.Begin); + stream.CopyTo(fs); + fs.Flush(true); + } } - }; - var filePath = string.Empty; - throw new NotImplementedException(); - return Response.AsFile(filePath); + //return the file. + var resp = new StreamResponse(() => new FileStream(exportFilePath, FileMode.Open), MimeTypes.GetMimeType(exportFileName)); + return resp.AsAttachment(exportFileName); + //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", model]; } } diff --git a/RaceLapTimer/RaceLapTimer/www/Views/HistoricRaceDetails.cshtml b/RaceLapTimer/RaceLapTimer/www/Views/HistoricRaceDetails.cshtml new file mode 100644 index 0000000..02e29c4 --- /dev/null +++ b/RaceLapTimer/RaceLapTimer/www/Views/HistoricRaceDetails.cshtml @@ -0,0 +1,255 @@ +@using System.Collections.Generic +@using Interfaces +@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@{ + Layout = "razor-layout.cshtml"; +} +

@Model.Title

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Race Title@Model.Title
Lap Count@Model.LapCount
Racer Count@Model.RacerCount
Race Type@Model.RaceType
Fastest Pilot@Model.FastestPilot.NameFastest Lap Time@Model.FastestLapTime
+ + + + + + + + + + + + @foreach (Pilot p in Model.Racers) + { + + + + + + + } + +
Racer NameTeam NameRacer Token IdRacer Image
@p.Name@p.TeamName@p.TransponderTokenPilot Image
+ + + + + + + + + + + + + + + + @foreach (RaceLap lap in Model.LapTimes) + { + + + + + + + + + } + +
Racer NumberRacer NameRacer TeamLap NumberLap TimeLap Position
@lap.RacerDetails.TransponderToken@lap.RacerDetails.Name@lap.RacerDetails.TeamName@lap.LapNumber@lap.LapTimeMs@lap.OverallPositon
+ + + +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml b/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml index 041f18e..38bb2c5 100644 --- a/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml +++ b/RaceLapTimer/RaceLapTimer/www/Views/HistoryIndex.cshtml @@ -26,7 +26,7 @@ standard 5 - +