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 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 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;
|
||||
|
||||
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);
|
||||
|
||||
return result ? id : -1;
|
||||
|
|
|
@ -24,21 +24,11 @@
|
|||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace PlexRequests.Core.Models
|
||||
{
|
||||
public class StatusModel
|
||||
{
|
||||
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 string UpdateUri { get; set; }
|
||||
public string DownloadUri { get; set; }
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using Mono.Data.Sqlite;
|
||||
using NLog;
|
||||
|
@ -72,18 +73,19 @@ namespace PlexRequests.Core
|
|||
|
||||
private int CheckSchema()
|
||||
{
|
||||
var checker = new StatusChecker();
|
||||
var status = checker.GetStatus();
|
||||
var productVersion = AssemblyHelper.GetProductVersion();
|
||||
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 schema = connection.GetSchemaVersion();
|
||||
if (schema == null)
|
||||
{
|
||||
connection.CreateSchema(status.DBVersion); // Set the default.
|
||||
connection.CreateSchema(version); // Set the default.
|
||||
schema = connection.GetSchemaVersion();
|
||||
}
|
||||
|
||||
var version = schema.SchemaVersion;
|
||||
version = schema.SchemaVersion;
|
||||
|
||||
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 CouchPotatoCacher(ISettingsService<CouchPotatoSettings> cpSettings, ICouchPotatoApi cpApi, ICacheProvider cache)
|
||||
public CouchPotatoCacher(ISettingsService<CouchPotatoSettings> cpSettings, ICouchPotatoApi cpApi, ICacheProvider cache, IJobRecord rec)
|
||||
{
|
||||
CpSettings = cpSettings;
|
||||
CpApi = cpApi;
|
||||
Cache = cache;
|
||||
Job = rec;
|
||||
}
|
||||
|
||||
private ISettingsService<CouchPotatoSettings> CpSettings { get; }
|
||||
private ICacheProvider Cache { get; }
|
||||
private ICouchPotatoApi CpApi { get; }
|
||||
private IJobRecord Job { get; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
@ -74,6 +76,10 @@ namespace PlexRequests.Services.Jobs
|
|||
{
|
||||
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 PlexAvailabilityChecker(ISettingsService<PlexSettings> plexSettings, ISettingsService<AuthenticationSettings> auth, IRequestService request, IPlexApi plex, ICacheProvider cache,
|
||||
INotificationService notify)
|
||||
INotificationService notify, IJobRecord rec)
|
||||
{
|
||||
Plex = plexSettings;
|
||||
Auth = auth;
|
||||
|
@ -55,6 +55,7 @@ namespace PlexRequests.Services.Jobs
|
|||
PlexApi = plex;
|
||||
Cache = cache;
|
||||
Notification = notify;
|
||||
Job = rec;
|
||||
}
|
||||
|
||||
private ISettingsService<PlexSettings> Plex { get; }
|
||||
|
@ -64,6 +65,7 @@ namespace PlexRequests.Services.Jobs
|
|||
private IPlexApi PlexApi { get; }
|
||||
private ICacheProvider Cache { get; }
|
||||
private INotificationService Notification { get; }
|
||||
private IJobRecord Job { get; }
|
||||
|
||||
public void CheckAndUpdateAll()
|
||||
{
|
||||
|
@ -144,6 +146,8 @@ namespace PlexRequests.Services.Jobs
|
|||
RequestService.BatchUpdate(modifiedModel);
|
||||
}
|
||||
|
||||
Job.Record(JobNames.PlexChecker);
|
||||
|
||||
}
|
||||
|
||||
public List<PlexMovie> GetPlexMovies()
|
||||
|
|
|
@ -41,11 +41,12 @@ namespace PlexRequests.Services.Jobs
|
|||
{
|
||||
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;
|
||||
SrApi = srApi;
|
||||
Cache = cache;
|
||||
Job = rec;
|
||||
}
|
||||
|
||||
private ISettingsService<SickRageSettings> SrSettings { get; }
|
||||
|
@ -53,6 +54,7 @@ namespace PlexRequests.Services.Jobs
|
|||
private ISickRageApi SrApi { get; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
private IJobRecord Job { get; }
|
||||
|
||||
public void Queued()
|
||||
{
|
||||
|
@ -74,6 +76,10 @@ namespace PlexRequests.Services.Jobs
|
|||
{
|
||||
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.Helpers;
|
||||
using PlexRequests.Services.Interfaces;
|
||||
using PlexRequests.Store.Models;
|
||||
using PlexRequests.Store.Repository;
|
||||
|
||||
using Quartz;
|
||||
|
||||
|
@ -42,16 +44,18 @@ namespace PlexRequests.Services.Jobs
|
|||
{
|
||||
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;
|
||||
SonarrApi = sonarrApi;
|
||||
Job = rec;
|
||||
Cache = cache;
|
||||
}
|
||||
|
||||
private ISettingsService<SonarrSettings> SonarrSettings { get; }
|
||||
private ICacheProvider Cache { get; }
|
||||
private ISonarrApi SonarrApi { get; }
|
||||
private IJobRecord Job { get; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
@ -75,6 +79,10 @@ namespace PlexRequests.Services.Jobs
|
|||
{
|
||||
Log.Error(ex, "Failed caching queued items from Sonarr");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Job.Record(JobNames.SonarrCacher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,10 @@ using System.Linq;
|
|||
|
||||
using NLog;
|
||||
|
||||
using PlexRequests.Services.Interfaces;
|
||||
using PlexRequests.Store;
|
||||
using PlexRequests.Store.Models;
|
||||
using PlexRequests.Store.Repository;
|
||||
|
||||
using Quartz;
|
||||
|
||||
|
@ -40,12 +43,14 @@ namespace PlexRequests.Services.Jobs
|
|||
{
|
||||
public class StoreBackup : IJob
|
||||
{
|
||||
public StoreBackup(ISqliteConfiguration sql)
|
||||
public StoreBackup(ISqliteConfiguration sql, IJobRecord rec)
|
||||
{
|
||||
Sql = sql;
|
||||
JobRecord = rec;
|
||||
}
|
||||
|
||||
private ISqliteConfiguration Sql { get; }
|
||||
private IJobRecord JobRecord { get; }
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
@ -82,6 +87,10 @@ namespace PlexRequests.Services.Jobs
|
|||
Log.Warn(e);
|
||||
Log.Warn("Exception when trying to copy the backup.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
JobRecord.Record(JobNames.StoreBackup);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,9 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</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\CouchPotatoCacher.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>
|
||||
<Compile Include="DbConfiguration.cs" />
|
||||
<Compile Include="Entity.cs" />
|
||||
<Compile Include="Models\ScheduledJobs.cs" />
|
||||
<Compile Include="Repository\IRequestRepository.cs" />
|
||||
<Compile Include="Repository\ISettingsRepository.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
|
||||
(
|
||||
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
|
||||
container.Register<IRepository<LogEntity>, GenericRepository<LogEntity>>();
|
||||
container.Register<IRepository<ScheduledJobs>, GenericRepository<ScheduledJobs>>();
|
||||
container.Register<IRequestService, JsonRequestService>();
|
||||
container.Register<ISettingsRepository, SettingsJsonRepository>();
|
||||
container.Register<IJobRecord, JobRecord>();
|
||||
|
||||
// Services
|
||||
container.Register<IAvailabilityChecker, PlexAvailabilityChecker>();
|
||||
|
|
|
@ -220,3 +220,7 @@ label {
|
|||
border-radius: 0 0.25rem 0.25rem 0 !important;
|
||||
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;
|
||||
$success-colour: #5cb85c;
|
||||
$i:
|
||||
!important
|
||||
;
|
||||
!important;
|
||||
|
||||
@media (min-width: 768px ) {
|
||||
.row {
|
||||
|
@ -280,3 +279,8 @@ $border-radius: 10px;
|
|||
border-radius: 0 .25rem .25rem 0 $i;
|
||||
padding: 12px 8px;
|
||||
}
|
||||
|
||||
#updateAvailable {
|
||||
background-color: rgb(255, 164, 0);
|
||||
text-align: center;
|
||||
}
|
|
@ -36,7 +36,7 @@ using Quartz.Spi;
|
|||
namespace PlexRequests.UI.Jobs
|
||||
{
|
||||
/// <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>
|
||||
/// <seealso cref="Quartz.Spi.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; }
|
||||
}
|
||||
}
|
|
@ -464,7 +464,7 @@ namespace PlexRequests.UI.Modules
|
|||
{
|
||||
var checker = new StatusChecker();
|
||||
var status = checker.GetStatus();
|
||||
var md = new Markdown();
|
||||
var md = new Markdown(new MarkdownOptions { AutoNewLines = true });
|
||||
status.ReleaseNotes = md.Transform(status.ReleaseNotes);
|
||||
return View["Status", status];
|
||||
}
|
||||
|
@ -623,7 +623,7 @@ namespace PlexRequests.UI.Modules
|
|||
{
|
||||
JsonSettings.MaxJsonLength = int.MaxValue;
|
||||
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)
|
||||
{
|
||||
l.DateString = l.Date.ToString("G");
|
||||
|
@ -650,7 +650,7 @@ namespace PlexRequests.UI.Modules
|
|||
settings.Level = level;
|
||||
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()
|
||||
|
|
|
@ -30,8 +30,11 @@ using Nancy.Extensions;
|
|||
using PlexRequests.UI.Models;
|
||||
using System;
|
||||
|
||||
using Nancy.Security;
|
||||
|
||||
using PlexRequests.Core;
|
||||
using PlexRequests.Core.SettingModels;
|
||||
using PlexRequests.Helpers;
|
||||
|
||||
namespace PlexRequests.UI.Modules
|
||||
{
|
||||
|
@ -52,6 +55,8 @@ namespace PlexRequests.UI.Modules
|
|||
}
|
||||
}
|
||||
|
||||
protected bool IsAdmin => Context.CurrentUser.IsAuthenticated();
|
||||
|
||||
protected int DateTimeOffset
|
||||
{
|
||||
get
|
||||
|
@ -87,5 +92,7 @@ namespace PlexRequests.UI.Modules
|
|||
: null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -124,14 +124,6 @@ namespace PlexRequests.UI.Modules
|
|||
private IHeadphonesApi HeadphonesApi { get; }
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private bool IsAdmin
|
||||
{
|
||||
get
|
||||
{
|
||||
return Context.CurrentUser.IsAuthenticated();
|
||||
}
|
||||
}
|
||||
|
||||
private Negotiator RequestLoad()
|
||||
{
|
||||
var settings = PrService.GetSettings();
|
||||
|
@ -626,7 +618,7 @@ namespace PlexRequests.UI.Modules
|
|||
Status = showInfo.status,
|
||||
RequestedDate = DateTime.UtcNow,
|
||||
Approved = false,
|
||||
RequestedUsers = new List<string>() { Username },
|
||||
RequestedUsers = new List<string> { Username },
|
||||
Issues = IssueState.None,
|
||||
ImdbId = showInfo.externals?.imdb ?? string.Empty,
|
||||
SeasonCount = showInfo.seasonCount
|
||||
|
@ -802,7 +794,7 @@ namespace PlexRequests.UI.Modules
|
|||
}
|
||||
|
||||
var sender = new HeadphonesSender(HeadphonesApi, hpSettings, RequestService);
|
||||
sender.AddAlbum(model);
|
||||
sender.AddAlbum(model).Wait();
|
||||
model.Approved = true;
|
||||
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\Scheduler.cs" />
|
||||
<Compile Include="Models\DatatablesModel.cs" />
|
||||
<Compile Include="Models\JsonUpdateAvailableModel.cs" />
|
||||
<Compile Include="Models\MovieSearchType.cs" />
|
||||
<Compile Include="Models\QualityModel.cs" />
|
||||
<Compile Include="Models\SearchViewModel.cs" />
|
||||
<Compile Include="Models\SearchMusicViewModel.cs" />
|
||||
<Compile Include="Models\SearchMovieViewModel.cs" />
|
||||
<Compile Include="Modules\BaseModule.cs" />
|
||||
<Compile Include="Modules\UpdateCheckerModule.cs" />
|
||||
<Compile Include="Start\StartupOptions.cs" />
|
||||
<Compile Include="Validators\HeadphonesValidator.cs" />
|
||||
<Compile Include="Validators\PushoverSettingsValidator.cs" />
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="updateAvailable" hidden="hidden"></div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
|
@ -82,6 +83,24 @@
|
|||
|
||||
$(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 () {
|
||||
|
||||
if ($(window).scrollTop() > 100) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue