More work on #298. Everything wired up

pull/332/head
tidusjar 9 years ago
parent 81d26a5442
commit fcf2c84f61

@ -64,6 +64,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

@ -90,6 +90,7 @@
<Compile Include="Tv\TvShowImages.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

@ -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;
}
}

@ -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; }
/// <summary>
/// The CSS name of the theme we want

@ -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
/// <summary>
/// Migrates to version 1.8.
/// <para>This includes updating the admin account to have all roles.</para>
/// <para>Set the log level to info</para>
/// <para>Set the log level to Error</para>
/// <para>Enable Analytics by default</para>
/// </summary>
private void MigrateToVersion1760()
private void MigrateToVersion1800()
{
// Give admin all roles/claims
try
{
var userMapper = new UserMapper(new UserRepository<UsersModel>(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<LogSettings>(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<PlexRequestSettings>(new SettingsJsonRepository(Db, new MemoryCacheProvider()));
var settings = prSettings.GetSettings();
settings.CollectAnalyticData = true;
var updated = prSettings.SaveSettings(settings);
}
catch (Exception e)
{
Log.Error(e);
}
}
}
}

@ -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
}
}

@ -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<string, string> BuildRequestData(HitType type, string username, string category, string action, string label, int? value, string exceptionDescription, int? fatal)
{
var postData = new Dictionary<string, string>
{
{ "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;
}
}
}

@ -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
}
}

@ -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
}
}

@ -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
{
/// <summary>
/// Tracks the event.
/// </summary>
/// <param name="category">The category.</param>
/// <param name="action">The action.</param>
/// <param name="label">The label.</param>
/// <param name="username">The username.</param>
/// <param name="value">The value.</param>
void TrackEvent(Category category, Action action, string label, string username, int? value = null);
/// <summary>
/// Tracks the event asynchronous.
/// </summary>
/// <param name="category">The category.</param>
/// <param name="action">The action.</param>
/// <param name="label">The label.</param>
/// <param name="username">The username.</param>
/// <param name="value">The value.</param>
/// <returns></returns>
Task TrackEventAsync(Category category, Action action, string label, string username, int? value = null);
/// <summary>
/// Tracks the page view.
/// </summary>
/// <param name="category">The category.</param>
/// <param name="action">The action.</param>
/// <param name="label">The label.</param>
/// <param name="username">The username.</param>
/// <param name="value">The value.</param>
void TrackPageview(Category category, Action action, string label, string username, int? value = null);
/// <summary>
/// Tracks the page view asynchronous.
/// </summary>
/// <param name="category">The category.</param>
/// <param name="action">The action.</param>
/// <param name="label">The label.</param>
/// <param name="username">The username.</param>
/// <param name="value">The value.</param>
/// <returns></returns>
Task TrackPageviewAsync(Category category, Action action, string label, string username, int? value = null);
/// <summary>
/// Tracks the exception.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="username">The username.</param>
/// <param name="fatal">if set to <c>true</c> [fatal].</param>
void TrackException(string message, string username, bool fatal);
/// <summary>
/// Tracks the exception asynchronous.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="username">The username.</param>
/// <param name="fatal">if set to <c>true</c> [fatal].</param>
/// <returns></returns>
Task TrackExceptionAsync(string message, string username, bool fatal);
}
}

@ -31,13 +31,26 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Hangfire.Core, Version=1.5.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Hangfire.Core.1.5.7\lib\net45\Hangfire.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Nancy, Version=1.4.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Nancy.1.4.3\lib\net40\Nancy.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.4\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -49,6 +62,11 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Analytics\Action.cs" />
<Compile Include="Analytics\Analytics.cs" />
<Compile Include="Analytics\Category.cs" />
<Compile Include="Analytics\HitType.cs" />
<Compile Include="Analytics\IAnalytics.cs" />
<Compile Include="AssemblyHelper.cs" />
<Compile Include="ByteConverterHelper.cs" />
<Compile Include="DateTimeHelper.cs" />
@ -68,6 +86,7 @@
<Compile Include="UserClaims.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Hangfire.Core" version="1.5.7" targetFramework="net45" />
<package id="Nancy" version="1.4.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net45" />
<package id="NLog" version="4.3.4" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>

@ -91,6 +91,7 @@
<Compile Include="Models\Audit.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="sqlite3.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

@ -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<ISickRageCacher, SickRageCacher>();
container.Register<IJobFactory, CustomJobFactory>();
container.Register<IAnalytics, Analytics>();
// Api
container.Register<ICouchPotatoApi, CouchPotatoApi>();
container.Register<IPushbulletApi, PushbulletApi>();

@ -45,6 +45,7 @@ using System.Windows.Forms;
using CommandLine;
using PlexRequests.Helpers.Analytics;
using PlexRequests.UI.Start;
namespace PlexRequests.UI

@ -26,6 +26,8 @@
#endregion
using System;
using Nancy.Helpers;
using NLog;
using Owin;

@ -87,7 +87,7 @@
<div class="form-group">
<div class='input-group date' id='endDate'>
<input type='text' class="form-control" value="@Model.NoticeStart"/>
<input type='text' class="form-control" value="@Model.NoticeEnd"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
@ -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");

@ -1,11 +1,10 @@

@using PlexRequests.UI.Helpers
@inherits PlexRequests.UI.Helpers.EmptyViewBase<PlexRequests.UI.Models.LandingPageViewModel>
<img class="center" src="~/Content/images/logo.png" width="300" />
<div id="area" class="landing-block">
@if (Model.NoticeEnable)
@if (Model.NoticeEnable && Model.NoticeActive)
{
<div class="row" style="padding-top: 20px">
<div class="col-md-1 col-md-push-3">
@ -13,25 +12,25 @@
</div>
<div class="col-md-5 col-md-push-3">
<span class="landing-title">Notice</span>
<br/>
<br />
@Model.NoticeMessage
<br/>
<strong>6/27/2016 @@ 9:00PM CST to 6/27/2016 @@ 9:00PM CST</strong>
<br />
<strong><span id="startDate"></span> <span id="endDate"></span></strong>
</div>
</div>
<br/>
<br/>
<br/>
<br/>
<br />
<br />
<br />
<br />
}
<div class="row">
<div class="col-md-1 col-md-push-3">
<i class="fa fa-check-circle fa-5x"></i>
<i id="statusIcon" class="fa fa-spinner fa-spin fa-5x fa-fw"></i>
</div>
<div class="col-md-5 col-md-push-3">
<span class="landing-title">Currently Online</span>
<br/>
The Plex server is currently online (check this page for continuous status updates)
<span id="statusTitle" class="landing-title">Loading...</span>
<br />
The Plex server is <strong><span id="statusText">Loading...</span></strong> (check this page for continuous status updates)
</div>
</div>
@ -39,3 +38,45 @@
<div style="text-align: center; margin-top: 10px">
<a href="@Model.ContinueUrl?landing=false" class="btn btn-success-outline">Continue</a>
</div>
<script>
$(function () {
@if (Model.NoticeEnable && Model.NoticeActive)
{
<text>
var start = moment("@Model.NoticeStart.ToString("O")");
var end = moment("@Model.NoticeEnd.ToString("O")");
var text = "for " + start.to(end, true);
$('#startDate').html(start.toString());
$('#endDate').html(text);
</text>
}
var base = "@Html.GetBaseUrl()";
var url = createBaseUrl(base, "landing/status");
$.ajax({
type: "GET",
url: url,
dataType: "json",
success: function (response) {
$('#statusIcon').removeClass("fa-spinner fa-spin fa-fw");
if (response === true) {
//fa fa-check-circle fa-5x
$('#statusIcon').addClass("fa-check-circle");
$('#statusText').text("currently online");
$('#statusTitle').text("Currently Online");
} else {
$('#statusIcon').addClass("fa-times-circle");
$('#statusText').text("currently offline");
$('#statusTitle').text("Currently Offline");
}
},
error: function (e) {
console.log(e);
$('#statusIcon').addClass("fa-times-circle");
}
});
});
</script>
Loading…
Cancel
Save