mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
- Added a visual indication on the UI to tell the admin there is a update available.
- We are now also recording the last scheduled run in the database
This commit is contained in:
parent
af028f0b56
commit
df3dc4ac04
28 changed files with 392 additions and 45 deletions
|
@ -47,5 +47,7 @@ namespace PlexRequests.Core
|
||||||
public const string CouchPotatoQueued = "CouchPotatoQueued";
|
public const string CouchPotatoQueued = "CouchPotatoQueued";
|
||||||
|
|
||||||
public const string GetBaseUrl = "GetBaseUrl";
|
public const string GetBaseUrl = "GetBaseUrl";
|
||||||
|
|
||||||
|
public const string LastestProductVersion = "LatestProductVersion";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -49,10 +49,9 @@ namespace PlexRequests.Core
|
||||||
var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId };
|
var entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId };
|
||||||
var id = Repo.Insert(entity);
|
var id = Repo.Insert(entity);
|
||||||
|
|
||||||
// TODO Keep an eye on this, since we are now doing 2 DB update for 1 single request, inserting and then updating
|
|
||||||
model.Id = (int)id;
|
model.Id = (int)id;
|
||||||
|
|
||||||
entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = (int)id, MusicId = model.MusicBrainzId};
|
entity = new RequestBlobs { Type = model.Type, Content = ByteConverterHelper.ReturnBytes(model), ProviderId = model.ProviderId, Id = (int)id, MusicId = model.MusicBrainzId };
|
||||||
var result = Repo.Update(entity);
|
var result = Repo.Update(entity);
|
||||||
|
|
||||||
return result ? id : -1;
|
return result ? id : -1;
|
||||||
|
|
|
@ -24,21 +24,11 @@
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// ************************************************************************/
|
// ************************************************************************/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace PlexRequests.Core.Models
|
namespace PlexRequests.Core.Models
|
||||||
{
|
{
|
||||||
public class StatusModel
|
public class StatusModel
|
||||||
{
|
{
|
||||||
public string Version { get; set; }
|
public string Version { get; set; }
|
||||||
public int DBVersion {
|
|
||||||
get
|
|
||||||
{
|
|
||||||
string trimStatus = new Regex("[^0-9]", RegexOptions.Compiled).Replace(Version, string.Empty).PadRight(4, '0');
|
|
||||||
return int.Parse(trimStatus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public bool UpdateAvailable { get; set; }
|
public bool UpdateAvailable { get; set; }
|
||||||
public string UpdateUri { get; set; }
|
public string UpdateUri { get; set; }
|
||||||
public string DownloadUri { get; set; }
|
public string DownloadUri { get; set; }
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using Mono.Data.Sqlite;
|
using Mono.Data.Sqlite;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
@ -72,18 +73,19 @@ namespace PlexRequests.Core
|
||||||
|
|
||||||
private int CheckSchema()
|
private int CheckSchema()
|
||||||
{
|
{
|
||||||
var checker = new StatusChecker();
|
var productVersion = AssemblyHelper.GetProductVersion();
|
||||||
var status = checker.GetStatus();
|
var trimStatus = new Regex("[^0-9]", RegexOptions.Compiled).Replace(productVersion, string.Empty).PadRight(4, '0');
|
||||||
|
var version = int.Parse(trimStatus);
|
||||||
|
|
||||||
var connection = Db.DbConnection();
|
var connection = Db.DbConnection();
|
||||||
var schema = connection.GetSchemaVersion();
|
var schema = connection.GetSchemaVersion();
|
||||||
if (schema == null)
|
if (schema == null)
|
||||||
{
|
{
|
||||||
connection.CreateSchema(status.DBVersion); // Set the default.
|
connection.CreateSchema(version); // Set the default.
|
||||||
schema = connection.GetSchemaVersion();
|
schema = connection.GetSchemaVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
var version = schema.SchemaVersion;
|
version = schema.SchemaVersion;
|
||||||
|
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
33
PlexRequests.Services/Interfaces/IJobRecord.cs
Normal file
33
PlexRequests.Services/Interfaces/IJobRecord.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: IJobRecord.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.Services.Interfaces
|
||||||
|
{
|
||||||
|
public interface IJobRecord
|
||||||
|
{
|
||||||
|
void Record(string jobName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,16 +41,18 @@ namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
public class CouchPotatoCacher : IJob, ICouchPotatoCacher
|
public class CouchPotatoCacher : IJob, ICouchPotatoCacher
|
||||||
{
|
{
|
||||||
public CouchPotatoCacher(ISettingsService<CouchPotatoSettings> cpSettings, ICouchPotatoApi cpApi, ICacheProvider cache)
|
public CouchPotatoCacher(ISettingsService<CouchPotatoSettings> cpSettings, ICouchPotatoApi cpApi, ICacheProvider cache, IJobRecord rec)
|
||||||
{
|
{
|
||||||
CpSettings = cpSettings;
|
CpSettings = cpSettings;
|
||||||
CpApi = cpApi;
|
CpApi = cpApi;
|
||||||
Cache = cache;
|
Cache = cache;
|
||||||
|
Job = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<CouchPotatoSettings> CpSettings { get; }
|
private ISettingsService<CouchPotatoSettings> CpSettings { get; }
|
||||||
private ICacheProvider Cache { get; }
|
private ICacheProvider Cache { get; }
|
||||||
private ICouchPotatoApi CpApi { get; }
|
private ICouchPotatoApi CpApi { get; }
|
||||||
|
private IJobRecord Job { get; }
|
||||||
|
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
@ -74,6 +76,10 @@ namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
Log.Error(ex, "Failed caching queued items from CouchPotato");
|
Log.Error(ex, "Failed caching queued items from CouchPotato");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Job.Record(JobNames.CpCacher);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
37
PlexRequests.Services/Jobs/JobNames.cs
Normal file
37
PlexRequests.Services/Jobs/JobNames.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: JobNames.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.Services
|
||||||
|
{
|
||||||
|
public static class JobNames
|
||||||
|
{
|
||||||
|
public const string StoreBackup = "Database Backup";
|
||||||
|
public const string CpCacher = "CouchPotato Cacher";
|
||||||
|
public const string SonarrCacher = "Sonarr Cacher";
|
||||||
|
public const string SrCacher = "SickRage Cacher";
|
||||||
|
public const string PlexChecker = "Plex Availability Cacher";
|
||||||
|
}
|
||||||
|
}
|
59
PlexRequests.Services/Jobs/JobRecord.cs
Normal file
59
PlexRequests.Services/Jobs/JobRecord.cs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: JobRecord.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.Linq;
|
||||||
|
|
||||||
|
using PlexRequests.Services.Interfaces;
|
||||||
|
using PlexRequests.Store.Models;
|
||||||
|
using PlexRequests.Store.Repository;
|
||||||
|
|
||||||
|
namespace PlexRequests.Services
|
||||||
|
{
|
||||||
|
public class JobRecord : IJobRecord
|
||||||
|
{
|
||||||
|
public JobRecord(IRepository<ScheduledJobs> repo)
|
||||||
|
{
|
||||||
|
Repo = repo;
|
||||||
|
}
|
||||||
|
private IRepository<ScheduledJobs> Repo { get; }
|
||||||
|
public void Record(string jobName)
|
||||||
|
{
|
||||||
|
var allJobs = Repo.GetAll();
|
||||||
|
var storeJob = allJobs.FirstOrDefault(x => x.Name == jobName);
|
||||||
|
if (storeJob != null)
|
||||||
|
{
|
||||||
|
storeJob.LastRun = DateTime.UtcNow;
|
||||||
|
Repo.Update(storeJob);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var job = new ScheduledJobs { LastRun = DateTime.UtcNow, Name = jobName };
|
||||||
|
Repo.Insert(job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,7 +47,7 @@ namespace PlexRequests.Services.Jobs
|
||||||
public class PlexAvailabilityChecker : IJob, IAvailabilityChecker
|
public class PlexAvailabilityChecker : IJob, IAvailabilityChecker
|
||||||
{
|
{
|
||||||
public PlexAvailabilityChecker(ISettingsService<PlexSettings> plexSettings, ISettingsService<AuthenticationSettings> auth, IRequestService request, IPlexApi plex, ICacheProvider cache,
|
public PlexAvailabilityChecker(ISettingsService<PlexSettings> plexSettings, ISettingsService<AuthenticationSettings> auth, IRequestService request, IPlexApi plex, ICacheProvider cache,
|
||||||
INotificationService notify)
|
INotificationService notify, IJobRecord rec)
|
||||||
{
|
{
|
||||||
Plex = plexSettings;
|
Plex = plexSettings;
|
||||||
Auth = auth;
|
Auth = auth;
|
||||||
|
@ -55,6 +55,7 @@ namespace PlexRequests.Services.Jobs
|
||||||
PlexApi = plex;
|
PlexApi = plex;
|
||||||
Cache = cache;
|
Cache = cache;
|
||||||
Notification = notify;
|
Notification = notify;
|
||||||
|
Job = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<PlexSettings> Plex { get; }
|
private ISettingsService<PlexSettings> Plex { get; }
|
||||||
|
@ -64,6 +65,7 @@ namespace PlexRequests.Services.Jobs
|
||||||
private IPlexApi PlexApi { get; }
|
private IPlexApi PlexApi { get; }
|
||||||
private ICacheProvider Cache { get; }
|
private ICacheProvider Cache { get; }
|
||||||
private INotificationService Notification { get; }
|
private INotificationService Notification { get; }
|
||||||
|
private IJobRecord Job { get; }
|
||||||
|
|
||||||
public void CheckAndUpdateAll()
|
public void CheckAndUpdateAll()
|
||||||
{
|
{
|
||||||
|
@ -144,6 +146,8 @@ namespace PlexRequests.Services.Jobs
|
||||||
RequestService.BatchUpdate(modifiedModel);
|
RequestService.BatchUpdate(modifiedModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Job.Record(JobNames.PlexChecker);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PlexMovie> GetPlexMovies()
|
public List<PlexMovie> GetPlexMovies()
|
||||||
|
|
|
@ -41,11 +41,12 @@ namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
public class SickRageCacher : IJob, ISickRageCacher
|
public class SickRageCacher : IJob, ISickRageCacher
|
||||||
{
|
{
|
||||||
public SickRageCacher(ISettingsService<SickRageSettings> srSettings, ISickRageApi srApi, ICacheProvider cache)
|
public SickRageCacher(ISettingsService<SickRageSettings> srSettings, ISickRageApi srApi, ICacheProvider cache, IJobRecord rec)
|
||||||
{
|
{
|
||||||
SrSettings = srSettings;
|
SrSettings = srSettings;
|
||||||
SrApi = srApi;
|
SrApi = srApi;
|
||||||
Cache = cache;
|
Cache = cache;
|
||||||
|
Job = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<SickRageSettings> SrSettings { get; }
|
private ISettingsService<SickRageSettings> SrSettings { get; }
|
||||||
|
@ -53,6 +54,7 @@ namespace PlexRequests.Services.Jobs
|
||||||
private ISickRageApi SrApi { get; }
|
private ISickRageApi SrApi { get; }
|
||||||
|
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
private IJobRecord Job { get; }
|
||||||
|
|
||||||
public void Queued()
|
public void Queued()
|
||||||
{
|
{
|
||||||
|
@ -74,6 +76,10 @@ namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
Log.Error(ex, "Failed caching queued items from SickRage");
|
Log.Error(ex, "Failed caching queued items from SickRage");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Job.Record(JobNames.SrCacher);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ using PlexRequests.Core;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
using PlexRequests.Helpers;
|
using PlexRequests.Helpers;
|
||||||
using PlexRequests.Services.Interfaces;
|
using PlexRequests.Services.Interfaces;
|
||||||
|
using PlexRequests.Store.Models;
|
||||||
|
using PlexRequests.Store.Repository;
|
||||||
|
|
||||||
using Quartz;
|
using Quartz;
|
||||||
|
|
||||||
|
@ -42,16 +44,18 @@ namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
public class SonarrCacher : IJob, ISonarrCacher
|
public class SonarrCacher : IJob, ISonarrCacher
|
||||||
{
|
{
|
||||||
public SonarrCacher(ISettingsService<SonarrSettings> sonarrSettings, ISonarrApi sonarrApi, ICacheProvider cache)
|
public SonarrCacher(ISettingsService<SonarrSettings> sonarrSettings, ISonarrApi sonarrApi, ICacheProvider cache, IJobRecord rec)
|
||||||
{
|
{
|
||||||
SonarrSettings = sonarrSettings;
|
SonarrSettings = sonarrSettings;
|
||||||
SonarrApi = sonarrApi;
|
SonarrApi = sonarrApi;
|
||||||
|
Job = rec;
|
||||||
Cache = cache;
|
Cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISettingsService<SonarrSettings> SonarrSettings { get; }
|
private ISettingsService<SonarrSettings> SonarrSettings { get; }
|
||||||
private ICacheProvider Cache { get; }
|
private ICacheProvider Cache { get; }
|
||||||
private ISonarrApi SonarrApi { get; }
|
private ISonarrApi SonarrApi { get; }
|
||||||
|
private IJobRecord Job { get; }
|
||||||
|
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
@ -75,6 +79,10 @@ namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
Log.Error(ex, "Failed caching queued items from Sonarr");
|
Log.Error(ex, "Failed caching queued items from Sonarr");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Job.Record(JobNames.SonarrCacher);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,10 @@ using System.Linq;
|
||||||
|
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
|
using PlexRequests.Services.Interfaces;
|
||||||
using PlexRequests.Store;
|
using PlexRequests.Store;
|
||||||
|
using PlexRequests.Store.Models;
|
||||||
|
using PlexRequests.Store.Repository;
|
||||||
|
|
||||||
using Quartz;
|
using Quartz;
|
||||||
|
|
||||||
|
@ -40,12 +43,14 @@ namespace PlexRequests.Services.Jobs
|
||||||
{
|
{
|
||||||
public class StoreBackup : IJob
|
public class StoreBackup : IJob
|
||||||
{
|
{
|
||||||
public StoreBackup(ISqliteConfiguration sql)
|
public StoreBackup(ISqliteConfiguration sql, IJobRecord rec)
|
||||||
{
|
{
|
||||||
Sql = sql;
|
Sql = sql;
|
||||||
|
JobRecord = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ISqliteConfiguration Sql { get; }
|
private ISqliteConfiguration Sql { get; }
|
||||||
|
private IJobRecord JobRecord { get; }
|
||||||
|
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
@ -82,6 +87,10 @@ namespace PlexRequests.Services.Jobs
|
||||||
Log.Warn(e);
|
Log.Warn(e);
|
||||||
Log.Warn("Exception when trying to copy the backup.");
|
Log.Warn("Exception when trying to copy the backup.");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
JobRecord.Record(JobNames.StoreBackup);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,9 @@
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Interfaces\IJobRecord.cs" />
|
||||||
|
<Compile Include="Jobs\JobRecord.cs" />
|
||||||
|
<Compile Include="Jobs\JobNames.cs" />
|
||||||
<Compile Include="Jobs\StoreBackup.cs" />
|
<Compile Include="Jobs\StoreBackup.cs" />
|
||||||
<Compile Include="Jobs\CouchPotatoCacher.cs" />
|
<Compile Include="Jobs\CouchPotatoCacher.cs" />
|
||||||
<Compile Include="Jobs\PlexAvailabilityChecker.cs" />
|
<Compile Include="Jobs\PlexAvailabilityChecker.cs" />
|
||||||
|
|
39
PlexRequests.Store/Models/ScheduledJobs.cs
Normal file
39
PlexRequests.Store/Models/ScheduledJobs.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: LogEntity.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 Dapper.Contrib.Extensions;
|
||||||
|
|
||||||
|
namespace PlexRequests.Store.Models
|
||||||
|
{
|
||||||
|
[Table("ScheduledJobs")]
|
||||||
|
public class ScheduledJobs : Entity
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public DateTime LastRun { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -63,6 +63,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DbConfiguration.cs" />
|
<Compile Include="DbConfiguration.cs" />
|
||||||
<Compile Include="Entity.cs" />
|
<Compile Include="Entity.cs" />
|
||||||
|
<Compile Include="Models\ScheduledJobs.cs" />
|
||||||
<Compile Include="Repository\IRequestRepository.cs" />
|
<Compile Include="Repository\IRequestRepository.cs" />
|
||||||
<Compile Include="Repository\ISettingsRepository.cs" />
|
<Compile Include="Repository\ISettingsRepository.cs" />
|
||||||
<Compile Include="ISqliteConfiguration.cs" />
|
<Compile Include="ISqliteConfiguration.cs" />
|
||||||
|
|
|
@ -45,5 +45,12 @@ CREATE UNIQUE INDEX IF NOT EXISTS Logs_Id ON Logs (Id);
|
||||||
CREATE TABLE IF NOT EXISTS DBInfo
|
CREATE TABLE IF NOT EXISTS DBInfo
|
||||||
(
|
(
|
||||||
SchemaVersion INTEGER
|
SchemaVersion INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
);
|
CREATE TABLE IF NOT EXISTS ScheduledJobs
|
||||||
|
(
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
Name varchar(100) NOT NULL,
|
||||||
|
LastRun varchar(100) NOT NULL
|
||||||
|
);
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS ScheduledJobs_Id ON ScheduledJobs (Id);
|
|
@ -87,8 +87,10 @@ namespace PlexRequests.UI
|
||||||
|
|
||||||
// Repo's
|
// Repo's
|
||||||
container.Register<IRepository<LogEntity>, GenericRepository<LogEntity>>();
|
container.Register<IRepository<LogEntity>, GenericRepository<LogEntity>>();
|
||||||
|
container.Register<IRepository<ScheduledJobs>, GenericRepository<ScheduledJobs>>();
|
||||||
container.Register<IRequestService, JsonRequestService>();
|
container.Register<IRequestService, JsonRequestService>();
|
||||||
container.Register<ISettingsRepository, SettingsJsonRepository>();
|
container.Register<ISettingsRepository, SettingsJsonRepository>();
|
||||||
|
container.Register<IJobRecord, JobRecord>();
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
container.Register<IAvailabilityChecker, PlexAvailabilityChecker>();
|
container.Register<IAvailabilityChecker, PlexAvailabilityChecker>();
|
||||||
|
|
|
@ -220,3 +220,7 @@ label {
|
||||||
border-radius: 0 0.25rem 0.25rem 0 !important;
|
border-radius: 0 0.25rem 0.25rem 0 !important;
|
||||||
padding: 12px 8px; }
|
padding: 12px 8px; }
|
||||||
|
|
||||||
|
#updateAvailable {
|
||||||
|
background-color: #ffa400;
|
||||||
|
text-align: center; }
|
||||||
|
|
||||||
|
|
2
PlexRequests.UI/Content/custom.min.css
vendored
2
PlexRequests.UI/Content/custom.min.css
vendored
|
@ -1 +1 @@
|
||||||
@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.navbar .nav a .fa,.dropdown-menu a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.dropdown-menu a .fa{top:2px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.scroll-top-wrapper{position:fixed;opacity:0;visibility:hidden;overflow:hidden;text-align:center;z-index:99999999;background-color:#4e5d6c;color:#eee;width:50px;height:48px;line-height:48px;right:30px;bottom:30px;padding-top:2px;border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;}.scroll-top-wrapper:hover{background-color:#637689;}.scroll-top-wrapper.show{visibility:visible;cursor:pointer;opacity:1;}.scroll-top-wrapper i.fa{line-height:inherit;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;}.form-control-search{padding:13px 105px 13px 16px;height:100%;}.form-control-withbuttons{padding-right:105px;}.input-group-addon .btn-group{position:absolute;right:45px;z-index:3;top:13px;box-shadow:0 0 0;}.input-group-addon .btn-group .btn{border:1px solid rgba(255,255,255,.7) !important;padding:3px 12px;color:rgba(255,255,255,.7) !important;}.btn-split .btn{border-radius:0 !important;}.btn-split .btn:not(.dropdown-toggle){border-radius:.25rem 0 0 .25rem !important;}.btn-split .btn.dropdown-toggle{border-radius:0 .25rem .25rem 0 !important;padding:12px 8px;}
|
@media(min-width:768px){.row{position:relative;}.bottom-align-text{position:absolute;bottom:0;right:0;}}@media(max-width:48em){.home{padding-top:1rem;}}@media(min-width:48em){.home{padding-top:4rem;}}.btn{border-radius:.25rem !important;}.multiSelect{background-color:#4e5d6c;}.form-control-custom{background-color:#4e5d6c !important;color:#fff !important;border-radius:0;box-shadow:0 0 0 !important;}h1{font-size:3.5rem !important;font-weight:600 !important;}.request-title{margin-top:0 !important;font-size:1.9rem !important;}p{font-size:1.1rem !important;}label{display:inline-block !important;margin-bottom:.5rem !important;font-size:16px !important;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{background:#4e5d6c;}.navbar .nav a .fa,.dropdown-menu a .fa{font-size:130%;top:1px;position:relative;display:inline-block;margin-right:5px;}.dropdown-menu a .fa{top:2px;}.btn-danger-outline{color:#d9534f !important;background-color:transparent;background-image:none;border-color:#d9534f !important;}.btn-danger-outline:focus,.btn-danger-outline.focus,.btn-danger-outline:active,.btn-danger-outline.active,.btn-danger-outline:hover,.open>.btn-danger-outline.dropdown-toggle{color:#fff !important;background-color:#d9534f !important;border-color:#d9534f !important;}.btn-primary-outline{color:#ff761b !important;background-color:transparent;background-image:none;border-color:#ff761b !important;}.btn-primary-outline:focus,.btn-primary-outline.focus,.btn-primary-outline:active,.btn-primary-outline.active,.btn-primary-outline:hover,.open>.btn-primary-outline.dropdown-toggle{color:#fff !important;background-color:#df691a !important;border-color:#df691a !important;}.btn-info-outline{color:#5bc0de !important;background-color:transparent;background-image:none;border-color:#5bc0de !important;}.btn-info-outline:focus,.btn-info-outline.focus,.btn-info-outline:active,.btn-info-outline.active,.btn-info-outline:hover,.open>.btn-info-outline.dropdown-toggle{color:#fff !important;background-color:#5bc0de !important;border-color:#5bc0de !important;}.btn-warning-outline{color:#f0ad4e !important;background-color:transparent;background-image:none;border-color:#f0ad4e !important;}.btn-warning-outline:focus,.btn-warning-outline.focus,.btn-warning-outline:active,.btn-warning-outline.active,.btn-warning-outline:hover,.open>.btn-warning-outline.dropdown-toggle{color:#fff !important;background-color:#f0ad4e !important;border-color:#f0ad4e !important;}.btn-success-outline{color:#5cb85c !important;background-color:transparent;background-image:none;border-color:#5cb85c !important;}.btn-success-outline:focus,.btn-success-outline.focus,.btn-success-outline:active,.btn-success-outline.active,.btn-success-outline:hover,.open>.btn-success-outline.dropdown-toggle{color:#fff !important;background-color:#5cb85c !important;border-color:#5cb85c !important;}#movieList .mix{display:none;}#tvList .mix{display:none;}.scroll-top-wrapper{position:fixed;opacity:0;visibility:hidden;overflow:hidden;text-align:center;z-index:99999999;background-color:#4e5d6c;color:#eee;width:50px;height:48px;line-height:48px;right:30px;bottom:30px;padding-top:2px;border-top-left-radius:10px;border-top-right-radius:10px;border-bottom-right-radius:10px;border-bottom-left-radius:10px;-webkit-transition:all .5s ease-in-out;-moz-transition:all .5s ease-in-out;-ms-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out;}.scroll-top-wrapper:hover{background-color:#637689;}.scroll-top-wrapper.show{visibility:visible;cursor:pointer;opacity:1;}.scroll-top-wrapper i.fa{line-height:inherit;}.no-search-results{text-align:center;}.no-search-results .no-search-results-icon{font-size:10em;color:#4e5d6c;}.no-search-results .no-search-results-text{margin:20px 0;color:#ccc;}.form-control-search{padding:13px 105px 13px 16px;height:100%;}.form-control-withbuttons{padding-right:105px;}.input-group-addon .btn-group{position:absolute;right:45px;z-index:3;top:13px;box-shadow:0 0 0;}.input-group-addon .btn-group .btn{border:1px solid rgba(255,255,255,.7) !important;padding:3px 12px;color:rgba(255,255,255,.7) !important;}.btn-split .btn{border-radius:0 !important;}.btn-split .btn:not(.dropdown-toggle){border-radius:.25rem 0 0 .25rem !important;}.btn-split .btn.dropdown-toggle{border-radius:0 .25rem .25rem 0 !important;padding:12px 8px;}#updateAvailable{background-color:#ffa400;text-align:center;}
|
|
@ -7,8 +7,7 @@ $warning-colour: #f0ad4e;
|
||||||
$danger-colour: #d9534f;
|
$danger-colour: #d9534f;
|
||||||
$success-colour: #5cb85c;
|
$success-colour: #5cb85c;
|
||||||
$i:
|
$i:
|
||||||
!important
|
!important;
|
||||||
;
|
|
||||||
|
|
||||||
@media (min-width: 768px ) {
|
@media (min-width: 768px ) {
|
||||||
.row {
|
.row {
|
||||||
|
@ -279,4 +278,9 @@ $border-radius: 10px;
|
||||||
.btn-split .btn.dropdown-toggle {
|
.btn-split .btn.dropdown-toggle {
|
||||||
border-radius: 0 .25rem .25rem 0 $i;
|
border-radius: 0 .25rem .25rem 0 $i;
|
||||||
padding: 12px 8px;
|
padding: 12px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#updateAvailable {
|
||||||
|
background-color: rgb(255, 164, 0);
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
|
@ -36,7 +36,7 @@ using Quartz.Spi;
|
||||||
namespace PlexRequests.UI.Jobs
|
namespace PlexRequests.UI.Jobs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The custom job factory we are using so we are able to use our IoC container with DI in our Jobs.
|
/// The custom job factory we are using so we are able to use our IoC container with DI in our JobNames.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="Quartz.Spi.IJobFactory" />
|
/// <seealso cref="Quartz.Spi.IJobFactory" />
|
||||||
public class CustomJobFactory : IJobFactory
|
public class CustomJobFactory : IJobFactory
|
||||||
|
|
33
PlexRequests.UI/Models/JsonUpdateAvailableModel.cs
Normal file
33
PlexRequests.UI/Models/JsonUpdateAvailableModel.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: JsonUpdateAvailableModel.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.UI.Models
|
||||||
|
{
|
||||||
|
public class JsonUpdateAvailableModel
|
||||||
|
{
|
||||||
|
public bool UpdateAvailable { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -295,8 +295,8 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = CpService.SaveSettings(couchPotatoSettings);
|
var result = CpService.SaveSettings(couchPotatoSettings);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for CouchPotato!" }
|
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for CouchPotato!" }
|
||||||
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ namespace PlexRequests.UI.Modules
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
NotificationService.UnSubscribe(new EmailMessageNotification(EmailService));
|
NotificationService.UnSubscribe(new EmailMessageNotification(EmailService));
|
||||||
}
|
}
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = "Successfully sent a test Email Notification!" });
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = "Successfully sent a test Email Notification!" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +464,7 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
var checker = new StatusChecker();
|
var checker = new StatusChecker();
|
||||||
var status = checker.GetStatus();
|
var status = checker.GetStatus();
|
||||||
var md = new Markdown();
|
var md = new Markdown(new MarkdownOptions { AutoNewLines = true });
|
||||||
status.ReleaseNotes = md.Transform(status.ReleaseNotes);
|
status.ReleaseNotes = md.Transform(status.ReleaseNotes);
|
||||||
return View["Status", status];
|
return View["Status", status];
|
||||||
}
|
}
|
||||||
|
@ -623,7 +623,7 @@ namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
JsonSettings.MaxJsonLength = int.MaxValue;
|
JsonSettings.MaxJsonLength = int.MaxValue;
|
||||||
var allLogs = LogsRepo.GetAll().OrderByDescending(x => x.Id).Take(200);
|
var allLogs = LogsRepo.GetAll().OrderByDescending(x => x.Id).Take(200);
|
||||||
var model = new DatatablesModel<LogEntity> {Data = new List<LogEntity>()};
|
var model = new DatatablesModel<LogEntity> { Data = new List<LogEntity>() };
|
||||||
foreach (var l in allLogs)
|
foreach (var l in allLogs)
|
||||||
{
|
{
|
||||||
l.DateString = l.Date.ToString("G");
|
l.DateString = l.Date.ToString("G");
|
||||||
|
@ -650,7 +650,7 @@ namespace PlexRequests.UI.Modules
|
||||||
settings.Level = level;
|
settings.Level = level;
|
||||||
LogService.SaveSettings(settings);
|
LogService.SaveSettings(settings);
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"The new log level is now {newLevel}"});
|
return Response.AsJson(new JsonResponseModel { Result = true, Message = $"The new log level is now {newLevel}" });
|
||||||
}
|
}
|
||||||
|
|
||||||
private Negotiator Headphones()
|
private Negotiator Headphones()
|
||||||
|
@ -673,7 +673,7 @@ namespace PlexRequests.UI.Modules
|
||||||
Log.Trace(settings.DumpJson());
|
Log.Trace(settings.DumpJson());
|
||||||
|
|
||||||
var result = HeadphonesService.SaveSettings(settings);
|
var result = HeadphonesService.SaveSettings(settings);
|
||||||
|
|
||||||
Log.Info("Saved headphones settings, result: {0}", result);
|
Log.Info("Saved headphones settings, result: {0}", result);
|
||||||
return Response.AsJson(result
|
return Response.AsJson(result
|
||||||
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Headphones!" }
|
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Headphones!" }
|
||||||
|
|
|
@ -30,8 +30,11 @@ using Nancy.Extensions;
|
||||||
using PlexRequests.UI.Models;
|
using PlexRequests.UI.Models;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
using Nancy.Security;
|
||||||
|
|
||||||
using PlexRequests.Core;
|
using PlexRequests.Core;
|
||||||
using PlexRequests.Core.SettingModels;
|
using PlexRequests.Core.SettingModels;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
|
||||||
namespace PlexRequests.UI.Modules
|
namespace PlexRequests.UI.Modules
|
||||||
{
|
{
|
||||||
|
@ -52,6 +55,8 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool IsAdmin => Context.CurrentUser.IsAuthenticated();
|
||||||
|
|
||||||
protected int DateTimeOffset
|
protected int DateTimeOffset
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -87,5 +92,7 @@ namespace PlexRequests.UI.Modules
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -124,14 +124,6 @@ namespace PlexRequests.UI.Modules
|
||||||
private IHeadphonesApi HeadphonesApi { get; }
|
private IHeadphonesApi HeadphonesApi { get; }
|
||||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private bool IsAdmin
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Context.CurrentUser.IsAuthenticated();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Negotiator RequestLoad()
|
private Negotiator RequestLoad()
|
||||||
{
|
{
|
||||||
var settings = PrService.GetSettings();
|
var settings = PrService.GetSettings();
|
||||||
|
@ -626,7 +618,7 @@ namespace PlexRequests.UI.Modules
|
||||||
Status = showInfo.status,
|
Status = showInfo.status,
|
||||||
RequestedDate = DateTime.UtcNow,
|
RequestedDate = DateTime.UtcNow,
|
||||||
Approved = false,
|
Approved = false,
|
||||||
RequestedUsers = new List<string>() { Username },
|
RequestedUsers = new List<string> { Username },
|
||||||
Issues = IssueState.None,
|
Issues = IssueState.None,
|
||||||
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
||||||
SeasonCount = showInfo.seasonCount
|
SeasonCount = showInfo.seasonCount
|
||||||
|
@ -802,7 +794,7 @@ namespace PlexRequests.UI.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService);
|
var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService);
|
||||||
sender.AddAlbum(model);
|
sender.AddAlbum(model).Wait();
|
||||||
model.Approved = true;
|
model.Approved = true;
|
||||||
RequestService.AddRequest(model);
|
RequestService.AddRequest(model);
|
||||||
|
|
||||||
|
|
79
PlexRequests.UI/Modules/UpdateCheckerModule.cs
Normal file
79
PlexRequests.UI/Modules/UpdateCheckerModule.cs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#region Copyright
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: UpdateCheckerModule.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 Nancy;
|
||||||
|
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
using PlexRequests.Core;
|
||||||
|
using PlexRequests.Helpers;
|
||||||
|
using PlexRequests.UI.Models;
|
||||||
|
|
||||||
|
namespace PlexRequests.UI.Modules
|
||||||
|
{
|
||||||
|
public class UpdateCheckerModule : BaseAuthModule
|
||||||
|
{
|
||||||
|
public UpdateCheckerModule(ICacheProvider provider) : base("updatechecker")
|
||||||
|
{
|
||||||
|
Cache = provider;
|
||||||
|
|
||||||
|
Get["/"] = _ => CheckLatestVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICacheProvider Cache { get; }
|
||||||
|
|
||||||
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
private Response CheckLatestVersion()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!IsAdmin)
|
||||||
|
{
|
||||||
|
return Response.AsJson(new JsonUpdateAvailableModel { UpdateAvailable = false });
|
||||||
|
}
|
||||||
|
|
||||||
|
var checker = new StatusChecker();
|
||||||
|
var release = Cache.GetOrSet(CacheKeys.LastestProductVersion, () => checker.GetStatus(), 30);
|
||||||
|
|
||||||
|
if (release.UpdateAvailable)
|
||||||
|
{
|
||||||
|
return Response.AsJson(new JsonUpdateAvailableModel { UpdateAvailable = true});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.AsJson(new JsonUpdateAvailableModel { UpdateAvailable = false });
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Warn("Exception Thrown when attempting to check the status");
|
||||||
|
Log.Warn(e);
|
||||||
|
return Response.AsJson(new JsonUpdateAvailableModel { UpdateAvailable = false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -185,12 +185,14 @@
|
||||||
<Compile Include="Jobs\CustomJobFactory.cs" />
|
<Compile Include="Jobs\CustomJobFactory.cs" />
|
||||||
<Compile Include="Jobs\Scheduler.cs" />
|
<Compile Include="Jobs\Scheduler.cs" />
|
||||||
<Compile Include="Models\DatatablesModel.cs" />
|
<Compile Include="Models\DatatablesModel.cs" />
|
||||||
|
<Compile Include="Models\JsonUpdateAvailableModel.cs" />
|
||||||
<Compile Include="Models\MovieSearchType.cs" />
|
<Compile Include="Models\MovieSearchType.cs" />
|
||||||
<Compile Include="Models\QualityModel.cs" />
|
<Compile Include="Models\QualityModel.cs" />
|
||||||
<Compile Include="Models\SearchViewModel.cs" />
|
<Compile Include="Models\SearchViewModel.cs" />
|
||||||
<Compile Include="Models\SearchMusicViewModel.cs" />
|
<Compile Include="Models\SearchMusicViewModel.cs" />
|
||||||
<Compile Include="Models\SearchMovieViewModel.cs" />
|
<Compile Include="Models\SearchMovieViewModel.cs" />
|
||||||
<Compile Include="Modules\BaseModule.cs" />
|
<Compile Include="Modules\BaseModule.cs" />
|
||||||
|
<Compile Include="Modules\UpdateCheckerModule.cs" />
|
||||||
<Compile Include="Start\StartupOptions.cs" />
|
<Compile Include="Start\StartupOptions.cs" />
|
||||||
<Compile Include="Validators\HeadphonesValidator.cs" />
|
<Compile Include="Validators\HeadphonesValidator.cs" />
|
||||||
<Compile Include="Validators\PushoverSettingsValidator.cs" />
|
<Compile Include="Validators\PushoverSettingsValidator.cs" />
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
</button>
|
</button>
|
||||||
<a class="navbar-brand" href="@url/search">Plex Requests</a>
|
<a class="navbar-brand" href="@url/search">Plex Requests</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
@Html.GetNavbarUrl(Context, "/search", "Search", "search")
|
@Html.GetNavbarUrl(Context, "/search", "Search", "search")
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
|
||||||
|
|
||||||
@if (!Context.CurrentUser.IsAuthenticated())
|
@if (!Context.CurrentUser.IsAuthenticated())
|
||||||
{
|
{
|
||||||
<li><a href="@url/login"><i class="fa fa-user"></i> Admin</a></li>
|
<li><a href="@url/login"><i class="fa fa-user"></i> Admin</a></li>
|
||||||
|
@ -66,6 +66,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="updateAvailable" hidden="hidden"></div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@ -82,6 +83,24 @@
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
|
var urlBase = '@Html.GetBaseUrl()';
|
||||||
|
var url = createBaseUrl(urlBase, '/updatechecker');
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (response) {
|
||||||
|
if (response.updateAvailable) {
|
||||||
|
var status = createBaseUrl(urlBase, '/admin/status');
|
||||||
|
$('#updateAvailable').html("There is a new update available! Click <a style='color: white' href='"+status+"'>Here!</a>");
|
||||||
|
$('#updateAvailable').removeAttr("hidden");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$(document).on('scroll', function () {
|
$(document).on('scroll', function () {
|
||||||
|
|
||||||
if ($(window).scrollTop() > 100) {
|
if ($(window).scrollTop() > 100) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue