This commit is contained in:
tidusjar 2016-11-16 22:14:21 +00:00
parent c2fe46f741
commit 39888a4b94
16 changed files with 312 additions and 275 deletions

View file

@ -43,5 +43,6 @@ namespace PlexRequests.Core.SettingModels
public int RecentlyAdded { get; set; } public int RecentlyAdded { get; set; }
public string RecentlyAddedCron { get; set; } public string RecentlyAddedCron { get; set; }
public int FaultQueueHandler { get; set; } public int FaultQueueHandler { get; set; }
public int PlexContentCacher { get; set; }
} }
} }

View file

@ -29,22 +29,23 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using PlexRequests.Store.Models; using PlexRequests.Store.Models;
using PlexRequests.Store.Models.Plex;
namespace PlexRequests.Services.Interfaces namespace PlexRequests.Services.Interfaces
{ {
public interface IAvailabilityChecker public interface IAvailabilityChecker
{ {
void CheckAndUpdateAll(); void CheckAndUpdateAll();
List<PlexMovie> GetPlexMovies(); IEnumerable<PlexContent> GetPlexMovies(IEnumerable<PlexContent> content);
bool IsMovieAvailable(PlexMovie[] plexMovies, string title, string year, string providerId = null); bool IsMovieAvailable(PlexContent[] plexMovies, string title, string year, string providerId = null);
List<PlexTvShow> GetPlexTvShows(); IEnumerable<PlexContent> GetPlexTvShows(IEnumerable<PlexContent> content);
bool IsTvShowAvailable(PlexTvShow[] plexShows, string title, string year, string providerId = null, int[] seasons = null); bool IsTvShowAvailable(PlexContent[] plexShows, string title, string year, string providerId = null, int[] seasons = null);
List<PlexAlbum> GetPlexAlbums(); IEnumerable<PlexContent> GetPlexAlbums(IEnumerable<PlexContent> content);
bool IsAlbumAvailable(PlexAlbum[] plexAlbums, string title, string year, string artist); bool IsAlbumAvailable(PlexContent[] plexAlbums, string title, string year, string artist);
bool IsEpisodeAvailable(string theTvDbId, int season, int episode); bool IsEpisodeAvailable(string theTvDbId, int season, int episode);
PlexAlbum GetAlbum(PlexAlbum[] plexAlbums, string title, string year, string artist); PlexContent GetAlbum(PlexContent[] plexAlbums, string title, string year, string artist);
PlexMovie GetMovie(PlexMovie[] plexMovies, string title, string year, string providerId = null); PlexContent GetMovie(PlexContent[] plexMovies, string title, string year, string providerId = null);
PlexTvShow GetTvShow(PlexTvShow[] plexShows, string title, string year, string providerId = null, int[] seasons = null); PlexContent GetTvShow(PlexContent[] plexShows, string title, string year, string providerId = null, int[] seasons = null);
/// <summary> /// <summary>
/// Gets the episode's stored in the cache. /// Gets the episode's stored in the cache.
/// </summary> /// </summary>

View file

@ -0,0 +1,10 @@
using Quartz;
namespace PlexRequests.Services.Jobs
{
public interface IPlexContentCacher
{
void CacheContent();
void Execute(IJobExecutionContext context);
}
}

View file

@ -30,7 +30,7 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapper; using Dapper;
using Newtonsoft.Json;
using NLog; using NLog;
using PlexRequests.Api.Interfaces; using PlexRequests.Api.Interfaces;
@ -89,17 +89,17 @@ namespace PlexRequests.Services.Jobs
Log.Debug("Validation of the plex settings failed."); Log.Debug("Validation of the plex settings failed.");
return; return;
} }
var libraries = CachedLibraries(plexSettings, true); //force setting the cache (10 min intervals via scheduler) //var libraries = CachedLibraries(plexSettings, true); //force setting the cache (10 min intervals via scheduler)
if (libraries == null || !libraries.Any()) //if (libraries == null || !libraries.Any())
{ //{
Log.Debug("Did not find any libraries in Plex."); // Log.Debug("Did not find any libraries in Plex.");
return; // return;
} //}
var content = PlexContent.GetAll().ToList();
var movies = GetPlexMovies().ToArray(); var movies = GetPlexMovies(content).ToArray();
var shows = GetPlexTvShows().ToArray(); var shows = GetPlexTvShows(content).ToArray();
var albums = GetPlexAlbums().ToArray(); var albums = GetPlexAlbums(content).ToArray();
var requests = RequestService.GetAll(); var requests = RequestService.GetAll();
var requestedModels = requests as RequestedModel[] ?? requests.Where(x => !x.Available).ToArray(); var requestedModels = requests as RequestedModel[] ?? requests.Where(x => !x.Available).ToArray();
@ -159,7 +159,7 @@ namespace PlexRequests.Services.Jobs
} }
} }
public List<PlexMovie> GetPlexMovies() public List<PlexMovie> GetPlexMoviesOld()
{ {
var settings = Plex.GetSettings(); var settings = Plex.GetSettings();
var movies = new List<PlexMovie>(); var movies = new List<PlexMovie>();
@ -186,13 +186,18 @@ namespace PlexRequests.Services.Jobs
return movies; return movies;
} }
public bool IsMovieAvailable(PlexMovie[] plexMovies, string title, string year, string providerId = null) public IEnumerable<PlexContent> GetPlexMovies(IEnumerable<PlexContent> content)
{
return content.Where(x => x.Type == Store.Models.Plex.PlexMediaType.Movie);
}
public bool IsMovieAvailable(PlexContent[] plexMovies, string title, string year, string providerId = null)
{ {
var movie = GetMovie(plexMovies, title, year, providerId); var movie = GetMovie(plexMovies, title, year, providerId);
return movie != null; return movie != null;
} }
public PlexMovie GetMovie(PlexMovie[] plexMovies, string title, string year, string providerId = null) public PlexContent GetMovie(PlexContent[] plexMovies, string title, string year, string providerId = null)
{ {
if (plexMovies.Length == 0) if (plexMovies.Length == 0)
{ {
@ -223,45 +228,19 @@ namespace PlexRequests.Services.Jobs
return null; return null;
} }
public List<PlexTvShow> GetPlexTvShows() public IEnumerable<PlexContent> GetPlexTvShows(IEnumerable<PlexContent> content)
{ {
var settings = Plex.GetSettings(); return content.Where(x => x.Type == Store.Models.Plex.PlexMediaType.Show);
var shows = new List<PlexTvShow>();
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
if (libs != null)
{
var withDir = libs.Where(x => x.Directory != null);
var tvLibs = withDir.Where(x =>
x.Directory.Any(y =>
y.Type.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)
)
).ToArray();
foreach (var lib in tvLibs)
{
shows.AddRange(lib.Directory.Select(x => new PlexTvShow // shows are in the directory list
{
Title = x.Title,
ReleaseYear = x.Year,
ProviderId = x.ProviderId,
Seasons = x.Seasons?.Select(d => PlexHelper.GetSeasonNumberFromTitle(d.Title)).ToArray(),
Url = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey)
}));
}
}
return shows;
} }
public bool IsTvShowAvailable(PlexTvShow[] plexShows, string title, string year, string providerId = null, int[] seasons = null) public bool IsTvShowAvailable(PlexContent[] plexShows, string title, string year, string providerId = null, int[] seasons = null)
{ {
var show = GetTvShow(plexShows, title, year, providerId, seasons); var show = GetTvShow(plexShows, title, year, providerId, seasons);
return show != null; return show != null;
} }
public PlexTvShow GetTvShow(PlexTvShow[] plexShows, string title, string year, string providerId = null, public PlexContent GetTvShow(PlexContent[] plexShows, string title, string year, string providerId = null,
int[] seasons = null) int[] seasons = null)
{ {
var advanced = !string.IsNullOrEmpty(providerId); var advanced = !string.IsNullOrEmpty(providerId);
@ -271,7 +250,8 @@ namespace PlexRequests.Services.Jobs
{ {
if (show.ProviderId == providerId && seasons != null) if (show.ProviderId == providerId && seasons != null)
{ {
if (seasons.Any(season => show.Seasons.Contains(season))) var showSeasons = ByteConverterHelper.ReturnObject<int[]>(show.Seasons);
if (seasons.Any(season => showSeasons.Contains(season)))
{ {
return show; return show;
} }
@ -357,41 +337,19 @@ namespace PlexRequests.Services.Jobs
return plexEpisodeses; return plexEpisodeses;
} }
public List<PlexAlbum> GetPlexAlbums() public IEnumerable<PlexContent> GetPlexAlbums(IEnumerable<PlexContent> content)
{ {
var settings = Plex.GetSettings(); return content.Where(x => x.Type == Store.Models.Plex.PlexMediaType.Artist);
var albums = new List<PlexAlbum>();
var libs = Cache.Get<List<PlexSearch>>(CacheKeys.PlexLibaries);
if (libs != null)
{
var albumLibs = libs.Where(x =>
x.Directory.Any(y =>
y.Type.Equals(PlexMediaType.Artist.ToString(), StringComparison.CurrentCultureIgnoreCase)
)
).ToArray();
foreach (var lib in albumLibs)
{
albums.AddRange(lib.Directory.Select(x => new PlexAlbum()
{
Title = x.Title,
ReleaseYear = x.Year,
Artist = x.ParentTitle,
Url = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey)
}));
}
}
return albums;
} }
public bool IsAlbumAvailable(PlexAlbum[] plexAlbums, string title, string year, string artist) public bool IsAlbumAvailable(PlexContent[] plexAlbums, string title, string year, string artist)
{ {
return plexAlbums.Any(x => return plexAlbums.Any(x =>
x.Title.Contains(title) && x.Title.Contains(title) &&
x.Artist.Equals(artist, StringComparison.CurrentCultureIgnoreCase)); x.Artist.Equals(artist, StringComparison.CurrentCultureIgnoreCase));
} }
public PlexAlbum GetAlbum(PlexAlbum[] plexAlbums, string title, string year, string artist) public PlexContent GetAlbum(PlexContent[] plexAlbums, string title, string year, string artist)
{ {
return plexAlbums.FirstOrDefault(x => return plexAlbums.FirstOrDefault(x =>
x.Title.Contains(title) && x.Title.Contains(title) &&

View file

@ -30,7 +30,7 @@ using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapper; using Dapper;
using Newtonsoft.Json;
using NLog; using NLog;
using Org.BouncyCastle.Crypto.Modes.Gcm; using Org.BouncyCastle.Crypto.Modes.Gcm;
using PlexRequests.Api.Interfaces; using PlexRequests.Api.Interfaces;
@ -51,7 +51,7 @@ using Quartz;
namespace PlexRequests.Services.Jobs namespace PlexRequests.Services.Jobs
{ {
public class PlexContentCacher : IJob public class PlexContentCacher : IJob, IPlexContentCacher
{ {
public PlexContentCacher(ISettingsService<PlexSettings> plexSettings, IRequestService request, IPlexApi plex, ICacheProvider cache, public PlexContentCacher(ISettingsService<PlexSettings> plexSettings, IRequestService request, IPlexApi plex, ICacheProvider cache,
INotificationService notify, IJobRecord rec, IRepository<UsersToNotify> users, IRepository<PlexEpisodes> repo, INotificationEngine e, IRepository<PlexContent> content) INotificationService notify, IJobRecord rec, IRepository<UsersToNotify> users, IRepository<PlexEpisodes> repo, INotificationEngine e, IRepository<PlexContent> content)
@ -115,7 +115,6 @@ namespace PlexRequests.Services.Jobs
{ {
movies.AddRange(lib.Video.Select(video => new PlexMovie movies.AddRange(lib.Video.Select(video => new PlexMovie
{ {
Id = video.Guid,
ReleaseYear = video.Year, ReleaseYear = video.Year,
Title = video.Title, Title = video.Title,
ProviderId = video.ProviderId, ProviderId = video.ProviderId,
@ -149,7 +148,6 @@ namespace PlexRequests.Services.Jobs
ProviderId = x.ProviderId, ProviderId = x.ProviderId,
Seasons = x.Seasons?.Select(d => PlexHelper.GetSeasonNumberFromTitle(d.Title)).ToArray(), Seasons = x.Seasons?.Select(d => PlexHelper.GetSeasonNumberFromTitle(d.Title)).ToArray(),
Url = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey), Url = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey),
Id = x.Guid
})); }));
} }
@ -177,7 +175,6 @@ namespace PlexRequests.Services.Jobs
albums.AddRange(lib.Directory.Select(x => new PlexAlbum() albums.AddRange(lib.Directory.Select(x => new PlexAlbum()
{ {
Title = x.Title, Title = x.Title,
Id = x.Guid,
ProviderId = x.ProviderId, ProviderId = x.ProviderId,
ReleaseYear = x.Year, ReleaseYear = x.Year,
Artist = x.ParentTitle, Artist = x.ParentTitle,
@ -240,47 +237,66 @@ namespace PlexRequests.Services.Jobs
} }
if (results != null) if (results != null)
{ {
var movies = GetPlexMovies(results); var movies = GetPlexMovies(results);
// Time to destroy the plex movies from the DB
PlexContent.Custom(connection =>
{
connection.Open();
connection.Query("delete from PlexContent where type = @type", new { type = 0 });
return new List<PlexContent>();
});
foreach (var m in movies) foreach (var m in movies)
{ {
PlexContent.Insert(new PlexContent PlexContent.Insert(new PlexContent
{ {
ProviderId = m.ProviderId, ProviderId = m.ProviderId,
ReleaseYear = m.ReleaseYear, ReleaseYear = m.ReleaseYear ?? string.Empty,
Title = m.Title, Title = m.Title,
Type = Store.Models.Plex.PlexMediaType.Movie, Type = Store.Models.Plex.PlexMediaType.Movie,
Url = m.Url, Url = m.Url
PlexId = m.Id
}); });
} }
var tv = GetPlexTvShows(results); var tv = GetPlexTvShows(results);
// Time to destroy the plex tv from the DB
PlexContent.Custom(connection =>
{
connection.Open();
connection.Query("delete from PlexContent where type = @type", new { type = 1 });
return new List<PlexContent>();
});
foreach (var t in tv) foreach (var t in tv)
{ {
PlexContent.Insert(new PlexContent PlexContent.Insert(new PlexContent
{ {
ProviderId = t.ProviderId, ProviderId = t.ProviderId,
ReleaseYear = t.ReleaseYear, ReleaseYear = t.ReleaseYear ?? string.Empty,
Title = t.Title, Title = t.Title,
Type = Store.Models.Plex.PlexMediaType.Show, Type = Store.Models.Plex.PlexMediaType.Show,
Url = t.Url, Url = t.Url,
Seasons = t.Seasons, Seasons = ByteConverterHelper.ReturnBytes(t.Seasons)
PlexId = t.Id
}); });
} }
var albums = GetPlexAlbums(results); var albums = GetPlexAlbums(results);
// Time to destroy the plex movies from the DB
PlexContent.Custom(connection =>
{
connection.Open();
connection.Query("delete from PlexContent where type = @type", new { type = 2 });
return new List<PlexContent>();
});
foreach (var a in albums) foreach (var a in albums)
{ {
PlexContent.Insert(new PlexContent PlexContent.Insert(new PlexContent
{ {
ProviderId = a.ProviderId, ProviderId = a.ProviderId,
ReleaseYear = a.ReleaseYear, ReleaseYear = a.ReleaseYear ?? string.Empty,
Title = a.Title, Title = a.Title,
Type = Store.Models.Plex.PlexMediaType.Artist, Type = Store.Models.Plex.PlexMediaType.Artist,
Url = a.Url, Url = a.Url
PlexId = a.Id
}); });
} }
} }

View file

@ -36,6 +36,10 @@
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Microsoft.Build.Framework" /> <Reference Include="Microsoft.Build.Framework" />
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.6\lib\net45\NLog.dll</HintPath> <HintPath>..\packages\NLog.4.3.6\lib\net45\NLog.dll</HintPath>
<Private>True</Private> <Private>True</Private>
@ -81,6 +85,7 @@
<Compile Include="Interfaces\IJobRecord.cs" /> <Compile Include="Interfaces\IJobRecord.cs" />
<Compile Include="Interfaces\INotificationEngine.cs" /> <Compile Include="Interfaces\INotificationEngine.cs" />
<Compile Include="Jobs\HtmlTemplateGenerator.cs" /> <Compile Include="Jobs\HtmlTemplateGenerator.cs" />
<Compile Include="Jobs\IPlexContentCacher.cs" />
<Compile Include="Jobs\IRecentlyAdded.cs" /> <Compile Include="Jobs\IRecentlyAdded.cs" />
<Compile Include="Jobs\JobRecord.cs" /> <Compile Include="Jobs\JobRecord.cs" />
<Compile Include="Jobs\JobNames.cs" /> <Compile Include="Jobs\JobNames.cs" />

View file

@ -38,12 +38,11 @@ namespace PlexRequests.Store.Models.Plex
public string ProviderId { get; set; } public string ProviderId { get; set; }
public PlexMediaType Type { get; set; } public PlexMediaType Type { get; set; }
public string Url { get; set; } public string Url { get; set; }
public string PlexId { get; set; }
/// <summary> /// <summary>
/// Only used for TV Shows /// Only used for TV Shows
/// </summary> /// </summary>
public int[] Seasons { get; set; } public byte[] Seasons { get; set; }
/// <summary> /// <summary>
/// Only used for Albums /// Only used for Albums

View file

@ -28,8 +28,8 @@ namespace PlexRequests.Store.Models.Plex
{ {
public enum PlexMediaType public enum PlexMediaType
{ {
Movie, Movie = 0,
Show, Show = 1,
Artist Artist = 2
} }
} }

View file

@ -154,7 +154,6 @@ CREATE TABLE IF NOT EXISTS PlexContent
ReleaseYear VARCHAR(100) NOT NULL, ReleaseYear VARCHAR(100) NOT NULL,
ProviderId VARCHAR(100) NOT NULL, ProviderId VARCHAR(100) NOT NULL,
Url VARCHAR(100) NOT NULL, Url VARCHAR(100) NOT NULL,
PlexId VARCHAR(100) NOT NULL,
Artist VARCHAR(100), Artist VARCHAR(100),
Seasons BLOB, Seasons BLOB,
Type INTEGER NOT NULL Type INTEGER NOT NULL

View file

@ -1,167 +1,167 @@
#region Copyright //#region Copyright
// /************************************************************************ //// /************************************************************************
// Copyright (c) 2016 Jamie Rees //// Copyright (c) 2016 Jamie Rees
// File: SearchModuleTests.cs //// File: SearchModuleTests.cs
// Created By: Jamie Rees //// Created By: Jamie Rees
// ////
// Permission is hereby granted, free of charge, to any person obtaining //// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the //// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including //// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish, //// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to //// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to //// permit persons to whom the Software is furnished to do so, subject to
// the following conditions: //// the following conditions:
// ////
// The above copyright notice and this permission notice shall be //// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. //// included in all copies or substantial portions of the Software.
// ////
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, //// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF //// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND //// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE //// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION //// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION //// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// 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; //using System;
using System.Collections.Generic; //using System.Collections.Generic;
using System.Linq; //using System.Linq;
using Moq; //using Moq;
using NUnit.Framework; //using NUnit.Framework;
using PlexRequests.Api.Interfaces; //using PlexRequests.Api.Interfaces;
using PlexRequests.Api.Models.Plex; //using PlexRequests.Api.Models.Plex;
using PlexRequests.Core; //using PlexRequests.Core;
using PlexRequests.Core.Queue; //using PlexRequests.Core.Queue;
using PlexRequests.Core.SettingModels; //using PlexRequests.Core.SettingModels;
using PlexRequests.Helpers; //using PlexRequests.Helpers;
using PlexRequests.Helpers.Analytics; //using PlexRequests.Helpers.Analytics;
using PlexRequests.Services.Interfaces; //using PlexRequests.Services.Interfaces;
using PlexRequests.Services.Jobs; //using PlexRequests.Services.Jobs;
using PlexRequests.Store; //using PlexRequests.Store;
using PlexRequests.Store.Models; //using PlexRequests.Store.Models;
using PlexRequests.Store.Repository; //using PlexRequests.Store.Repository;
using PlexRequests.UI.Modules; //using PlexRequests.UI.Modules;
using Ploeh.AutoFixture; //using Ploeh.AutoFixture;
namespace PlexRequests.UI.Tests //namespace PlexRequests.UI.Tests
{ //{
[TestFixture] // [TestFixture]
public class SearchModuleTests // public class SearchModuleTests
{ // {
private Mock<ISettingsService<HeadphonesSettings>> _headphonesSettings; // private Mock<ISettingsService<HeadphonesSettings>> _headphonesSettings;
private Mock<INotificationService> _notificationService; // private Mock<INotificationService> _notificationService;
private Mock<ISettingsService<SickRageSettings>> _sickRageSettingsMock; // private Mock<ISettingsService<SickRageSettings>> _sickRageSettingsMock;
private Mock<ICouchPotatoApi> _cpApi; // private Mock<ICouchPotatoApi> _cpApi;
private Mock<ISettingsService<SonarrSettings>> _sonarrSettingsMock; // private Mock<ISettingsService<SonarrSettings>> _sonarrSettingsMock;
private Mock<ISonarrApi> _sonarrApiMock; // private Mock<ISonarrApi> _sonarrApiMock;
private Mock<ISettingsService<PlexSettings>> _plexSettingsMock; // private Mock<ISettingsService<PlexSettings>> _plexSettingsMock;
private Mock<ISettingsService<CouchPotatoSettings>> _cpMock; // private Mock<ISettingsService<CouchPotatoSettings>> _cpMock;
private Mock<ISettingsService<PlexRequestSettings>> _plexRequestMock; // private Mock<ISettingsService<PlexRequestSettings>> _plexRequestMock;
private Mock<ISettingsService<AuthenticationSettings>> _authMock; // private Mock<ISettingsService<AuthenticationSettings>> _authMock;
private Mock<IAnalytics> _analytics; // private Mock<IAnalytics> _analytics;
private Mock<IAvailabilityChecker> _availabilityMock; // private Mock<IAvailabilityChecker> _availabilityMock;
private Mock<IRequestService> _rServiceMock; // private Mock<IRequestService> _rServiceMock;
private Mock<ISickRageApi> _srApi; // private Mock<ISickRageApi> _srApi;
private Mock<IMusicBrainzApi> _music; // private Mock<IMusicBrainzApi> _music;
private Mock<IHeadphonesApi> _hpAPi; // private Mock<IHeadphonesApi> _hpAPi;
private Mock<ICouchPotatoCacher> _cpCache; // private Mock<ICouchPotatoCacher> _cpCache;
private Mock<ISonarrCacher> _sonarrCache; // private Mock<ISonarrCacher> _sonarrCache;
private Mock<ISickRageCacher> _srCache; // private Mock<ISickRageCacher> _srCache;
private Mock<IPlexApi> _plexApi; // private Mock<IPlexApi> _plexApi;
private Mock<IRepository<UsersToNotify>> _userRepo; // private Mock<IRepository<UsersToNotify>> _userRepo;
private Mock<ISettingsService<EmailNotificationSettings>> _emailSettings; // private Mock<ISettingsService<EmailNotificationSettings>> _emailSettings;
private Mock<IIssueService> _issueService; // private Mock<IIssueService> _issueService;
private Mock<ICacheProvider> _cache; // private Mock<ICacheProvider> _cache;
private Mock<ITransientFaultQueue> _faultQueue; // private Mock<ITransientFaultQueue> _faultQueue;
private Mock<IRepository<RequestLimit>> RequestLimitRepo { get; set; } // private Mock<IRepository<RequestLimit>> RequestLimitRepo { get; set; }
private SearchModule Search { get; set; } // private SearchModule Search { get; set; }
private readonly Fixture F = new Fixture(); // private readonly Fixture F = new Fixture();
[Test] // [Test]
public void CheckNoRequestLimitTest() // public void CheckNoRequestLimitTest()
{ // {
var settings = new PlexRequestSettings { AlbumWeeklyRequestLimit = 0, MovieWeeklyRequestLimit = 2, TvWeeklyRequestLimit = 0 }; // var settings = new PlexRequestSettings { AlbumWeeklyRequestLimit = 0, MovieWeeklyRequestLimit = 2, TvWeeklyRequestLimit = 0 };
var result = Search.CheckRequestLimit(settings, RequestType.Movie).Result; // var result = Search.CheckRequestLimit(settings, RequestType.Movie).Result;
Assert.That(result, Is.True); // Assert.That(result, Is.True);
RequestLimitRepo.Verify(x => x.GetAllAsync(), Times.Once); // RequestLimitRepo.Verify(x => x.GetAllAsync(), Times.Once);
} // }
[TestCaseSource(nameof(MovieLimitData))] // [TestCaseSource(nameof(MovieLimitData))]
public bool CheckMovieLimitTest(int requestCount) // public bool CheckMovieLimitTest(int requestCount)
{ // {
var users = F.CreateMany<RequestLimit>().ToList(); // var users = F.CreateMany<RequestLimit>().ToList();
users.Add(new RequestLimit { Username = "", RequestCount = requestCount, RequestType = RequestType.Movie}); // users.Add(new RequestLimit { Username = "", RequestCount = requestCount, RequestType = RequestType.Movie});
RequestLimitRepo.Setup(x => x.GetAllAsync()).ReturnsAsync(users); // RequestLimitRepo.Setup(x => x.GetAllAsync()).ReturnsAsync(users);
var settings = new PlexRequestSettings { AlbumWeeklyRequestLimit = 0, MovieWeeklyRequestLimit = 5, TvWeeklyRequestLimit = 0 }; // var settings = new PlexRequestSettings { AlbumWeeklyRequestLimit = 0, MovieWeeklyRequestLimit = 5, TvWeeklyRequestLimit = 0 };
var result = Search.CheckRequestLimit(settings, RequestType.Movie).Result; // var result = Search.CheckRequestLimit(settings, RequestType.Movie).Result;
RequestLimitRepo.Verify(x => x.GetAllAsync(), Times.Once); // RequestLimitRepo.Verify(x => x.GetAllAsync(), Times.Once);
return result; // return result;
} // }
private static IEnumerable<TestCaseData> MovieLimitData // private static IEnumerable<TestCaseData> MovieLimitData
{ // {
get // get
{ // {
yield return new TestCaseData(1).Returns(true).SetName("1 Request of 5"); // yield return new TestCaseData(1).Returns(true).SetName("1 Request of 5");
yield return new TestCaseData(2).Returns(true).SetName("2 Request of 5"); // yield return new TestCaseData(2).Returns(true).SetName("2 Request of 5");
yield return new TestCaseData(3).Returns(true).SetName("3 Request of 5"); // yield return new TestCaseData(3).Returns(true).SetName("3 Request of 5");
yield return new TestCaseData(4).Returns(true).SetName("4 Request of 5"); // yield return new TestCaseData(4).Returns(true).SetName("4 Request of 5");
yield return new TestCaseData(5).Returns(false).SetName("5 Request of 5"); // yield return new TestCaseData(5).Returns(false).SetName("5 Request of 5");
yield return new TestCaseData(6).Returns(false).SetName("6 Request of 5"); // yield return new TestCaseData(6).Returns(false).SetName("6 Request of 5");
yield return new TestCaseData(0).Returns(true).SetName("0 Request of 5"); // yield return new TestCaseData(0).Returns(true).SetName("0 Request of 5");
} // }
} // }
[SetUp] // [SetUp]
public void Setup() // public void Setup()
{ // {
_authMock = new Mock<Core.ISettingsService<AuthenticationSettings>>(); // _authMock = new Mock<Core.ISettingsService<AuthenticationSettings>>();
_plexRequestMock = new Mock<ISettingsService<PlexRequestSettings>>(); // _plexRequestMock = new Mock<ISettingsService<PlexRequestSettings>>();
_plexRequestMock.Setup(x => x.GetSettings()).Returns(new PlexRequestSettings()); // _plexRequestMock.Setup(x => x.GetSettings()).Returns(new PlexRequestSettings());
_cpMock = new Mock<Core.ISettingsService<CouchPotatoSettings>>(); // _cpMock = new Mock<Core.ISettingsService<CouchPotatoSettings>>();
_plexSettingsMock = new Mock<Core.ISettingsService<PlexSettings>>(); // _plexSettingsMock = new Mock<Core.ISettingsService<PlexSettings>>();
_sonarrApiMock = new Mock<ISonarrApi>(); // _sonarrApiMock = new Mock<ISonarrApi>();
_sonarrSettingsMock = new Mock<Core.ISettingsService<SonarrSettings>>(); // _sonarrSettingsMock = new Mock<Core.ISettingsService<SonarrSettings>>();
_cpApi = new Mock<ICouchPotatoApi>(); // _cpApi = new Mock<ICouchPotatoApi>();
_sickRageSettingsMock = new Mock<Core.ISettingsService<SickRageSettings>>(); // _sickRageSettingsMock = new Mock<Core.ISettingsService<SickRageSettings>>();
_notificationService = new Mock<INotificationService>(); // _notificationService = new Mock<INotificationService>();
_headphonesSettings = new Mock<Core.ISettingsService<HeadphonesSettings>>(); // _headphonesSettings = new Mock<Core.ISettingsService<HeadphonesSettings>>();
_cache = new Mock<ICacheProvider>(); // _cache = new Mock<ICacheProvider>();
_analytics = new Mock<IAnalytics>(); // _analytics = new Mock<IAnalytics>();
_availabilityMock = new Mock<IAvailabilityChecker>(); // _availabilityMock = new Mock<IAvailabilityChecker>();
_rServiceMock = new Mock<IRequestService>(); // _rServiceMock = new Mock<IRequestService>();
_srApi = new Mock<ISickRageApi>(); // _srApi = new Mock<ISickRageApi>();
_music = new Mock<IMusicBrainzApi>(); // _music = new Mock<IMusicBrainzApi>();
_hpAPi = new Mock<IHeadphonesApi>(); // _hpAPi = new Mock<IHeadphonesApi>();
_cpCache = new Mock<ICouchPotatoCacher>(); // _cpCache = new Mock<ICouchPotatoCacher>();
_sonarrCache = new Mock<ISonarrCacher>(); // _sonarrCache = new Mock<ISonarrCacher>();
_srCache = new Mock<ISickRageCacher>(); // _srCache = new Mock<ISickRageCacher>();
_plexApi = new Mock<IPlexApi>(); // _plexApi = new Mock<IPlexApi>();
_userRepo = new Mock<IRepository<UsersToNotify>>(); // _userRepo = new Mock<IRepository<UsersToNotify>>();
RequestLimitRepo = new Mock<IRepository<RequestLimit>>(); // RequestLimitRepo = new Mock<IRepository<RequestLimit>>();
_emailSettings = new Mock<ISettingsService<EmailNotificationSettings>>(); // _emailSettings = new Mock<ISettingsService<EmailNotificationSettings>>();
_issueService = new Mock<IIssueService>(); // _issueService = new Mock<IIssueService>();
_faultQueue = new Mock<ITransientFaultQueue>(); // _faultQueue = new Mock<ITransientFaultQueue>();
CreateModule(); // CreateModule();
} // }
private void CreateModule() // private void CreateModule()
{ // {
Search = new SearchModule(_cache.Object, _cpMock.Object, _plexRequestMock.Object, _availabilityMock.Object, // Search = new SearchModule(_cache.Object, _cpMock.Object, _plexRequestMock.Object, _availabilityMock.Object,
_rServiceMock.Object, _sonarrApiMock.Object, _sonarrSettingsMock.Object, // _rServiceMock.Object, _sonarrApiMock.Object, _sonarrSettingsMock.Object,
_sickRageSettingsMock.Object, _cpApi.Object, _srApi.Object, _notificationService.Object, // _sickRageSettingsMock.Object, _cpApi.Object, _srApi.Object, _notificationService.Object,
_music.Object, _hpAPi.Object, _headphonesSettings.Object, _cpCache.Object, _sonarrCache.Object, // _music.Object, _hpAPi.Object, _headphonesSettings.Object, _cpCache.Object, _sonarrCache.Object,
_srCache.Object, _plexApi.Object, _plexSettingsMock.Object, _authMock.Object, // _srCache.Object, _plexApi.Object, _plexSettingsMock.Object, _authMock.Object,
_userRepo.Object, _emailSettings.Object, _issueService.Object, _analytics.Object, RequestLimitRepo.Object, _faultQueue.Object); // _userRepo.Object, _emailSettings.Object, _issueService.Object, _analytics.Object, RequestLimitRepo.Object, _faultQueue.Object);
} // }
} // }
} //}

View file

@ -147,10 +147,6 @@
}); });
} }
function getBaseUrl() {
return $('#baseUrl').val();
}
$scope.formatDate = function (utcDate) { $scope.formatDate = function (utcDate) {
return moment.utc(utcDate).local().format('lll'); return moment.utc(utcDate).local().format('lll');
} }

View file

@ -4,8 +4,11 @@
$http.defaults.headers.common['Content-Type'] = 'application/json'; // Set default headers $http.defaults.headers.common['Content-Type'] = 'application/json'; // Set default headers
var getUsers = function () { var getUsers = function () {
return $http.get('/usermanagement/users'); var url = createBaseUrl(getBaseUrl(), '/usermanagement/users');
return $http.get(url);
}; };
var addUser = function (user, permissions, features) { var addUser = function (user, permissions, features) {
@ -13,32 +16,41 @@
return null; return null;
} }
var url = createBaseUrl(getBaseUrl(), '/usermanagement/createuser');
return $http({ return $http({
url: '/usermanagement/createuser', url: url,
method: "POST", method: "POST",
data: { username: user.username, password: user.password, permissions: permissions, features : features, email: user.email } data: { username: user.username, password: user.password, permissions: permissions, features : features, email: user.email }
}); });
} }
var getFeatures = function () { var getFeatures = function () {
return $http.get('/usermanagement/features'); var url = createBaseUrl(getBaseUrl(), '/usermanagement/features');
return $http.get(url);
} }
var getPermissions = function () { var getPermissions = function () {
return $http.get('/usermanagement/permissions'); var url = createBaseUrl(getBaseUrl(), '/usermanagement/permissions');
return $http.get(url);
} }
var updateUser = function (id, permissions, features, alias, email) { var updateUser = function (id, permissions, features, alias, email) {
var url = createBaseUrl(getBaseUrl(), '/usermanagement/updateUser');
return $http({ return $http({
url: '/usermanagement/updateUser', url: url,
method: "POST", method: "POST",
data: { id: id, permissions: permissions, features: features, alias: alias, emailAddress: email }, data: { id: id, permissions: permissions, features: features, alias: alias, emailAddress: email },
}); });
} }
var deleteUser = function (id) { var deleteUser = function (id) {
var url = createBaseUrl(getBaseUrl(), '/usermanagement/deleteUser');
return $http({ return $http({
url: '/usermanagement/deleteUser', url: url,
method: "POST", method: "POST",
data: { id: id } data: { id: id }
}); });
@ -53,6 +65,9 @@
deleteUser: deleteUser deleteUser: deleteUser
}; };
} }
function getBaseUrl() {
return $('#baseUrl').text();
}
angular.module('PlexRequests').factory('userManagementService', ["$http", userManagementService]); angular.module('PlexRequests').factory('userManagementService', ["$http", userManagementService]);

View file

@ -62,6 +62,7 @@ namespace PlexRequests.UI.Jobs
var jobList = new List<IJobDetail> var jobList = new List<IJobDetail>
{ {
JobBuilder.Create<PlexAvailabilityChecker>().WithIdentity("PlexAvailabilityChecker", "Plex").Build(), JobBuilder.Create<PlexAvailabilityChecker>().WithIdentity("PlexAvailabilityChecker", "Plex").Build(),
JobBuilder.Create<PlexContentCacher>().WithIdentity("PlexContentCacher", "Plex").Build(),
JobBuilder.Create<PlexEpisodeCacher>().WithIdentity("PlexEpisodeCacher", "Cache").Build(), JobBuilder.Create<PlexEpisodeCacher>().WithIdentity("PlexEpisodeCacher", "Cache").Build(),
JobBuilder.Create<SickRageCacher>().WithIdentity("SickRageCacher", "Cache").Build(), JobBuilder.Create<SickRageCacher>().WithIdentity("SickRageCacher", "Cache").Build(),
JobBuilder.Create<SonarrCacher>().WithIdentity("SonarrCacher", "Cache").Build(), JobBuilder.Create<SonarrCacher>().WithIdentity("SonarrCacher", "Cache").Build(),
@ -154,15 +155,25 @@ namespace PlexRequests.UI.Jobs
{ {
s.FaultQueueHandler = 6; s.FaultQueueHandler = 6;
} }
if (s.PlexContentCacher == 0)
{
s.PlexContentCacher = 60;
}
var triggers = new List<ITrigger>(); var triggers = new List<ITrigger>();
var plexAvailabilityChecker = var plexAvailabilityChecker =
TriggerBuilder.Create() TriggerBuilder.Create()
.WithIdentity("PlexAvailabilityChecker", "Plex") .WithIdentity("PlexAvailabilityChecker", "Plex")
.StartNow() .StartAt(DateBuilder.FutureDate(5, IntervalUnit.Minute))
.WithSimpleSchedule(x => x.WithIntervalInMinutes(s.PlexAvailabilityChecker).RepeatForever()) .WithSimpleSchedule(x => x.WithIntervalInMinutes(s.PlexAvailabilityChecker).RepeatForever())
.Build(); .Build();
var plexCacher =
TriggerBuilder.Create()
.WithIdentity("PlexContentCacher", "Plex")
.StartNow()
.WithSimpleSchedule(x => x.WithIntervalInMinutes(s.PlexContentCacher).RepeatForever())
.Build();
var srCacher = var srCacher =
TriggerBuilder.Create() TriggerBuilder.Create()
@ -241,6 +252,7 @@ namespace PlexRequests.UI.Jobs
triggers.Add(userRequestLimiter); triggers.Add(userRequestLimiter);
triggers.Add(plexEpCacher); triggers.Add(plexEpCacher);
triggers.Add(fault); triggers.Add(fault);
triggers.Add(plexCacher);
return triggers; return triggers;
} }

View file

@ -61,6 +61,7 @@ using PlexRequests.Core.Queue;
using PlexRequests.Helpers.Analytics; using PlexRequests.Helpers.Analytics;
using PlexRequests.Helpers.Permissions; using PlexRequests.Helpers.Permissions;
using PlexRequests.Store.Models; using PlexRequests.Store.Models;
using PlexRequests.Store.Models.Plex;
using PlexRequests.Store.Repository; using PlexRequests.Store.Repository;
using TMDbLib.Objects.General; using TMDbLib.Objects.General;
@ -81,7 +82,7 @@ namespace PlexRequests.UI.Modules
ICouchPotatoCacher cpCacher, ISonarrCacher sonarrCacher, ISickRageCacher sickRageCacher, IPlexApi plexApi, ICouchPotatoCacher cpCacher, ISonarrCacher sonarrCacher, ISickRageCacher sickRageCacher, IPlexApi plexApi,
ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth, ISettingsService<PlexSettings> plexService, ISettingsService<AuthenticationSettings> auth,
IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email, IRepository<UsersToNotify> u, ISettingsService<EmailNotificationSettings> email,
IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue) IIssueService issue, IAnalytics a, IRepository<RequestLimit> rl, ITransientFaultQueue tfQueue, IRepository<PlexContent> content)
: base("search", prSettings) : base("search", prSettings)
{ {
Auth = auth; Auth = auth;
@ -112,6 +113,7 @@ namespace PlexRequests.UI.Modules
RequestLimitRepo = rl; RequestLimitRepo = rl;
FaultQueue = tfQueue; FaultQueue = tfQueue;
TvApi = new TvMazeApi(); TvApi = new TvMazeApi();
PlexContentRepository = content;
Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad(); Get["SearchIndex", "/", true] = async (x, ct) => await RequestLoad();
@ -137,6 +139,7 @@ namespace PlexRequests.UI.Modules
Get["/episodes", true] = async (x, ct) => await GetEpisodes(); Get["/episodes", true] = async (x, ct) => await GetEpisodes();
} }
private IRepository<PlexContent> PlexContentRepository { get; }
private TvMazeApi TvApi { get; } private TvMazeApi TvApi { get; }
private IPlexApi PlexApi { get; } private IPlexApi PlexApi { get; }
private TheMovieDbApi MovieApi { get; } private TheMovieDbApi MovieApi { get; }
@ -243,7 +246,8 @@ namespace PlexRequests.UI.Modules
var cpCached = CpCacher.QueuedIds(); var cpCached = CpCacher.QueuedIds();
var plexMovies = Checker.GetPlexMovies(); var content = PlexContentRepository.GetAll();
var plexMovies = Checker.GetPlexMovies(content);
var settings = await PrService.GetSettingsAsync(); var settings = await PrService.GetSettingsAsync();
var viewMovies = new List<SearchMovieViewModel>(); var viewMovies = new List<SearchMovieViewModel>();
var counter = 0; var counter = 0;
@ -342,7 +346,8 @@ namespace PlexRequests.UI.Modules
var sonarrCached = SonarrCacher.QueuedIds(); var sonarrCached = SonarrCacher.QueuedIds();
var sickRageCache = SickRageCacher.QueuedIds(); // consider just merging sonarr/sickrage arrays var sickRageCache = SickRageCacher.QueuedIds(); // consider just merging sonarr/sickrage arrays
var plexTvShows = Checker.GetPlexTvShows(); var content = PlexContentRepository.GetAll();
var plexTvShows = Checker.GetPlexTvShows(content);
var viewTv = new List<SearchTvShowViewModel>(); var viewTv = new List<SearchTvShowViewModel>();
foreach (var t in apiTv) foreach (var t in apiTv)
@ -423,7 +428,8 @@ namespace PlexRequests.UI.Modules
var dbAlbum = allResults.ToDictionary(x => x.MusicBrainzId); var dbAlbum = allResults.ToDictionary(x => x.MusicBrainzId);
var plexAlbums = Checker.GetPlexAlbums(); var content = PlexContentRepository.GetAll();
var plexAlbums = Checker.GetPlexAlbums(content);
var viewAlbum = new List<SearchMusicViewModel>(); var viewAlbum = new List<SearchMusicViewModel>();
foreach (var a in apiAlbums) foreach (var a in apiAlbums)
@ -514,7 +520,9 @@ namespace PlexRequests.UI.Modules
try try
{ {
var movies = Checker.GetPlexMovies();
var content = PlexContentRepository.GetAll();
var movies = Checker.GetPlexMovies(content);
if (Checker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString())) if (Checker.IsMovieAvailable(movies.ToArray(), movieInfo.Title, movieInfo.ReleaseDate?.Year.ToString()))
{ {
return return
@ -784,7 +792,9 @@ namespace PlexRequests.UI.Modules
try try
{ {
var shows = Checker.GetPlexTvShows();
var content = PlexContentRepository.GetAll();
var shows = Checker.GetPlexTvShows(content);
var providerId = string.Empty; var providerId = string.Empty;
var plexSettings = await PlexService.GetSettingsAsync(); var plexSettings = await PlexService.GetSettingsAsync();
if (plexSettings.AdvancedSearch) if (plexSettings.AdvancedSearch)
@ -1046,7 +1056,9 @@ namespace PlexRequests.UI.Modules
}); });
} }
var albums = Checker.GetPlexAlbums();
var content = PlexContentRepository.GetAll();
var albums = Checker.GetPlexAlbums(content);
var alreadyInPlex = Checker.IsAlbumAvailable(albums.ToArray(), albumInfo.title, release.ToString("yyyy"), var alreadyInPlex = Checker.IsAlbumAvailable(albums.ToArray(), albumInfo.title, release.ToString("yyyy"),
artist.name); artist.name);

View file

@ -46,6 +46,7 @@ namespace PlexRequests.UI.NinjectModules
Bind<ISonarrCacher>().To<SonarrCacher>(); Bind<ISonarrCacher>().To<SonarrCacher>();
Bind<ISickRageCacher>().To<SickRageCacher>(); Bind<ISickRageCacher>().To<SickRageCacher>();
Bind<IRecentlyAdded>().To<RecentlyAdded>(); Bind<IRecentlyAdded>().To<RecentlyAdded>();
Bind<IPlexContentCacher>().To<PlexContentCacher>();
Bind<IJobFactory>().To<CustomJobFactory>(); Bind<IJobFactory>().To<CustomJobFactory>();
Bind<IAnalytics>().To<Analytics>(); Bind<IAnalytics>().To<Analytics>();

View file

@ -32,7 +32,11 @@ using Ninject.Planning.Bindings.Resolvers;
using NLog; using NLog;
using Owin; using Owin;
using PlexRequests.Core;
using PlexRequests.Core.Migration; using PlexRequests.Core.Migration;
using PlexRequests.Services.Jobs;
using PlexRequests.Store.Models;
using PlexRequests.Store.Repository;
using PlexRequests.UI.Helpers; using PlexRequests.UI.Helpers;
using PlexRequests.UI.Jobs; using PlexRequests.UI.Jobs;
using PlexRequests.UI.NinjectModules; using PlexRequests.UI.NinjectModules;
@ -74,10 +78,18 @@ namespace PlexRequests.UI
Debug.WriteLine("Settings up Scheduler"); Debug.WriteLine("Settings up Scheduler");
var scheduler = new Scheduler(); var scheduler = new Scheduler();
scheduler.StartScheduler();
//var c = kernel.Get<IRecentlyAdded>();
//c.Test(); // Reset any jobs running
var jobSettings = kernel.Get<IRepository<ScheduledJobs>>();
var all = jobSettings.GetAll();
foreach (var scheduledJobse in all)
{
scheduledJobse.Running = false;
jobSettings.Update(scheduledJobse);
}
scheduler.StartScheduler();