diff --git a/PlexRequests.Api.Interfaces/PlexRequests.Api.Interfaces.csproj b/PlexRequests.Api.Interfaces/PlexRequests.Api.Interfaces.csproj index 8512ca932..cf321d344 100644 --- a/PlexRequests.Api.Interfaces/PlexRequests.Api.Interfaces.csproj +++ b/PlexRequests.Api.Interfaces/PlexRequests.Api.Interfaces.csproj @@ -64,6 +64,7 @@ + diff --git a/PlexRequests.Api.Interfaces/app.config b/PlexRequests.Api.Interfaces/app.config new file mode 100644 index 000000000..de5386a47 --- /dev/null +++ b/PlexRequests.Api.Interfaces/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj b/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj index 8e670e858..9b0857e44 100644 --- a/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj +++ b/PlexRequests.Api.Models/PlexRequests.Api.Models.csproj @@ -90,6 +90,7 @@ + diff --git a/PlexRequests.Api.Models/app.config b/PlexRequests.Api.Models/app.config new file mode 100644 index 000000000..de5386a47 --- /dev/null +++ b/PlexRequests.Api.Models/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/PlexRequests.Core/SettingModels/LandingPageSettings.cs b/PlexRequests.Core/SettingModels/LandingPageSettings.cs index e3ca5a88e..c765a7bf4 100644 --- a/PlexRequests.Core/SettingModels/LandingPageSettings.cs +++ b/PlexRequests.Core/SettingModels/LandingPageSettings.cs @@ -26,6 +26,8 @@ #endregion using System; +using Newtonsoft.Json; + namespace PlexRequests.Core.SettingModels { public class LandingPageSettings : Settings @@ -37,5 +39,8 @@ namespace PlexRequests.Core.SettingModels public bool EnabledNoticeTime { get; set; } public DateTime NoticeStart { get; set; } public DateTime NoticeEnd { get; set; } + + [JsonIgnore] + public bool NoticeActive => DateTime.Now > NoticeEnd || DateTime.Now < NoticeStart; } } \ No newline at end of file diff --git a/PlexRequests.Core/SettingModels/PlexRequestSettings.cs b/PlexRequests.Core/SettingModels/PlexRequestSettings.cs index 20bf58acd..493d8bf39 100644 --- a/PlexRequests.Core/SettingModels/PlexRequestSettings.cs +++ b/PlexRequests.Core/SettingModels/PlexRequestSettings.cs @@ -44,6 +44,7 @@ namespace PlexRequests.Core.SettingModels public bool UsersCanViewOnlyOwnIssues { get; set; } public int WeeklyRequestLimit { get; set; } public string NoApprovalUsers { get; set; } + public bool CollectAnalyticData { get; set; } /// /// The CSS name of the theme we want diff --git a/PlexRequests.Core/Setup.cs b/PlexRequests.Core/Setup.cs index b01810378..2c015f55c 100644 --- a/PlexRequests.Core/Setup.cs +++ b/PlexRequests.Core/Setup.cs @@ -57,13 +57,13 @@ namespace PlexRequests.Core var version = CheckSchema(); if (version > 0) { - if (version > 1700 && version <= 1759) + if (version > 1700 && version <= 1799) { MigrateToVersion1700(); } - if (version > 1759 && version <= 1799) + if (version > 1799 && version <= 1800) { - MigrateToVersion1760(); + MigrateToVersion1800(); } } @@ -181,10 +181,13 @@ namespace PlexRequests.Core /// /// Migrates to version 1.8. /// This includes updating the admin account to have all roles. - /// Set the log level to info + /// Set the log level to Error + /// Enable Analytics by default /// - private void MigrateToVersion1760() + private void MigrateToVersion1800() { + + // Give admin all roles/claims try { var userMapper = new UserMapper(new UserRepository(Db, new MemoryCacheProvider())); @@ -201,14 +204,15 @@ namespace PlexRequests.Core catch (Exception e) { Log.Error(e); - throw; } + + // Set log level try { var settingsService = new SettingsServiceV2(new SettingsJsonRepository(Db, new MemoryCacheProvider())); var logSettings = settingsService.GetSettings(); - logSettings.Level = LogLevel.Info.Ordinal; + logSettings.Level = LogLevel.Error.Ordinal; settingsService.SaveSettings(logSettings); LoggingHelper.ReconfigureLogLevel(LogLevel.FromOrdinal(logSettings.Level)); @@ -217,10 +221,24 @@ namespace PlexRequests.Core catch (Exception e) { Log.Error(e); - throw; } + // Enable analytics; + try + { + + var prSettings = new SettingsServiceV2(new SettingsJsonRepository(Db, new MemoryCacheProvider())); + var settings = prSettings.GetSettings(); + settings.CollectAnalyticData = true; + var updated = prSettings.SaveSettings(settings); + + } + catch (Exception e) + { + Log.Error(e); + } + } } } diff --git a/PlexRequests.Helpers/Analytics/Action.cs b/PlexRequests.Helpers/Analytics/Action.cs new file mode 100644 index 000000000..39f0f344e --- /dev/null +++ b/PlexRequests.Helpers/Analytics/Action.cs @@ -0,0 +1,33 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: Action.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +namespace PlexRequests.Helpers.Analytics +{ + public enum Action + { + Donate + } +} \ No newline at end of file diff --git a/PlexRequests.Helpers/Analytics/Analytics.cs b/PlexRequests.Helpers/Analytics/Analytics.cs new file mode 100644 index 000000000..6bab0ee58 --- /dev/null +++ b/PlexRequests.Helpers/Analytics/Analytics.cs @@ -0,0 +1,240 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: Analytics.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +using NLog; + +using HttpUtility = Nancy.Helpers.HttpUtility; + +namespace PlexRequests.Helpers.Analytics +{ + public class Analytics : IAnalytics + { + private const string AnalyticsUri = "http://www.google-analytics.com/collect"; + private const string RequestMethod = "POST"; + private const string TrackingId = "UA-77083919-2"; + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + public void TrackEvent(Category category, Action action, string label, string username, int? value = null) + { + var cat = category.ToString(); + var act = action.ToString(); + Track(HitType.@event, username, cat, act, label, value); + } + + public async Task TrackEventAsync(Category category, Action action, string label, string username, int? value = null) + { + var cat = category.ToString(); + var act = action.ToString(); + await TrackAsync(HitType.@event, username, cat, act, label, value); + } + + public void TrackPageview(Category category, Action action, string label, string username, int? value = null) + { + var cat = category.ToString(); + var act = action.ToString(); + Track(HitType.@pageview, username, cat, act, label, value); + } + public async Task TrackPageviewAsync(Category category, Action action, string label, string username, int? value = null) + { + var cat = category.ToString(); + var act = action.ToString(); + await TrackAsync(HitType.@pageview, username, cat, act, label, value); + } + + public void TrackException(string message, string username, bool fatal) + { + var fatalInt = fatal ? 1 : 0; + Track(HitType.exception, message, fatalInt, username); + } + + public async Task TrackExceptionAsync(string message, string username, bool fatal) + { + var fatalInt = fatal ? 1 : 0; + await TrackAsync(HitType.exception, message, fatalInt, username); + } + + private void Track(HitType type, string username, string category, string action, string label, int? value = null) + { + if (string.IsNullOrEmpty(category)) throw new ArgumentNullException(nameof(category)); + if (string.IsNullOrEmpty(action)) throw new ArgumentNullException(nameof(action)); + if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username)); + + var postData = BuildRequestData(type, username, category, action, label, value, null, null); + + var postDataString = postData + .Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}")) + .TrimEnd('&'); + + SendRequest(postDataString); + } + + private async Task TrackAsync(HitType type, string username, string category, string action, string label, int? value = null) + { + if (string.IsNullOrEmpty(category)) throw new ArgumentNullException(nameof(category)); + if (string.IsNullOrEmpty(action)) throw new ArgumentNullException(nameof(action)); + if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username)); + + var postData = BuildRequestData(type, username, category, action, label, value, null, null); + + var postDataString = postData + .Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}")) + .TrimEnd('&'); + + await SendRequestAsync(postDataString); + } + private async Task TrackAsync(HitType type, string message, int fatal, string username) + { + if (string.IsNullOrEmpty(message)) throw new ArgumentNullException(nameof(message)); + if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username)); + + var postData = BuildRequestData(type, username, null, null, null, null, message, fatal); + + var postDataString = postData + .Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}")) + .TrimEnd('&'); + + await SendRequestAsync(postDataString); + } + + private void Track(HitType type, string message, int fatal, string username) + { + if (string.IsNullOrEmpty(message)) throw new ArgumentNullException(nameof(message)); + if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username)); + + var postData = BuildRequestData(type, username, null, null, null, null, message, fatal); + + var postDataString = postData + .Aggregate("", (data, next) => string.Format($"{data}&{next.Key}={HttpUtility.UrlEncode(next.Value)}")) + .TrimEnd('&'); + + SendRequest(postDataString); + } + + private void SendRequest(string postDataString) + { + var request = (HttpWebRequest)WebRequest.Create(AnalyticsUri); + request.Method = RequestMethod; + // set the Content-Length header to the correct value + request.ContentLength = Encoding.UTF8.GetByteCount(postDataString); + + // write the request body to the request + using (var writer = new StreamWriter(request.GetRequestStream())) + { + writer.Write(postDataString); + } + + try + { + var webResponse = (HttpWebResponse)request.GetResponse(); + if (webResponse.StatusCode != HttpStatusCode.OK) + { + throw new HttpException((int)webResponse.StatusCode, "Google Analytics tracking did not return OK 200"); + } + } + catch (Exception ex) + { + Log.Error(ex, "Analytics tracking failed"); + } + } + private async Task SendRequestAsync(string postDataString) + { + var request = (HttpWebRequest)WebRequest.Create(AnalyticsUri); + request.Method = RequestMethod; + // set the Content-Length header to the correct value + request.ContentLength = Encoding.UTF8.GetByteCount(postDataString); + + // write the request body to the request + using (var writer = new StreamWriter(request.GetRequestStream())) + { + await writer.WriteAsync(postDataString); + } + + try + { + var webResponse = (HttpWebResponse)await request.GetResponseAsync(); + if (webResponse.StatusCode != HttpStatusCode.OK) + { + throw new HttpException((int)webResponse.StatusCode, "Google Analytics tracking did not return OK 200"); + } + } + catch (Exception ex) + { + Log.Error(ex, "Analytics tracking failed"); + } + } + + private Dictionary BuildRequestData(HitType type, string username, string category, string action, string label, int? value, string exceptionDescription, int? fatal) + { + var postData = new Dictionary + { + { "v", "1" }, + { "tid", TrackingId }, + { "t", type.ToString() }, + {"cid", "" } + }; + + if (!string.IsNullOrEmpty(username)) + { + postData.Add("uid", username); + } + if (!string.IsNullOrEmpty(label)) + { + postData.Add("el", label); + } + if (value.HasValue) + { + postData.Add("ev", value.ToString()); + } + if (!string.IsNullOrEmpty(category)) + { + postData.Add("ec", category); + } + if (!string.IsNullOrEmpty(action)) + { + postData.Add("ea", action); + } + if (!string.IsNullOrEmpty(exceptionDescription)) + { + postData.Add("exd", exceptionDescription); + } + if (fatal.HasValue) + { + postData.Add("exf", fatal.ToString()); + } + return postData; + } + } +} \ No newline at end of file diff --git a/PlexRequests.Helpers/Analytics/Category.cs b/PlexRequests.Helpers/Analytics/Category.cs new file mode 100644 index 000000000..1a3a2739e --- /dev/null +++ b/PlexRequests.Helpers/Analytics/Category.cs @@ -0,0 +1,40 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: Category.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +namespace PlexRequests.Helpers.Analytics +{ + public enum Category + { + Startup, + Search, + Requests, + Admin, + LandingPage, + Api, + Issues, + UserLogin + } +} \ No newline at end of file diff --git a/PlexRequests.Helpers/Analytics/HitType.cs b/PlexRequests.Helpers/Analytics/HitType.cs new file mode 100644 index 000000000..c3882f96a --- /dev/null +++ b/PlexRequests.Helpers/Analytics/HitType.cs @@ -0,0 +1,36 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: HitType.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +// ReSharper disable InconsistentNaming +namespace PlexRequests.Helpers.Analytics +{ + internal enum HitType + { + @event, + @pageview, + @exception + } +} \ No newline at end of file diff --git a/PlexRequests.Helpers/Analytics/IAnalytics.cs b/PlexRequests.Helpers/Analytics/IAnalytics.cs new file mode 100644 index 000000000..4e228f545 --- /dev/null +++ b/PlexRequests.Helpers/Analytics/IAnalytics.cs @@ -0,0 +1,92 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2016 Jamie Rees +// File: IAnalytics.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion +using System.Threading.Tasks; + +namespace PlexRequests.Helpers.Analytics +{ + public interface IAnalytics + { + /// + /// Tracks the event. + /// + /// The category. + /// The action. + /// The label. + /// The username. + /// The value. + void TrackEvent(Category category, Action action, string label, string username, int? value = null); + + /// + /// Tracks the event asynchronous. + /// + /// The category. + /// The action. + /// The label. + /// The username. + /// The value. + /// + Task TrackEventAsync(Category category, Action action, string label, string username, int? value = null); + + /// + /// Tracks the page view. + /// + /// The category. + /// The action. + /// The label. + /// The username. + /// The value. + void TrackPageview(Category category, Action action, string label, string username, int? value = null); + + /// + /// Tracks the page view asynchronous. + /// + /// The category. + /// The action. + /// The label. + /// The username. + /// The value. + /// + Task TrackPageviewAsync(Category category, Action action, string label, string username, int? value = null); + + /// + /// Tracks the exception. + /// + /// The message. + /// The username. + /// if set to true [fatal]. + void TrackException(string message, string username, bool fatal); + + /// + /// Tracks the exception asynchronous. + /// + /// The message. + /// The username. + /// if set to true [fatal]. + /// + Task TrackExceptionAsync(string message, string username, bool fatal); + } +} \ No newline at end of file diff --git a/PlexRequests.Helpers/PlexRequests.Helpers.csproj b/PlexRequests.Helpers/PlexRequests.Helpers.csproj index 47ebb77b4..aad6aa86a 100644 --- a/PlexRequests.Helpers/PlexRequests.Helpers.csproj +++ b/PlexRequests.Helpers/PlexRequests.Helpers.csproj @@ -31,13 +31,26 @@ 4 + + ..\packages\Hangfire.Core.1.5.7\lib\net45\Hangfire.Core.dll + True + + + ..\packages\Nancy.1.4.3\lib\net40\Nancy.dll + True + ..\packages\NLog.4.3.4\lib\net45\NLog.dll True + + ..\packages\Owin.1.0\lib\net40\Owin.dll + True + + @@ -49,6 +62,11 @@ + + + + + @@ -68,6 +86,7 @@ + diff --git a/PlexRequests.Helpers/app.config b/PlexRequests.Helpers/app.config new file mode 100644 index 000000000..de5386a47 --- /dev/null +++ b/PlexRequests.Helpers/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/PlexRequests.Helpers/packages.config b/PlexRequests.Helpers/packages.config index 150691482..9fa4953ae 100644 --- a/PlexRequests.Helpers/packages.config +++ b/PlexRequests.Helpers/packages.config @@ -1,5 +1,8 @@  + + + \ No newline at end of file diff --git a/PlexRequests.Store/PlexRequests.Store.csproj b/PlexRequests.Store/PlexRequests.Store.csproj index e0d242c88..335ea07db 100644 --- a/PlexRequests.Store/PlexRequests.Store.csproj +++ b/PlexRequests.Store/PlexRequests.Store.csproj @@ -91,6 +91,7 @@ + Always diff --git a/PlexRequests.Store/app.config b/PlexRequests.Store/app.config new file mode 100644 index 000000000..de5386a47 --- /dev/null +++ b/PlexRequests.Store/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/PlexRequests.UI/Bootstrapper.cs b/PlexRequests.UI/Bootstrapper.cs index f9a2083f4..6f6bd7d5e 100644 --- a/PlexRequests.UI/Bootstrapper.cs +++ b/PlexRequests.UI/Bootstrapper.cs @@ -52,6 +52,7 @@ using PlexRequests.Store.Repository; using PlexRequests.UI.Helpers; using Nancy.Json; +using PlexRequests.Helpers.Analytics; using PlexRequests.Services.Jobs; using PlexRequests.UI.Jobs; @@ -100,6 +101,8 @@ namespace PlexRequests.UI container.Register(); container.Register(); + container.Register(); + // Api container.Register(); container.Register(); diff --git a/PlexRequests.UI/Program.cs b/PlexRequests.UI/Program.cs index 1bb0da24c..7cb342bd4 100644 --- a/PlexRequests.UI/Program.cs +++ b/PlexRequests.UI/Program.cs @@ -45,6 +45,7 @@ using System.Windows.Forms; using CommandLine; +using PlexRequests.Helpers.Analytics; using PlexRequests.UI.Start; namespace PlexRequests.UI diff --git a/PlexRequests.UI/Startup.cs b/PlexRequests.UI/Startup.cs index a4a3c81cf..361085a96 100644 --- a/PlexRequests.UI/Startup.cs +++ b/PlexRequests.UI/Startup.cs @@ -26,6 +26,8 @@ #endregion using System; +using Nancy.Helpers; + using NLog; using Owin; diff --git a/PlexRequests.UI/Views/Admin/LandingPage.cshtml b/PlexRequests.UI/Views/Admin/LandingPage.cshtml index dbc81d156..9f6dcec6f 100644 --- a/PlexRequests.UI/Views/Admin/LandingPage.cshtml +++ b/PlexRequests.UI/Views/Admin/LandingPage.cshtml @@ -87,7 +87,7 @@
- + @@ -120,16 +120,16 @@ $('#startDate').data("DateTimePicker").maxDate(e.date); }); - var start = ''; - var end = ''; - if ($startDate.data("DateTimePicker").date()) { - start = $startDate.data("DateTimePicker").date().toISOString(); - } - if ($endDate.data("DateTimePicker").date()) { - end = $endDate.data("DateTimePicker").date().toISOString(); - } - $('#save').click(function (e) { + var start = ''; + var end = ''; + if ($startDate.data("DateTimePicker").date()) { + start = $startDate.data("DateTimePicker").date().toISOString(); + } + if ($endDate.data("DateTimePicker").date()) { + end = $endDate.data("DateTimePicker").date().toISOString(); + } + e.preventDefault(); var $form = $("#mainForm"); diff --git a/PlexRequests.UI/Views/Landing/Index.cshtml b/PlexRequests.UI/Views/Landing/Index.cshtml index 143565a4c..3bf8fa8b2 100644 --- a/PlexRequests.UI/Views/Landing/Index.cshtml +++ b/PlexRequests.UI/Views/Landing/Index.cshtml @@ -1,11 +1,10 @@  +@using PlexRequests.UI.Helpers @inherits PlexRequests.UI.Helpers.EmptyViewBase - -
- @if (Model.NoticeEnable) + @if (Model.NoticeEnable && Model.NoticeActive) {
@@ -13,29 +12,71 @@
Notice -
+
@Model.NoticeMessage -
- 6/27/2016 @@ 9:00PM CST to 6/27/2016 @@ 9:00PM CST +
+
-
-
-
-
+
+
+
+
}
- +
- Currently Online -
- The Plex server is currently online (check this page for continuous status updates) + Loading... +
+ The Plex server is Loading... (check this page for continuous status updates)
\ No newline at end of file +
+ + \ No newline at end of file