cache the couchpotato wanted list, update it on an interval, and use it to determine if a movie has been queued already

pull/158/head
Drewster727 9 years ago
parent e8fb28a024
commit 6ed7df2c21

@ -36,5 +36,6 @@ namespace PlexRequests.Api.Interfaces
bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl, string profileID = default(string)); bool AddMovie(string imdbid, string apiKey, string title, Uri baseUrl, string profileID = default(string));
CouchPotatoStatus GetStatus(Uri url, string apiKey); CouchPotatoStatus GetStatus(Uri url, string apiKey);
CouchPotatoProfiles GetProfiles(Uri url, string apiKey); CouchPotatoProfiles GetProfiles(Uri url, string apiKey);
CouchPotatoMovies GetMovies(Uri baseUrl, string apiKey, string[] status);
} }
} }

@ -14,7 +14,7 @@ namespace PlexRequests.Api.Models.Movie
} }
public class Rating public class Rating
{ {
public List<double> imdb { get; set; } public List<string> imdb { get; set; }
} }
@ -23,15 +23,15 @@ namespace PlexRequests.Api.Models.Movie
{ {
public List<object> disc_art { get; set; } public List<object> disc_art { get; set; }
public List<string> poster { get; set; } public List<string> poster { get; set; }
public List<string> backdrop { get; set; }
public List<object> extra_thumbs { get; set; } public List<object> extra_thumbs { get; set; }
public List<string> poster_original { get; set; } public List<string> poster_original { get; set; }
public List<object> landscape { get; set; } public List<string> actors { get; set; }
public string[] actors { get; set; }
public List<string> backdrop_original { get; set; } public List<string> backdrop_original { get; set; }
public List<object> clear_art { get; set; } public List<object> clear_art { get; set; }
public List<object> logo { get; set; } public List<object> logo { get; set; }
public List<object> banner { get; set; } public List<object> banner { get; set; }
public List<string> backdrop { get; set; } public List<object> landscape { get; set; }
public List<object> extra_fanart { get; set; } public List<object> extra_fanart { get; set; }
} }
@ -42,16 +42,17 @@ namespace PlexRequests.Api.Models.Movie
public int tmdb_id { get; set; } public int tmdb_id { get; set; }
public string plot { get; set; } public string plot { get; set; }
public string tagline { get; set; } public string tagline { get; set; }
public Release_Date release_date { get; set; }
public int year { get; set; }
public string original_title { get; set; } public string original_title { get; set; }
public string[] actor_roles { get; set; } public List<string> actor_roles { get; set; }
public bool via_imdb { get; set; } public bool via_imdb { get; set; }
public string mpaa { get; set; } public Images images { get; set; }
public bool via_tmdb { get; set; }
public List<string> directors { get; set; } public List<string> directors { get; set; }
public List<string> titles { get; set; } public List<string> titles { get; set; }
public string imdb { get; set; } public string imdb { get; set; }
public int year { get; set; } public string mpaa { get; set; }
public Images images { get; set; } public bool via_tmdb { get; set; }
public List<string> actors { get; set; } public List<string> actors { get; set; }
public List<string> writers { get; set; } public List<string> writers { get; set; }
public int runtime { get; set; } public int runtime { get; set; }
@ -59,6 +60,19 @@ namespace PlexRequests.Api.Models.Movie
public string released { get; set; } public string released { get; set; }
} }
public class Release_Date
{
public int dvd { get; set; }
public int expires { get; set; }
public int theater { get; set; }
public bool bluray { get; set; }
}
public class Files
{
public List<string> image_poster { get; set; }
}
public class Identifiers public class Identifiers
{ {
public string imdb { get; set; } public string imdb { get; set; }
@ -74,8 +88,11 @@ namespace PlexRequests.Api.Models.Movie
public string _rev { get; set; } public string _rev { get; set; }
public string profile_id { get; set; } public string profile_id { get; set; }
public string _id { get; set; } public string _id { get; set; }
public List<object> tags { get; set; }
public int last_edit { get; set; }
public object category_id { get; set; } public object category_id { get; set; }
public string type { get; set; } public string type { get; set; }
public Files files { get; set; }
public Identifiers identifiers { get; set; } public Identifiers identifiers { get; set; }
} }

@ -0,0 +1,12 @@
using System.Collections.Generic;
namespace PlexRequests.Api.Models.Movie
{
public class CouchPotatoMovies
{
public List<Movie> movies { get; set; }
public int total { get; set; }
public bool success { get; set; }
public bool empty { get; set; }
}
}

@ -46,6 +46,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Movie\CouchPotatoAdd.cs" /> <Compile Include="Movie\CouchPotatoAdd.cs" />
<Compile Include="Movie\CouchPotatoMovies.cs" />
<Compile Include="Movie\CouchPotatoProfiles.cs" /> <Compile Include="Movie\CouchPotatoProfiles.cs" />
<Compile Include="Movie\CouchPotatoStatus.cs" /> <Compile Include="Movie\CouchPotatoStatus.cs" />
<Compile Include="Music\HeadphonesAlbumSearchResult.cs" /> <Compile Include="Music\HeadphonesAlbumSearchResult.cs" />

@ -115,5 +115,16 @@ namespace PlexRequests.Api
return Api.Execute<CouchPotatoProfiles>(request, url); return Api.Execute<CouchPotatoProfiles>(request, url);
} }
public CouchPotatoMovies GetMovies(Uri baseUrl, string apiKey, string[] status)
{
RestRequest request;
request = new RestRequest { Resource = "/api/{apikey}/movie.list?status={status}" };
request.AddUrlSegment("apikey", apiKey);
request.AddUrlSegment("status", string.Join(",", status));
return Api.Execute<CouchPotatoMovies>(request, baseUrl);
}
} }
} }

@ -31,6 +31,8 @@ namespace PlexRequests.Core
public const string TvDbToken = "TheTvDbApiToken"; public const string TvDbToken = "TheTvDbApiToken";
public const string SonarrQualityProfiles = "SonarrQualityProfiles"; public const string SonarrQualityProfiles = "SonarrQualityProfiles";
public const string SickRageQualityProfiles = "SickRageQualityProfiles"; public const string SickRageQualityProfiles = "SickRageQualityProfiles";
public const string CouchPotatoQualityProfiles = "CouchPotatoQualityProfiles"; public const string CouchPotatoQualityProfiles = "CouchPotatoQualityProfiles";
public const string CouchPotatoQueued = "CouchPotatoQueued";
} }
} }

@ -0,0 +1,77 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: PlexAvailabilityChecker.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 NLog;
using PlexRequests.Api.Interfaces;
using PlexRequests.Core;
using PlexRequests.Core.SettingModels;
using PlexRequests.Helpers;
using PlexRequests.Services.Interfaces;
using PlexRequests.Api.Models.Movie;
using System.Linq;
namespace PlexRequests.Services
{
public class CouchPotatoCacher : ICouchPotatoCacher
{
public CouchPotatoCacher(ISettingsService<CouchPotatoSettings> cpSettings, ICouchPotatoApi cpApi, ICacheProvider cache)
{
CpSettings = cpSettings;
CpApi = cpApi;
Cache = cache;
}
private ISettingsService<CouchPotatoSettings> CpSettings { get; }
private ICacheProvider Cache { get; }
private ICouchPotatoApi CpApi { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
public void Queued(long check)
{
Log.Trace("This is check no. {0}", check);
Log.Trace("Getting the settings");
var settings = CpSettings.GetSettings();
if (settings.Enabled)
{
Log.Trace("Getting all movies from CouchPotato");
var movies = CpApi.GetMovies(settings.FullUri, settings.ApiKey, new[] { "active" });
Cache.Set(CacheKeys.CouchPotatoQueued, movies, 10);
}
}
// we do not want to set here...
public int[] QueuedIds()
{
var movies = Cache.Get<CouchPotatoMovies>(CacheKeys.CouchPotatoQueued);
return movies != null ? movies.movies.Select(x => x.info.tmdb_id).ToArray() : new int[] { };
}
}
}

@ -0,0 +1,8 @@
namespace PlexRequests.Services.Interfaces
{
public interface ICouchPotatoCacher
{
void Queued(long check);
int[] QueuedIds();
}
}

@ -0,0 +1,89 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: AvailabilityUpdateService.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.Reactive.Linq;
using System.Web.Hosting;
using FluentScheduler;
using Mono.Data.Sqlite;
using NLog;
using PlexRequests.Api;
using PlexRequests.Core;
using PlexRequests.Core.SettingModels;
using PlexRequests.Helpers;
using PlexRequests.Services.Interfaces;
using PlexRequests.Store;
using PlexRequests.Store.Repository;
namespace PlexRequests.Services
{
public class MediaCacheService : ITask, IRegisteredObject, IAvailabilityUpdateService
{
public MediaCacheService()
{
var memCache = new MemoryCacheProvider();
var dbConfig = new DbConfiguration(new SqliteFactory());
var repo = new SettingsJsonRepository(dbConfig, memCache);
ConfigurationReader = new ConfigurationReader();
CpCacher = new CouchPotatoCacher(new SettingsServiceV2<CouchPotatoSettings>(repo), new CouchPotatoApi(), memCache);
HostingEnvironment.RegisterObject(this);
}
private static Logger Log = LogManager.GetCurrentClassLogger();
private IConfigurationReader ConfigurationReader { get; }
private ICouchPotatoCacher CpCacher { get; }
private IDisposable UpdateSubscription { get; set; }
public void Start(Configuration c)
{
UpdateSubscription?.Dispose();
CpCacher.Queued(-1);
UpdateSubscription = Observable.Interval(c.Intervals.Notification).Subscribe(CpCacher.Queued);
}
public void Execute()
{
Start(ConfigurationReader.Read());
}
public void Stop(bool immediate)
{
HostingEnvironment.UnregisterObject(this);
}
}
public interface ICouchPotatoCacheService
{
void Start(Configuration c);
}
}

@ -85,6 +85,7 @@ namespace PlexRequests.UI
// Services // Services
container.Register<IAvailabilityChecker, PlexAvailabilityChecker>(); container.Register<IAvailabilityChecker, PlexAvailabilityChecker>();
container.Register<ICouchPotatoCacher, CouchPotatoCacher>();
container.Register<IConfigurationReader, ConfigurationReader>(); container.Register<IConfigurationReader, ConfigurationReader>();
container.Register<IIntervals, UpdateInterval>(); container.Register<IIntervals, UpdateInterval>();
@ -106,6 +107,7 @@ namespace PlexRequests.UI
TaskManager.TaskFactory = new PlexTaskFactory(); TaskManager.TaskFactory = new PlexTaskFactory();
TaskManager.Initialize(new PlexRegistry()); TaskManager.Initialize(new PlexRegistry());
TaskManager.Initialize(new MediaCacheRegistry());
} }
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines) protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)

@ -0,0 +1,41 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: PlexRegistry.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 FluentScheduler;
using PlexRequests.Services;
namespace PlexRequests.UI.Jobs
{
public class MediaCacheRegistry : Registry
{
public MediaCacheRegistry()
{
Schedule<MediaCacheService>().ToRunNow();
}
}
}

@ -61,7 +61,7 @@ namespace PlexRequests.UI.Modules
ISettingsService<PlexRequestSettings> prSettings, IAvailabilityChecker checker, ISettingsService<PlexRequestSettings> prSettings, IAvailabilityChecker checker,
IRequestService request, ISonarrApi sonarrApi, ISettingsService<SonarrSettings> sonarrSettings, IRequestService request, ISonarrApi sonarrApi, ISettingsService<SonarrSettings> sonarrSettings,
ISettingsService<SickRageSettings> sickRageService, ICouchPotatoApi cpApi, ISickRageApi srApi, ISettingsService<SickRageSettings> sickRageService, ICouchPotatoApi cpApi, ISickRageApi srApi,
INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi, ISettingsService<HeadphonesSettings> hpService) : base("search") INotificationService notify, IMusicBrainzApi mbApi, IHeadphonesApi hpApi, ISettingsService<HeadphonesSettings> hpService, ICouchPotatoCacher cpCacher) : base("search")
{ {
CpService = cpSettings; CpService = cpSettings;
PrService = prSettings; PrService = prSettings;
@ -69,6 +69,7 @@ namespace PlexRequests.UI.Modules
TvApi = new TheTvDbApi(); TvApi = new TheTvDbApi();
Cache = cache; Cache = cache;
Checker = checker; Checker = checker;
CpCacher = cpCacher;
RequestService = request; RequestService = request;
SonarrApi = sonarrApi; SonarrApi = sonarrApi;
SonarrService = sonarrSettings; SonarrService = sonarrSettings;
@ -109,6 +110,7 @@ namespace PlexRequests.UI.Modules
private ISettingsService<SickRageSettings> SickRageService { get; } private ISettingsService<SickRageSettings> SickRageService { get; }
private ISettingsService<HeadphonesSettings> HeadphonesService { get; } private ISettingsService<HeadphonesSettings> HeadphonesService { get; }
private IAvailabilityChecker Checker { get; } private IAvailabilityChecker Checker { get; }
private ICouchPotatoCacher CpCacher { get; }
private IMusicBrainzApi MusicBrainzApi { get; } private IMusicBrainzApi MusicBrainzApi { get; }
private IHeadphonesApi HeadphonesApi { get; } private IHeadphonesApi HeadphonesApi { get; }
private static Logger Log = LogManager.GetCurrentClassLogger(); private static Logger Log = LogManager.GetCurrentClassLogger();
@ -150,6 +152,8 @@ namespace PlexRequests.UI.Modules
private Response ProcessMovies(MovieSearchType searchType, string searchTerm) private Response ProcessMovies(MovieSearchType searchType, string searchTerm)
{ {
List<Task> taskList = new List<Task>(); List<Task> taskList = new List<Task>();
var z = CpService.GetSettings();
CouchPotatoApi.GetMovies(z.FullUri, z.ApiKey, new[] { "active" });
List<MovieResult> apiMovies = new List<MovieResult>(); List<MovieResult> apiMovies = new List<MovieResult>();
taskList.Add(Task.Factory.StartNew<List<MovieResult>>(() => taskList.Add(Task.Factory.StartNew<List<MovieResult>>(() =>
@ -198,6 +202,8 @@ namespace PlexRequests.UI.Modules
Task.WaitAll(taskList.ToArray()); Task.WaitAll(taskList.ToArray());
int[] cpCached = CpCacher.QueuedIds();
List<SearchMovieViewModel> viewMovies = new List<SearchMovieViewModel>(); List<SearchMovieViewModel> viewMovies = new List<SearchMovieViewModel>();
foreach (MovieResult movie in apiMovies) foreach (MovieResult movie in apiMovies)
{ {
@ -219,7 +225,7 @@ namespace PlexRequests.UI.Modules
VoteCount = movie.VoteCount VoteCount = movie.VoteCount
}; };
if (dbMovies.ContainsKey(movie.Id)) if (dbMovies.ContainsKey(movie.Id)) // compare to the requests db
{ {
var dbm = dbMovies[movie.Id]; var dbm = dbMovies[movie.Id];
@ -227,6 +233,10 @@ namespace PlexRequests.UI.Modules
viewMovie.Approved = dbm.Approved; viewMovie.Approved = dbm.Approved;
viewMovie.Available = dbm.Available; viewMovie.Available = dbm.Available;
} }
else if (cpCached.Contains(movie.Id)) // compare to the couchpotato db
{
viewMovie.Requested = true;
}
viewMovies.Add(viewMovie); viewMovies.Add(viewMovie);
} }

@ -168,6 +168,7 @@
<Compile Include="Helpers\StringHelper.cs" /> <Compile Include="Helpers\StringHelper.cs" />
<Compile Include="Helpers\TvSender.cs" /> <Compile Include="Helpers\TvSender.cs" />
<Compile Include="Helpers\ValidationHelper.cs" /> <Compile Include="Helpers\ValidationHelper.cs" />
<Compile Include="Jobs\MediaCacheRegistry.cs" />
<Compile Include="Models\DatatablesModel.cs" /> <Compile Include="Models\DatatablesModel.cs" />
<Compile Include="Models\MovieSearchType.cs" /> <Compile Include="Models\MovieSearchType.cs" />
<Compile Include="Models\QualityModel.cs" /> <Compile Include="Models\QualityModel.cs" />

Loading…
Cancel
Save