private RuleResult CheckExistingContent(ChildRequests child, PlexServerContent content) { foreach (var season in child.SeasonRequests) { var episodesToRemove = new List <EpisodeRequests>(); var currentSeasonRequest = content.Episodes.Where(x => x.SeasonNumber == season.SeasonNumber).ToList(); if (!currentSeasonRequest.Any()) { continue; } foreach (var e in season.Episodes) { var existingEpRequest = currentSeasonRequest.FirstOrDefault(x => x.EpisodeNumber == e.EpisodeNumber); if (existingEpRequest != null) { episodesToRemove.Add(e); } } episodesToRemove.ForEach(x => { season.Episodes.Remove(x); }); } var anyEpisodes = child.SeasonRequests.SelectMany(x => x.Episodes).Any(); if (!anyEpisodes) { return(Fail(ErrorCode.EpisodesAlreadyRequested, $"We already have episodes requested from series {child.Title}")); } return(Success()); }
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable <PlexEpisode> allEpisodes, EpisodeRequests episode, SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb) { PlexEpisode epExists = null; if (useImdb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.ImdbId == item.ImdbId.ToString()); } if (useTheMovieDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.TheMovieDbId == item.TheMovieDbId.ToString()); } if (useTvDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.TvDbId == item.TvDbId.ToString()); } if (epExists != null) { episode.Available = true; } }
private async Task ProcessMovies() { // Get all non available var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available); var itemsForAvailbility = new List <AvailabilityModel>(); foreach (var movie in movies) { if (movie.Available) { return; } PlexServerContent item = null; if (movie.ImdbId.HasValue()) { item = await _repo.Get(movie.ImdbId, ProviderType.ImdbId); } if (item == null) { if (movie.TheMovieDbId.ToString().HasValue()) { item = await _repo.Get(movie.TheMovieDbId.ToString(), ProviderType.TheMovieDbId); } } if (item == null) { // We don't yet have this continue; } _log.LogInformation("[PAC] - Movie request {0} is now available, sending notification", $"{movie.Title} - {movie.Id}"); movie.Available = true; movie.MarkedAsAvailable = DateTime.UtcNow; itemsForAvailbility.Add(new AvailabilityModel { Id = movie.Id, RequestedUser = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty }); } if (itemsForAvailbility.Any()) { await _movieRepo.SaveChangesAsync(); } foreach (var i in itemsForAvailbility) { await _notificationService.Notify(new NotificationOptions { DateTime = DateTime.Now, NotificationType = NotificationType.RequestAvailable, RequestId = i.Id, RequestType = RequestType.Movie, Recipient = i.RequestedUser }); } //await _repo.SaveChangesAsync(); }
private async Task ProcessMovies() { // Get all non available var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available); foreach (var movie in movies) { PlexServerContent item = null; if (movie.ImdbId.HasValue()) { item = await _repo.Get(movie.ImdbId); } if (item == null) { if (movie.TheMovieDbId.ToString().HasValue()) { item = await _repo.Get(movie.TheMovieDbId.ToString()); } } if (item == null) { // We don't yet have this continue; } movie.Available = true; movie.MarkedAsAvailable = DateTime.Now; item.RequestId = movie.Id; _log.LogInformation("[PAC] - Movie request {0} is now available, sending notification", $"{movie.Title} - {movie.Id}"); await _notificationService.Notify(new NotificationOptions { DateTime = DateTime.Now, NotificationType = NotificationType.RequestAvailable, RequestId = movie.Id, RequestType = RequestType.Movie, Recipient = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty }); } await _movieRepo.Save(); await _repo.SaveChangesAsync(); }
private async Task ProcessMovies() { // Get all non available var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available); foreach (var movie in movies) { PlexServerContent item = null; if (movie.ImdbId.HasValue()) { item = await _repo.Get(movie.ImdbId); } if (item == null) { if (movie.TheMovieDbId.ToString().HasValue()) { item = await _repo.Get(movie.TheMovieDbId.ToString()); } } if (item == null) { // We don't yet have this continue; } movie.Available = true; movie.MarkedAsAvailable = DateTime.Now; if (movie.Available) { _backgroundJobClient.Enqueue(() => _notificationService.Publish(new NotificationOptions { DateTime = DateTime.Now, NotificationType = NotificationType.RequestAvailable, RequestId = movie.Id, RequestType = RequestType.Movie, Recipient = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty })); } } await _movieRepo.Save(); }
private async Task GetProviderIds(PlexMetadata showMetadata, PlexServerContent existingContent) { var metadata = showMetadata.MediaContainer.Metadata.FirstOrDefault(); var guids = new List <string> { metadata.guid }; if (metadata.Guid != null) { foreach (var g in metadata.Guid) { guids.Add(g.Id); } } var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); if (providerIds.ImdbId.HasValue()) { existingContent.ImdbId = providerIds.ImdbId; } if (providerIds.TheMovieDb.HasValue()) { existingContent.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.TheTvDb.HasValue()) { // Lookup TheMovieDbId var findResult = await _movieApi.Find(providerIds.TheTvDb, ExternalSource.tvdb_id); var tvResult = findResult.tv_results.FirstOrDefault(); if (tvResult != null) { existingContent.TheMovieDbId = tvResult.id.ToString(); } existingContent.TvDbId = providerIds.TheTvDb; } }
private static void GetProviderIds(PlexMetadata showMetadata, PlexServerContent existingContent) { var providerIds = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata.FirstOrDefault() .guid); if (providerIds.Type == ProviderType.ImdbId) { existingContent.ImdbId = providerIds.ImdbId; } if (providerIds.Type == ProviderType.TheMovieDbId) { existingContent.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.Type == ProviderType.TvDbId) { existingContent.TvDbId = providerIds.TheTvDb; } }
private RuleResult CheckExistingContent(ChildRequests child, PlexServerContent content) { foreach (var season in child.SeasonRequests) { var currentSeasonRequest = content.Episodes.Where(x => x.SeasonNumber == season.SeasonNumber).ToList(); if (!currentSeasonRequest.Any()) { continue; } foreach (var e in season.Episodes) { var hasEpisode = currentSeasonRequest.Any(x => x.EpisodeNumber == e.EpisodeNumber); if (hasEpisode) { return(Fail($"We already have episodes requested from series {child.Title}")); } } } return(Success()); }
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable <PlexEpisode> allEpisodes, EpisodeRequests episode, SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log) { PlexEpisode epExists = null; try { if (useImdb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.ImdbId == item.ImdbId); } if (useTheMovieDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.TheMovieDbId == item.TheMovieDbId); } if (useTvDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.TvDbId == item.TvDbId); } } catch (Exception e) { log.LogError(e, "Exception thrown when attempting to check if something is available"); } if (epExists != null) { episode.Available = true; } }
private async Task ProcessTvShow(PlexServers servers, Metadata show, HashSet <PlexServerContent> contentToAdd, Dictionary <int, int> contentProcessed) { var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, show.ratingKey); var seasonsContent = new List <PlexSeasonsContent>(); foreach (var season in seasonList.MediaContainer.Metadata) { seasonsContent.Add(new PlexSeasonsContent { ParentKey = season.parentRatingKey, SeasonKey = season.ratingKey, SeasonNumber = season.index, PlexContentId = show.ratingKey }); } // Do we already have this item? // Let's try and match var existingContent = await Repo.GetFirstContentByCustom(x => x.Title == show.title && x.ReleaseYear == show.year.ToString() && x.Type == PlexMediaTypeEntity.Show); // Just double check the rating key, since this is our unique constraint var existingKey = await Repo.GetByKey(show.ratingKey); if (existingKey != null) { // Damn son. // Let's check if they match up var doesMatch = show.title.Equals(existingKey.Title, StringComparison.CurrentCulture); if (!doesMatch) { // Something f****d up on Plex at somepoint... Damn, rebuild of lib maybe? // Lets delete the matching key await Repo.Delete(existingKey); existingKey = null; } else if (existingContent == null) { existingContent = await Repo.GetFirstContentByCustom(x => x.Key == show.ratingKey); } } if (existingContent != null) { // Let's make sure that we have some sort of ID e.g. Imdbid for this, // Looks like it's possible to not have an Id for a show // I suspect we cached that show just as it was added to Plex. if (!existingContent.HasImdb && !existingContent.HasTheMovieDb && !existingContent.HasTvDb) { var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, existingContent.Key); GetProviderIds(showMetadata, existingContent); await Repo.Update(existingContent); } // Just check the key if (existingKey != null) { // The rating key is all good! } else { // This means the rating key has changed somehow. // Should probably delete this and get the new one var oldKey = existingContent.Key; Repo.DeleteWithoutSave(existingContent); // Because we have changed the rating key, we need to change all children too var episodeToChange = Repo.GetAllEpisodes().Where(x => x.GrandparentKey == oldKey); if (episodeToChange.Any()) { foreach (var e in episodeToChange) { Repo.DeleteWithoutSave(e); } } await Repo.SaveChangesAsync(); existingContent = null; } } // Also make sure it's not already being processed... var alreadyProcessed = contentProcessed.Select(x => x.Value).Any(x => x == show.ratingKey); if (alreadyProcessed) { return; } // The ratingKey keeps changing... //var existingContent = await Repo.GetByKey(show.ratingKey); if (existingContent != null) { try { Logger.LogDebug("We already have show {0} checking for new seasons", existingContent.Title); // Ok so we have it, let's check if there are any new seasons var itemAdded = false; foreach (var season in seasonsContent) { var seasonExists = existingContent.Seasons.FirstOrDefault(x => x.SeasonKey == season.SeasonKey); if (seasonExists != null) { // We already have this season // check if we have the episode //if (episode != null) //{ // var existing = existingContent.Episodes.Any(x => // x.SeasonNumber == episode.parentIndex && x.EpisodeNumber == episode.index); // if (!existing) // { // // We don't have this episode, lets add it // existingContent.Episodes.Add(new PlexEpisode // { // EpisodeNumber = episode.index, // SeasonNumber = episode.parentIndex, // GrandparentKey = episode.grandparentRatingKey, // ParentKey = episode.parentRatingKey, // Key = episode.ratingKey, // Title = episode.title // }); // itemAdded = true; // } //} continue; } existingContent.Seasons.Add(season); itemAdded = true; } if (itemAdded) { await Repo.Update(existingContent); } } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new seasons to title {0}", existingContent.Title); } } else { try { Logger.LogDebug("New show {0}, so add it", show.title); // 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 PlexServerContent { AddedAt = DateTime.Now, Key = show.ratingKey, ReleaseYear = show.year.ToString(), Type = PlexMediaTypeEntity.Show, Title = show.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey), Seasons = new List <PlexSeasonsContent>() }; GetProviderIds(showMetadata, item); // Let's just double check to make sure we do not have it now we have some id's var existingImdb = false; var existingMovieDbId = false; var existingTvDbId = false; if (item.ImdbId.HasValue()) { existingImdb = await Repo.GetAll().AnyAsync(x => x.ImdbId == item.ImdbId && x.Type == PlexMediaTypeEntity.Show); } if (item.TheMovieDbId.HasValue()) { existingMovieDbId = await Repo.GetAll().AnyAsync(x => x.TheMovieDbId == item.TheMovieDbId && x.Type == PlexMediaTypeEntity.Show); } if (item.TvDbId.HasValue()) { existingTvDbId = await Repo.GetAll().AnyAsync(x => x.TvDbId == item.TvDbId && x.Type == PlexMediaTypeEntity.Show); } if (existingImdb || existingTvDbId || existingMovieDbId) { // We already have it! return; } item.Seasons.ToList().AddRange(seasonsContent); contentToAdd.Add(item); } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding tv show {0}", show.title); } } }
private async Task <ProcessedContent> ProcessServer(PlexServers servers, bool recentlyAddedSearch) { var retVal = new ProcessedContent(); var contentProcessed = new Dictionary <int, int>(); var episodesProcessed = new List <int>(); Logger.LogDebug("Getting all content from server {0}", servers.Name); var allContent = await GetAllContent(servers, recentlyAddedSearch); Logger.LogDebug("We found {0} items", allContent.Count); // Let's now process this. var contentToAdd = new HashSet <PlexServerContent>(); var allEps = Repo.GetAllEpisodes(); foreach (var content in allContent) { if (content.viewGroup.Equals(PlexMediaType.Episode.ToString(), StringComparison.CurrentCultureIgnoreCase)) { Logger.LogDebug("Found some episodes, this must be a recently added sync"); var count = 0; foreach (var epInfo in content.Metadata ?? new Metadata[] {}) { count++; var grandParentKey = epInfo.grandparentRatingKey; // Lookup the rating key var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, grandParentKey); var show = showMetadata.MediaContainer.Metadata.FirstOrDefault(); if (show == null) { continue; } await ProcessTvShow(servers, show, contentToAdd, contentProcessed); if (contentToAdd.Any()) { await Repo.AddRange(contentToAdd, false); if (recentlyAddedSearch) { foreach (var plexServerContent in contentToAdd) { contentProcessed.Add(plexServerContent.Id, plexServerContent.Key); } } contentToAdd.Clear(); } if (count > 200) { await Repo.SaveChangesAsync(); } } // Save just to make sure we don't leave anything hanging await Repo.SaveChangesAsync(); if (content.Metadata != null) { var episodesAdded = await EpisodeSync.ProcessEpsiodes(content.Metadata, allEps); episodesProcessed.AddRange(episodesAdded.Select(x => x.Id)); } } if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)) { // Process Shows Logger.LogDebug("Processing TV Shows"); var count = 0; foreach (var show in content.Metadata ?? new Metadata[] { }) { count++; await ProcessTvShow(servers, show, contentToAdd, contentProcessed); if (contentToAdd.Any()) { await Repo.AddRange(contentToAdd, false); if (recentlyAddedSearch) { foreach (var plexServerContent in contentToAdd) { contentProcessed.Add(plexServerContent.Id, plexServerContent.Key); } } contentToAdd.Clear(); } if (count > 200) { await Repo.SaveChangesAsync(); } } await Repo.SaveChangesAsync(); } if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)) { Logger.LogDebug("Processing Movies"); foreach (var movie in content?.Metadata ?? new Metadata[] { }) { // Let's check if we have this movie try { var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title && x.ReleaseYear == movie.year.ToString() && x.Type == PlexMediaTypeEntity.Movie); // The rating key keeps changing //var existing = await Repo.GetByKey(movie.ratingKey); if (existing != null) { Logger.LogDebug("We already have movie {0}", movie.title); continue; } var hasSameKey = await Repo.GetByKey(movie.ratingKey); if (hasSameKey != null) { await Repo.Delete(hasSameKey); } Logger.LogDebug("Adding movie {0}", movie.title); var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, movie.ratingKey); var providerIds = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata .FirstOrDefault() .guid); var item = new PlexServerContent { AddedAt = DateTime.Now, Key = movie.ratingKey, ReleaseYear = movie.year.ToString(), Type = PlexMediaTypeEntity.Movie, Title = movie.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), Seasons = new List <PlexSeasonsContent>(), Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty }; if (providerIds.Type == ProviderType.ImdbId) { item.ImdbId = providerIds.ImdbId; } if (providerIds.Type == ProviderType.TheMovieDbId) { item.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.Type == ProviderType.TvDbId) { item.TvDbId = providerIds.TheTvDb; } contentToAdd.Add(item); } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}", movie.title); } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); foreach (var c in contentToAdd) { contentProcessed.Add(c.Id, c.Key); } contentToAdd.Clear(); } } } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); foreach (var c in contentToAdd) { contentProcessed.Add(c.Id, c.Key); } contentToAdd.Clear(); } } if (contentToAdd.Any()) { await Repo.AddRange(contentToAdd); foreach (var c in contentToAdd) { contentProcessed.Add(c.Id, c.Key); } } retVal.Content = contentProcessed.Values; retVal.Episodes = episodesProcessed; return(retVal); }
private async Task ProcessServer(PlexServers servers, bool recentlyAddedSearch) { Logger.LogInformation("Getting all content from server {0}", servers.Name); var allContent = await GetAllContent(servers, recentlyAddedSearch); Logger.LogInformation("We found {0} items", allContent.Count); // Let's now process this. var contentToAdd = new HashSet <PlexServerContent>(); foreach (var content in allContent) { if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)) { // Process Shows Logger.LogInformation("Processing TV Shows"); foreach (var show in content.Metadata ?? new Metadata[] { }) { var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, show.ratingKey); var seasonsContent = new List <PlexSeasonsContent>(); foreach (var season in seasonList.MediaContainer.Metadata) { seasonsContent.Add(new PlexSeasonsContent { ParentKey = season.parentRatingKey, SeasonKey = season.ratingKey, SeasonNumber = season.index, PlexContentId = show.ratingKey }); } // Do we already have this item? // Let's try and match var existingContent = await Repo.GetFirstContentByCustom(x => x.Title == show.title && x.ReleaseYear == show.year.ToString() && x.Type == PlexMediaTypeEntity.Show); // Just double check the rating key, since this is our unique constraint var existingKey = await Repo.GetByKey(show.ratingKey); if (existingKey != null) { // Damn son. // Let's check if they match up var doesMatch = show.title.Equals(existingKey.Title, StringComparison.CurrentCulture); if (!doesMatch) { // Something f****d up on Plex at somepoint... Damn, rebuild of lib maybe? // Lets delete the matching key await Repo.Delete(existingKey); existingKey = null; } } if (existingContent != null) { // Just check the key if (existingKey != null) { // The rating key is all good! } else { // This means the rating key has changed somehow. // Should probably delete this and get the new one var oldKey = existingContent.Key; Repo.DeleteWithoutSave(existingContent); // Because we have changed the rating key, we need to change all children too var episodeToChange = Repo.GetAllEpisodes().Where(x => x.GrandparentKey == oldKey); if (episodeToChange.Any()) { foreach (var e in episodeToChange) { Repo.DeleteWithoutSave(e); } } await Repo.SaveChangesAsync(); existingContent = null; } } // The ratingKey keeps changing... //var existingContent = await Repo.GetByKey(show.ratingKey); if (existingContent != null) { try { Logger.LogInformation("We already have show {0} checking for new seasons", existingContent.Title); // Ok so we have it, let's check if there are any new seasons var itemAdded = false; foreach (var season in seasonsContent) { var seasonExists = existingContent.Seasons.FirstOrDefault(x => x.SeasonKey == season.SeasonKey); if (seasonExists != null) { // We already have this season continue; } existingContent.Seasons.Add(season); itemAdded = true; } if (itemAdded) { await Repo.Update(existingContent); } } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new seasons to title {0}", existingContent.Title); } } else { try { Logger.LogInformation("New show {0}, so add it", show.title); // 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 providerIds = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata.FirstOrDefault() .guid); var item = new PlexServerContent { AddedAt = DateTime.Now, Key = show.ratingKey, ReleaseYear = show.year.ToString(), Type = PlexMediaTypeEntity.Show, Title = show.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey), Seasons = new List <PlexSeasonsContent>() }; if (providerIds.Type == ProviderType.ImdbId) { item.ImdbId = providerIds.ImdbId; } if (providerIds.Type == ProviderType.TheMovieDbId) { item.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.Type == ProviderType.TvDbId) { item.TvDbId = providerIds.TheTvDb; } // Let's just double check to make sure we do not have it now we have some id's var existingImdb = false; var existingMovieDbId = false; var existingTvDbId = false; if (item.ImdbId.HasValue()) { existingImdb = await Repo.GetAll().AnyAsync(x => x.ImdbId == item.ImdbId && x.Type == PlexMediaTypeEntity.Show); } if (item.TheMovieDbId.HasValue()) { existingMovieDbId = await Repo.GetAll().AnyAsync(x => x.TheMovieDbId == item.TheMovieDbId && x.Type == PlexMediaTypeEntity.Show); } if (item.TvDbId.HasValue()) { existingTvDbId = await Repo.GetAll().AnyAsync(x => x.TvDbId == item.TvDbId && x.Type == PlexMediaTypeEntity.Show); } if (existingImdb || existingTvDbId || existingMovieDbId) { // We already have it! continue; } item.Seasons.ToList().AddRange(seasonsContent); contentToAdd.Add(item); } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding tv show {0}", show.title); } } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); contentToAdd.Clear(); } } } if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)) { Logger.LogInformation("Processing Movies"); foreach (var movie in content?.Metadata ?? new Metadata[] { }) { // Let's check if we have this movie try { var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title && x.ReleaseYear == movie.year.ToString() && x.Type == PlexMediaTypeEntity.Movie); // The rating key keeps changing //var existing = await Repo.GetByKey(movie.ratingKey); if (existing != null) { Logger.LogInformation("We already have movie {0}", movie.title); continue; } var hasSameKey = await Repo.GetByKey(movie.ratingKey); if (hasSameKey != null) { await Repo.Delete(hasSameKey); } Logger.LogInformation("Adding movie {0}", movie.title); var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, movie.ratingKey); var providerIds = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata .FirstOrDefault() .guid); var item = new PlexServerContent { AddedAt = DateTime.Now, Key = movie.ratingKey, ReleaseYear = movie.year.ToString(), Type = PlexMediaTypeEntity.Movie, Title = movie.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), Seasons = new List <PlexSeasonsContent>(), Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty }; if (providerIds.Type == ProviderType.ImdbId) { item.ImdbId = providerIds.ImdbId; } if (providerIds.Type == ProviderType.TheMovieDbId) { item.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.Type == ProviderType.TvDbId) { item.TvDbId = providerIds.TheTvDb; } contentToAdd.Add(item); } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}", movie.title); } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); contentToAdd.Clear(); } } } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); contentToAdd.Clear(); } } if (contentToAdd.Any()) { await Repo.AddRange(contentToAdd); } }
private async Task ProcessMovies() { var feature4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); // Get all non available var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)); var itemsForAvailbility = new List <AvailabilityModel>(); foreach (var movie in movies) { var has4kRequest = movie.Has4KRequest; PlexServerContent item = null; if (movie.ImdbId.HasValue()) { item = await _repo.Get(movie.ImdbId, ProviderType.ImdbId); } if (item == null) { if (movie.TheMovieDbId.ToString().HasValue()) { item = await _repo.Get(movie.TheMovieDbId.ToString(), ProviderType.TheMovieDbId); } } if (item == null) { // We don't yet have this continue; } _log.LogInformation($"[PAC] - Movie request {movie.Title} - {movie.Id} is now available, sending notification"); var notify = false; if (has4kRequest && item.Has4K && !movie.Available4K && feature4kEnabled) { movie.Available4K = true; movie.Approved4K = true; movie.MarkedAsAvailable4K = DateTime.Now; await _movieRepo.SaveChangesAsync(); notify = true; } if (!feature4kEnabled && !movie.Available) { movie.Available = true; movie.MarkedAsAvailable = DateTime.Now; await _movieRepo.SaveChangesAsync(); notify = true; } // If we have a non-4k versison then mark as available if (item.Quality != null && !movie.Available) { movie.Available = true; movie.Approved = true; movie.MarkedAsAvailable = DateTime.Now; await _movieRepo.SaveChangesAsync(); notify = true; } if (notify) { itemsForAvailbility.Add(new AvailabilityModel { Id = movie.Id, RequestedUser = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty }); } } foreach (var i in itemsForAvailbility.DistinctBy(x => x.Id)) { await _notificationService.Notify(new NotificationOptions { DateTime = DateTime.Now, NotificationType = NotificationType.RequestAvailable, RequestId = i.Id, RequestType = RequestType.Movie, Recipient = i.RequestedUser }); } }
public async Task MovieLoop(PlexServers servers, Mediacontainer content, HashSet <PlexServerContent> contentToAdd, Dictionary <int, int> contentProcessed) { Logger.LogDebug("Processing Movies"); foreach (var movie in content?.Metadata ?? new Metadata[] { }) { // Let's check if we have this movie try { var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title && x.ReleaseYear == movie.year.ToString() && x.Type == PlexMediaTypeEntity.Movie); // The rating key keeps changing //var existing = await Repo.GetByKey(movie.ratingKey); if (existing != null) { Logger.LogDebug("We already have movie {0}", movie.title); continue; } var hasSameKey = await Repo.GetByKey(movie.ratingKey); if (hasSameKey != null) { await Repo.Delete(hasSameKey); } Logger.LogDebug("Adding movie {0}", movie.title); var guids = new List <string>(); if (!movie.Guid.Any()) { var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, movie.ratingKey); var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); guids.Add(meta.guid); if (meta.Guid != null) { foreach (var g in meta.Guid) { guids.Add(g.Id); } } } else { // Currently a Plex Pass feature only foreach (var g in movie.Guid) { guids.Add(g.Id); } } var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); var item = new PlexServerContent { AddedAt = DateTime.Now, Key = movie.ratingKey, ReleaseYear = movie.year.ToString(), Type = PlexMediaTypeEntity.Movie, Title = movie.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), Seasons = new List <PlexSeasonsContent>(), Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty }; if (providerIds.ImdbId.HasValue()) { item.ImdbId = providerIds.ImdbId; } if (providerIds.TheMovieDb.HasValue()) { item.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.TheTvDb.HasValue()) { item.TvDbId = providerIds.TheTvDb; } contentToAdd.Add(item); } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}", movie.title); } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); foreach (var c in contentToAdd) { contentProcessed.Add(c.Id, c.Key); } contentToAdd.Clear(); } } }
public async Task <RuleResult> Execute(SearchViewModel obj) { PlexServerContent item = null; var useImdb = false; var useTheMovieDb = false; var useTvDb = false; if (obj.ImdbId.HasValue()) { item = await PlexContentRepository.Get(obj.ImdbId); if (item != null) { useImdb = true; } } if (item == null) { if (obj.TheMovieDbId.HasValue()) { item = await PlexContentRepository.Get(obj.TheMovieDbId); if (item != null) { useTheMovieDb = true; } } if (item == null) { if (obj.TheTvDbId.HasValue()) { item = await PlexContentRepository.Get(obj.TheTvDbId); if (item != null) { useTvDb = true; } } } } if (item != null) { obj.Available = true; obj.PlexUrl = item.Url; obj.Quality = item.Quality; if (obj.Type == RequestType.TvShow) { var search = (SearchTvShowViewModel)obj; // Let's go through the episodes now if (search.SeasonRequests.Any()) { var allEpisodes = PlexContentRepository.GetAllEpisodes(); foreach (var season in search.SeasonRequests) { foreach (var episode in season.Episodes) { await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb); } } AvailabilityRuleHelper.CheckForUnairedEpisodes(search); } } } return(Success()); }
private async Task StartTheCache(PlexSettings plexSettings) { foreach (var servers in plexSettings.Servers ?? new List <PlexServers>()) { Logger.LogInformation("Getting all content from server {0}", servers.Name); var allContent = await GetAllContent(servers); Logger.LogInformation("We found {0} items", allContent.Count); // Let's now process this. var contentToAdd = new List <PlexServerContent>(); foreach (var content in allContent) { if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)) { // Process Shows Logger.LogInformation("Processing TV Shows"); foreach (var show in content.Metadata ?? new Metadata[] { }) { var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, show.ratingKey); var seasonsContent = new List <PlexSeasonsContent>(); foreach (var season in seasonList.MediaContainer.Metadata) { seasonsContent.Add(new PlexSeasonsContent { ParentKey = season.parentRatingKey, SeasonKey = season.ratingKey, SeasonNumber = season.index, PlexContentId = show.ratingKey }); } // Do we already have this item? // Let's try and match var existingContent = await Repo.GetFirstContentByCustom(x => x.Title == show.title && x.ReleaseYear == show.year.ToString() && x.Type == PlexMediaTypeEntity.Show); if (existingContent == null) { // Just check the key var hasSameKey = await Repo.GetByKey(show.ratingKey); if (hasSameKey != null) { existingContent = hasSameKey; } } // The ratingKey keeps changing... //var existingContent = await Repo.GetByKey(show.ratingKey); if (existingContent != null) { try { Logger.LogInformation("We already have show {0} checking for new seasons", existingContent.Title); // Ok so we have it, let's check if there are any new seasons var itemAdded = false; foreach (var season in seasonsContent) { var seasonExists = existingContent.Seasons.FirstOrDefault(x => x.SeasonKey == season.SeasonKey); if (seasonExists != null) { // We already have this season continue; } existingContent.Seasons.Add(season); itemAdded = true; } if (itemAdded) { await Repo.Update(existingContent); } } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new seasons to title {0}", existingContent.Title); } } else { Logger.LogInformation("New show {0}, so add it", show.title); // 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 providerIds = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata.FirstOrDefault().guid); var item = new PlexServerContent { AddedAt = DateTime.Now, Key = show.ratingKey, ReleaseYear = show.year.ToString(), Type = PlexMediaTypeEntity.Show, Title = show.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey), Seasons = new List <PlexSeasonsContent>() }; if (providerIds.Type == ProviderType.ImdbId) { item.ImdbId = providerIds.ImdbId; } if (providerIds.Type == ProviderType.TheMovieDbId) { item.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.Type == ProviderType.TvDbId) { item.TvDbId = providerIds.TheTvDb; } item.Seasons.ToList().AddRange(seasonsContent); contentToAdd.Add(item); } } } if (content.viewGroup.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)) { Logger.LogInformation("Processing Movies"); foreach (var movie in content?.Metadata ?? new Metadata[] { }) { // Let's check if we have this movie var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title && x.ReleaseYear == movie.year.ToString() && x.Type == PlexMediaTypeEntity.Movie); // The rating key keeps changing //var existing = await Repo.GetByKey(movie.ratingKey); if (existing != null) { Logger.LogInformation("We already have movie {0}", movie.title); continue; } var hasSameKey = await Repo.GetByKey(movie.ratingKey); if (hasSameKey != null) { await Repo.Delete(hasSameKey); } Logger.LogInformation("Adding movie {0}", movie.title); var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, movie.ratingKey); var providerIds = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.Metadata .FirstOrDefault() .guid); var item = new PlexServerContent { AddedAt = DateTime.Now, Key = movie.ratingKey, ReleaseYear = movie.year.ToString(), Type = PlexMediaTypeEntity.Movie, Title = movie.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), Seasons = new List <PlexSeasonsContent>(), Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty }; if (providerIds.Type == ProviderType.ImdbId) { item.ImdbId = providerIds.ImdbId; } if (providerIds.Type == ProviderType.TheMovieDbId) { item.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.Type == ProviderType.TvDbId) { item.TvDbId = providerIds.TheTvDb; } contentToAdd.Add(item); } } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); contentToAdd = new List <PlexServerContent>(); } } if (contentToAdd.Any()) { await Repo.AddRange(contentToAdd); } } }
public async Task <RuleResult> Execute(SearchViewModel obj) { PlexServerContent item = null; var useImdb = false; var useTheMovieDb = false; var useTvDb = false; if (obj.ImdbId.HasValue()) { item = await PlexContentRepository.Get(obj.ImdbId); if (item != null) { useImdb = true; } } if (item == null) { if (obj.TheMovieDbId.HasValue()) { item = await PlexContentRepository.Get(obj.TheMovieDbId); if (item != null) { useTheMovieDb = true; } } if (item == null) { if (obj.TheTvDbId.HasValue()) { item = await PlexContentRepository.Get(obj.TheTvDbId); if (item != null) { useTvDb = true; } } } } if (item != null) { obj.Available = true; obj.PlexUrl = item.Url; obj.Quality = item.Quality; if (obj.Type == RequestType.TvShow) { var search = (SearchTvShowViewModel)obj; // Let's go through the episodes now if (search.SeasonRequests.Any()) { var allEpisodes = PlexContentRepository.GetAllEpisodes(); foreach (var season in search.SeasonRequests) { foreach (var episode in season.Episodes) { PlexEpisode epExists = null; if (useImdb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.ImdbId == item.ImdbId.ToString()); } if (useTheMovieDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.TheMovieDbId == item.TheMovieDbId.ToString()); } if (useTvDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.TvDbId == item.TvDbId.ToString()); } if (epExists != null) { episode.Available = true; } } } if (search.SeasonRequests.All(x => x.Episodes.All(e => e.Available))) { search.FullyAvailable = true; } } } } return(Success()); }
public async Task MovieLoop(PlexServers servers, Mediacontainer content, HashSet <PlexServerContent> contentToAdd, Dictionary <int, string> contentProcessed) { Logger.LogDebug("Processing Movies"); foreach (var movie in content?.Metadata ?? Array.Empty <Metadata>()) { // Let's check if we have this movie try { var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title && x.ReleaseYear == movie.year.ToString() && x.Type == MediaType.Movie); if (existing != null) { // We need to see if this is a different quality, // We want to know if this is a 4k content for example var foundQualities = movie.Media?.Select(x => x.videoResolution); var qualitySaved = false; foreach (var quality in foundQualities) { if (qualitySaved) { break; } if (quality.Equals(existing.Quality)) { // We got it continue; } // We don't have this quality if (quality.Equals("4k", StringComparison.InvariantCultureIgnoreCase)) { Logger.LogDebug($"We already have movie {movie.title}, But found a 4K version!"); existing.Has4K = true; await Repo.Update(existing); } else { qualitySaved = true; existing.Quality = quality; await Repo.Update(existing); } } Logger.LogDebug($"We already have movie {movie.title}"); continue; } //var hasSameKey = await Repo.GetByKey(movie.ratingKey); //if (hasSameKey != null) //{ // await Repo.Delete(hasSameKey); //} Logger.LogDebug("Adding movie {0}", movie.title); var guids = new List <string>(); if (!movie.Guid.Any()) { var metaData = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri, movie.ratingKey); var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); guids.Add(meta.guid); if (meta.Guid != null) { foreach (var g in meta.Guid) { guids.Add(g.Id); } } } else { // Currently a Plex Pass feature only foreach (var g in movie.Guid) { guids.Add(g.Id); } } if (!guids.Any()) { Logger.LogWarning($"Movie {movie.title} has no relevant metadata. Skipping."); continue; } var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); if (!providerIds.Any()) { Logger.LogWarning($"Movie {movie.title} has no External Ids in Plex (ImdbId, TheMovieDbId). Skipping."); continue; } var qualities = movie?.Media?.Select(x => x?.videoResolution ?? string.Empty) ?? Enumerable.Empty <string>(); var is4k = qualities != null && qualities.Any(x => x.Equals("4k", StringComparison.InvariantCultureIgnoreCase)); var selectedQuality = is4k ? null : qualities?.OrderBy(x => x)?.FirstOrDefault() ?? string.Empty; var item = new PlexServerContent { AddedAt = DateTime.Now, Key = movie.ratingKey, ReleaseYear = movie.year.ToString(), Type = MediaType.Movie, Title = movie.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey, servers.ServerHostname), Seasons = new List <PlexSeasonsContent>(), Quality = selectedQuality, Has4K = is4k, }; if (providerIds.ImdbId.HasValue()) { item.ImdbId = providerIds.ImdbId; } if (providerIds.TheMovieDb.HasValue()) { item.TheMovieDbId = providerIds.TheMovieDb; } if (providerIds.TheTvDb.HasValue()) { item.TvDbId = providerIds.TheTvDb; } contentToAdd.Add(item); } catch (Exception e) { Logger.LogError(LoggingEvents.PlexContentCacher, e, "Exception when adding new Movie {0}", movie.title); } if (contentToAdd.Count > 500) { await Repo.AddRange(contentToAdd); foreach (var c in contentToAdd) { contentProcessed.Add(c.Id, c.Key); } contentToAdd.Clear(); } } }
public async Task <RuleResult> Execute(SearchViewModel obj) { PlexServerContent item = null; var useImdb = false; var useTheMovieDb = false; var useId = false; var useTvDb = false; PlexMediaTypeEntity type = ConvertType(obj.Type); if (obj.ImdbId.HasValue()) { item = await PlexContentRepository.GetByType(obj.ImdbId, ProviderType.ImdbId, type); if (item != null) { useImdb = true; } } if (item == null) { if (obj.Id > 0) { item = await PlexContentRepository.GetByType(obj.Id.ToString(), ProviderType.TheMovieDbId, type); if (item != null) { useId = true; } } if (obj.TheMovieDbId.HasValue()) { item = await PlexContentRepository.GetByType(obj.TheMovieDbId, ProviderType.TheMovieDbId, type); if (item != null) { useTheMovieDb = true; } } if (item == null) { if (obj.TheTvDbId.HasValue()) { item = await PlexContentRepository.GetByType(obj.TheTvDbId, ProviderType.TvDbId, type); if (item != null) { useTvDb = true; } } } } if (item != null) { var settings = await _plexSettings.GetSettingsAsync(); var firstServer = settings.Servers.FirstOrDefault(); var host = string.Empty; if (firstServer != null) { host = firstServer.ServerHostname; } if (useId) { obj.TheMovieDbId = obj.Id.ToString(); useTheMovieDb = true; } obj.Available = true; obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host); obj.Quality = item.Quality; if (obj.Type == RequestType.TvShow) { var search = (SearchTvShowViewModel)obj; // Let's go through the episodes now if (search.SeasonRequests.Any()) { var allEpisodes = PlexContentRepository.GetAllEpisodes(); foreach (var season in search.SeasonRequests.ToList()) { foreach (var episode in season.Episodes.ToList()) { await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log); } } AvailabilityRuleHelper.CheckForUnairedEpisodes(search); } } } return(Success()); }