diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs index a9e72dcd3..5be8f2ff3 100644 --- a/src/Ombi.Core/Engine/MovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs @@ -13,13 +13,15 @@ using Ombi.Core.Requests.Models; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Store.Entities; +using Ombi.Store.Repository; namespace Ombi.Core.Engine { public class MovieSearchEngine : BaseMediaEngine, IMovieEngine { - public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ISettingsService plexSettings, ISettingsService embySettings, + public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ISettingsService plexSettings, + ISettingsService embySettings, IPlexContentRepository repo, ILogger logger) : base(identity, service) { @@ -28,6 +30,7 @@ namespace Ombi.Core.Engine PlexSettings = plexSettings; EmbySettings = embySettings; Logger = logger; + PlexContentRepo = repo; } private IMovieDbApi MovieApi { get; } @@ -35,6 +38,7 @@ namespace Ombi.Core.Engine private ISettingsService PlexSettings { get; } private ISettingsService EmbySettings { get; } private ILogger Logger { get; } + private IPlexContentRepository PlexContentRepo { get; } public async Task> LookupImdbInformation(IEnumerable movies) { @@ -136,8 +140,17 @@ namespace Ombi.Core.Engine private async Task ProcessSingleMovie(SearchMovieViewModel viewMovie, Dictionary existingRequests, PlexSettings plexSettings, EmbySettings embySettings) { + var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id); if (plexSettings.Enable) { + + var item = await PlexContentRepo.Get(showInfo.ImdbId.ToString()); + if(item != null) + { + viewMovie.Available = true; + viewMovie.PlexUrl = item.Url; + } + // var content = PlexContentRepository.GetAll(); // var plexMovies = PlexChecker.GetPlexMovies(content); diff --git a/src/Ombi.Core/Engine/TvSearchEngine.cs b/src/Ombi.Core/Engine/TvSearchEngine.cs index 9dc0a7b99..229bb75a0 100644 --- a/src/Ombi.Core/Engine/TvSearchEngine.cs +++ b/src/Ombi.Core/Engine/TvSearchEngine.cs @@ -14,6 +14,7 @@ using Ombi.Core.Requests.Models; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Store.Entities; +using Ombi.Store.Repository; namespace Ombi.Core.Engine { @@ -21,13 +22,14 @@ namespace Ombi.Core.Engine { public TvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ISettingsService plexSettings, - ISettingsService embySettings) + ISettingsService embySettings, IPlexContentRepository repo) : base(identity, service) { TvMazeApi = tvMaze; Mapper = mapper; PlexSettings = plexSettings; EmbySettings = embySettings; + PlexContentRepo = repo; //TraktApi = trakt; } @@ -35,6 +37,7 @@ namespace Ombi.Core.Engine private IMapper Mapper { get; } private ISettingsService PlexSettings { get; } private ISettingsService EmbySettings { get; } + private IPlexContentRepository PlexContentRepo { get; } //private ITraktApi TraktApi { get; } @@ -91,7 +94,7 @@ namespace Ombi.Core.Engine var existingRequests = await GetTvRequests(); var plexSettings = await PlexSettings.GetSettingsAsync(); var embySettings = await EmbySettings.GetSettingsAsync(); - return ProcessResult(mapped, existingRequests, plexSettings, embySettings); + return await ProcessResult(mapped, existingRequests, plexSettings, embySettings); } //public async Task> Popular() @@ -127,12 +130,12 @@ namespace Ombi.Core.Engine foreach (var tvMazeSearch in items) { var viewT = Mapper.Map(tvMazeSearch); - retVal.Add(ProcessResult(viewT, existingRequests, plexSettings, embySettings)); + retVal.Add(await ProcessResult(viewT, existingRequests, plexSettings, embySettings)); } return retVal; } - private SearchTvShowViewModel ProcessResult(SearchTvShowViewModel item, Dictionary existingRequests, PlexSettings plexSettings, EmbySettings embySettings) + private async Task ProcessResult(SearchTvShowViewModel item, Dictionary existingRequests, PlexSettings plexSettings, EmbySettings embySettings) { if (embySettings.Enable) { @@ -144,6 +147,13 @@ namespace Ombi.Core.Engine } if (plexSettings.Enable) { + var content = await PlexContentRepo.Get(item.Id.ToString()); + + if (content != null) + { + item.Available = true; + item.PlexUrl = content.Url; + } //var plexShow = PlexChecker.GetTvShow(plexTvShows.ToArray(), t.show.name, t.show.premiered?.Substring(0, 4), // providerId); //if (plexShow != null) @@ -155,6 +165,8 @@ namespace Ombi.Core.Engine if (item.Id > 0 && item.Available) { + + // TODO need to check if the episodes are available var tvdbid = item.Id; if (existingRequests.ContainsKey(tvdbid)) { @@ -168,7 +180,7 @@ namespace Ombi.Core.Engine { foreach (var existingRequestChildRequest in existingRequest.ChildRequests) { - + // Find the existing request season var existingSeason = existingRequestChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber); diff --git a/src/Ombi.Schedule/JobSetup.cs b/src/Ombi.Schedule/JobSetup.cs index cee94cf0e..49ba396b8 100644 --- a/src/Ombi.Schedule/JobSetup.cs +++ b/src/Ombi.Schedule/JobSetup.cs @@ -14,7 +14,7 @@ namespace Ombi.Schedule private IPlexContentCacher Cacher { get; } public void Setup() { - RecurringJob.AddOrUpdate(() => Cacher.CacheContent(), Cron.Minutely); + RecurringJob.AddOrUpdate(() => Cacher.CacheContent(), Cron.Hourly); } } } diff --git a/src/Ombi.Schedule/Jobs/PlexContentCacher.cs b/src/Ombi.Schedule/Jobs/PlexContentCacher.cs index 4b8f6a7fe..318e1acce 100644 --- a/src/Ombi.Schedule/Jobs/PlexContentCacher.cs +++ b/src/Ombi.Schedule/Jobs/PlexContentCacher.cs @@ -126,17 +126,16 @@ namespace Ombi.Schedule.Jobs var allContent = GetAllContent(servers); // Let's now process this. - var contentToAdd = new List(); foreach (var content in allContent) { if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)) { // Process Shows - foreach (var metadata in content.Metadata) + foreach (var show in content.Metadata) { var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, - metadata.ratingKey); + show.ratingKey); var seasonsContent = new List(); foreach (var season in seasonList.MediaContainer.Metadata) { @@ -149,46 +148,83 @@ namespace Ombi.Schedule.Jobs } // Do we already have this item? - var existingContent = await Repo.GetByKey(metadata.key); + var existingContent = await Repo.GetByKey(show.ratingKey); if (existingContent != null) { // Ok so we have it, let's check if there are any new seasons - var seasonDifference = seasonsContent.Except(existingContent.Seasons).ToList(); - if (seasonDifference.Any()) + var itemAdded = false; + foreach (var season in seasonsContent) { - // We have new seasons on Plex, let's add them back into the entity - existingContent.Seasons.AddRange(seasonDifference); - await Repo.Update(existingContent); - continue; + var seasonExists = existingContent.Seasons.Where(x => x.SeasonKey == season.SeasonKey); + + if (seasonExists != null) + { + // We already have this season + continue; + } + else + { + existingContent.Seasons.Add(season); + itemAdded = true; + } } - else + + if (itemAdded) await Repo.Update(existingContent); + } + else + { + + // Get the show metadata... This sucks since the `metadata` var contains all information about the show + // But it does not contain the `guid` property that we need to pull out thetvdb id... + var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, + show.ratingKey); + var item = new PlexContent { - // No changes, no need to do anything - continue; - } + AddedAt = DateTime.Now, + Key = show.ratingKey, + ProviderId = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata + .FirstOrDefault() + .guid), + ReleaseYear = show.year.ToString(), + Type = PlexMediaTypeEntity.Show, + Title = show.title, + Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey), + Seasons = new List() + }; + + item.Seasons.ToList().AddRange(seasonsContent); + + contentToAdd.Add(item); + } + } + } + if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)) + { + foreach (var movie in content.Metadata) + { + // Let's check if we have this movie + var existing = await Repo.GetByKey(movie.ratingKey); + if(existing != null) + { + continue; } - // Get the show metadata... This sucks since the `metadata` var contains all information about the show - // But it does not contain the `guid` property that we need to pull out thetvdb id... - var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, - metadata.ratingKey); + var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, + movie.ratingKey); var item = new PlexContent { AddedAt = DateTime.Now, - Key = metadata.ratingKey, - ProviderId = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata - .FirstOrDefault() - .guid), - ReleaseYear = metadata.year.ToString(), - Type = PlexMediaTypeEntity.Show, - Title = metadata.title, - Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, metadata.ratingKey), + Key = movie.ratingKey, + ProviderId = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata + .FirstOrDefault() + .guid), + ReleaseYear = movie.year.ToString(), + Type = PlexMediaTypeEntity.Movie, + Title = movie.title, + Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), Seasons = new List() }; - - item.Seasons.AddRange(seasonsContent); - contentToAdd.Add(item); } } @@ -196,7 +232,8 @@ namespace Ombi.Schedule.Jobs if (contentToAdd.Any()) { - await Repo.AddRange(contentToAdd); + + contentToAdd.ForEach(async x => await Repo.Add(x)); } } diff --git a/src/Ombi.Store/Context/IOmbiContext.cs b/src/Ombi.Store/Context/IOmbiContext.cs index 56723762b..2b10503d7 100644 --- a/src/Ombi.Store/Context/IOmbiContext.cs +++ b/src/Ombi.Store/Context/IOmbiContext.cs @@ -15,8 +15,7 @@ namespace Ombi.Store.Context DbSet Settings { get; set; } DbSet PlexContent { get; set; } DbSet Users { get; set; } - EntityEntry Entry(GlobalSettings settings); - EntityEntry Entry(User settings); + EntityEntry Entry(T entry) where T : class; EntityEntry Attach(TEntity entity) where TEntity : class; } } \ No newline at end of file diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 06554379b..19a080aaf 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -37,14 +37,9 @@ namespace Ombi.Store.Context public DbSet PlexContent { get; set; } - public EntityEntry Entry(GlobalSettings settings) + public EntityEntry Entry(T entry) where T : class { - return base.Entry(settings); - } - - public EntityEntry Entry(User settings) - { - return base.Entry(settings); + return base.Entry(entry); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) diff --git a/src/Ombi.Store/Entities/PlexContent.cs b/src/Ombi.Store/Entities/PlexContent.cs index 0a32433ea..f5efa2f5d 100644 --- a/src/Ombi.Store/Entities/PlexContent.cs +++ b/src/Ombi.Store/Entities/PlexContent.cs @@ -44,7 +44,7 @@ namespace Ombi.Store.Entities /// /// Only used for TV Shows /// - public List Seasons { get; set; } + public virtual ICollection Seasons { get; set; } /// /// Plex's internal ID for this item @@ -55,6 +55,7 @@ namespace Ombi.Store.Entities public class SeasonsContent : Entity { + public int PlexContentId { get; set; } public int SeasonNumber { get; set; } public int SeasonKey { get; set; } public int ParentKey { get; set; } diff --git a/src/Ombi.Store/Repository/PlexContentRepository.cs b/src/Ombi.Store/Repository/PlexContentRepository.cs index 0a0ada0fb..48ee88e4e 100644 --- a/src/Ombi.Store/Repository/PlexContentRepository.cs +++ b/src/Ombi.Store/Repository/PlexContentRepository.cs @@ -50,7 +50,7 @@ namespace Ombi.Store.Repository public async Task AddRange(IEnumerable content) { - await Db.PlexContent.AddRangeAsync(content); + Db.PlexContent.AddRange(content); await Db.SaveChangesAsync(); } @@ -73,7 +73,7 @@ namespace Ombi.Store.Repository public async Task GetByKey(string key) { - return await Db.PlexContent.FirstOrDefaultAsync(x => x.Key == key); + return await Db.PlexContent.Include(x => x.Seasons).FirstOrDefaultAsync(x => x.Key == key); } public async Task Update(PlexContent existingContent) diff --git a/src/Ombi/Controllers/External/PlexController.cs b/src/Ombi/Controllers/External/PlexController.cs index 9ffccb7ad..de797416f 100644 --- a/src/Ombi/Controllers/External/PlexController.cs +++ b/src/Ombi/Controllers/External/PlexController.cs @@ -36,27 +36,37 @@ namespace Ombi.Controllers.External if (!string.IsNullOrEmpty(result.user?.authentication_token)) { var server = await PlexApi.GetServer(result.user.authentication_token); - var servers = server.Server; + var servers = server.Server.FirstOrDefault(); - settings.Servers = new List(); - var serverNumber = 0; - foreach (var s in servers) - { - if (string.IsNullOrEmpty(s.LocalAddresses) || string.IsNullOrEmpty(s.Port)) - { - continue; - } - settings.Servers.Add(new PlexServers - { - PlexAuthToken = result.user.authentication_token, + settings.Enable = true; + settings.Servers = new List { new PlexServers{ +PlexAuthToken = result.user.authentication_token, Id = new Random().Next(), - Ip = s.LocalAddresses.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(), - MachineIdentifier = s.MachineIdentifier, - Port = int.Parse(s.Port), - Ssl = s.Scheme != "http", - Name = $"Server{serverNumber++}" - }); + Ip = servers.LocalAddresses.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(), + MachineIdentifier = servers.MachineIdentifier, + Port = int.Parse(servers.Port), + Ssl = servers.Scheme != "http", + Name = $"Server 1", } + }; + //var serverNumber = 0; + //foreach (var s in servers) + //{ + // if (string.IsNullOrEmpty(s.LocalAddresses) || string.IsNullOrEmpty(s.Port)) + // { + // continue; + // } + // settings.Servers.Add(new PlexServers + // { + // PlexAuthToken = result.user.authentication_token, + // Id = new Random().Next(), + // Ip = s.LocalAddresses.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(), + // MachineIdentifier = s.MachineIdentifier, + // Port = int.Parse(s.Port), + // Ssl = s.Scheme != "http", + // Name = $"Server{serverNumber++}" + // }); + //} await PlexSettings.SaveSettingsAsync(settings); } @@ -72,6 +82,6 @@ namespace Ombi.Controllers.External return libs; } - + } } diff --git a/src/Ombi/wwwroot/app/search/moviesearch.component.html b/src/Ombi/wwwroot/app/search/moviesearch.component.html index 99022e6ce..92105b98a 100644 --- a/src/Ombi/wwwroot/app/search/moviesearch.component.html +++ b/src/Ombi/wwwroot/app/search/moviesearch.component.html @@ -85,6 +85,7 @@ +