public Task <RuleResult> Execute(object objec, string requestOnBehalf) { if (objec is SearchAlbumViewModel obj) { // Check if it's in Lidarr var result = _db.GetAll().FirstOrDefault(x => x.ForeignAlbumId == obj.ForeignAlbumId); if (result != null) { obj.PercentOfTracks = result.PercentOfTracks; obj.Monitored = true; // It's in Lidarr so it's monitored } } if (objec is ReleaseGroup release) { // Check if it's in Lidarr var result = _db.GetAll().FirstOrDefault(x => x.ForeignAlbumId == release.Id); if (result != null) { release.PercentOfTracks = result.PercentOfTracks; release.Monitored = true; // It's in Lidarr so it's monitored } } return(Task.FromResult(Success())); }
private async Task Process(RadarrSettings settings) { if (settings.Enabled) { try { var movies = await _api.GetMovies(settings.ApiKey, settings.FullUri); var existingMovies = _radarrRepo.GetAll(); if (movies != null) { var movieIds = new List <RadarrCache>(); foreach (var m in movies) { if (m.monitored || m.hasFile) { if (m.tmdbId > 0) { var is4k = m.movieFile?.quality?.quality?.resolution >= 2160; // Do we have a cached movie for this already? var existing = await existingMovies.FirstOrDefaultAsync(x => x.TheMovieDbId == m.tmdbId); if (existing != null) { existing.Has4K = is4k; existing.HasFile = m.hasFile; } else { movieIds.Add(new RadarrCache { TheMovieDbId = m.tmdbId, HasFile = m.hasFile, Has4K = is4k, HasRegular = !is4k }); } } else { _logger.LogError($"TMDBId is not > 0 for movie {m.title}"); } } } // Save from the updates made to the existing movies (they are in the EF Change Tracker) await _radarrRepo.SaveChangesAsync(); await _radarrRepo.AddRange(movieIds); } await OmbiQuartz.TriggerJob(nameof(IArrAvailabilityChecker), "DVR"); } catch (System.Exception ex) { _logger.LogError(LoggingEvents.Cacher, ex, "Failed caching queued items from Radarr"); } } }
private async Task ProcessMovies() { var availableRadarrMovies = _radarrRepo.GetAll().Where(x => x.HasFile).ToImmutableHashSet(); var unavailableMovieRequests = _movies.GetAll().Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)).ToImmutableHashSet(); var itemsForAvailability = new List <AvailabilityModel>(); foreach (var movieRequest in unavailableMovieRequests) { // Do we have an item in the radarr list var available = availableRadarrMovies.FirstOrDefault(x => x.TheMovieDbId == movieRequest.TheMovieDbId); if (available != null) { _logger.LogInformation($"Found move '{movieRequest.Title}' available in Radarr"); if (available.Has4K && !movieRequest.Available4K) { itemsForAvailability.Add(new AvailabilityModel { Id = movieRequest.Id, RequestedUser = movieRequest.RequestedUser != null ? movieRequest.RequestedUser.Email : string.Empty }); movieRequest.Available4K = true; movieRequest.MarkedAsAvailable4K = DateTime.UtcNow; } if (available.HasRegular) { itemsForAvailability.Add(new AvailabilityModel { Id = movieRequest.Id, RequestedUser = movieRequest.RequestedUser != null ? movieRequest.RequestedUser.Email : string.Empty }); movieRequest.Available = true; movieRequest.MarkedAsAvailable = DateTime.UtcNow; } await _movies.SaveChangesAsync(); } } if (itemsForAvailability.Any()) { await _hub.Clients.Clients(NotificationHub.AdminConnectionIds) .SendAsync(NotificationHub.NotificationEvent, "Radarr Availability Checker found some new available movies!"); } foreach (var item in itemsForAvailability) { await _notification.Notify(new NotificationOptions { DateTime = DateTime.Now, NotificationType = NotificationType.RequestAvailable, RequestId = item.Id, RequestType = RequestType.Movie, Recipient = item.RequestedUser }); } }
public Task <RuleResult> Execute(object objec, string requestOnBehalf) { var obj = (SearchArtistViewModel)objec; // Check if it's in Lidarr var result = _db.GetAll().FirstOrDefault(x => x.ForeignArtistId == obj.ForignArtistId); if (result != null) { obj.Monitored = true; // It's in Lidarr so it's monitored } return(Task.FromResult(Success())); }
public Task <RuleResult> Execute(object objec) { var obj = (SearchArtistViewModel)objec; // Check if it's in Lidarr var result = _db.GetAll().FirstOrDefault(x => x.ForeignArtistId.Equals(obj.ForignArtistId, StringComparison.InvariantCultureIgnoreCase)); if (result != null) { obj.Monitored = true; // It's in Lidarr so it's monitored } return(Task.FromResult(Success())); }
public Task <RuleResult> Execute(SearchViewModel obj) { if (obj.Type == RequestType.Movie) { // Check if it's in Radarr var result = _db.GetAll().FirstOrDefault(x => x.TheMovieDbId == obj.Id); if (result != null) { obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something? if (result.HasFile) { obj.Available = true; } } } return(Task.FromResult(Success())); }
private HashSet <LidarrAlbumCache> GetMusicContent(IExternalRepository <LidarrAlbumCache> repository, bool test) { var lidarrContent = repository.GetAll().AsNoTracking().ToList().Where(x => x.FullyAvailable); HashSet <LidarrAlbumCache> albumsToSend; if (test) { albumsToSend = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); } else { // Filter out the ones that we haven't sent yet var addedLog = _recentlyAddedLog.GetAll().ToList(); HashSet <string> addedAlbumLogIds; GetRecentlyAddedMoviesData(addedLog, out addedAlbumLogIds); albumsToSend = lidarrContent.Where(x => !addedAlbumLogIds.Contains(x.ForeignAlbumId)).ToHashSet(); } _log.LogInformation("Albums to send: {0}", albumsToSend.Count()); return(albumsToSend); }
public async Task ProcessTvShows() { var tv = await _tvRequest.GetChild().Where(x => !x.Available).ToListAsync(); var sonarrEpisodes = _sonarrEpisodeRepo.GetAll().Where(x => x.HasFile); foreach (var child in tv) { var tvDbId = child.ParentRequest.TvDbId; IQueryable <SonarrEpisodeCache> seriesEpisodes = sonarrEpisodes.Where(x => x.TvDbId == tvDbId); if (seriesEpisodes == null || !seriesEpisodes.Any()) { continue; } //if (!seriesEpisodes.Any()) //{ // // Let's try and match the series by name // seriesEpisodes = sonarrEpisodes.Where(x => // x.EpisodeNumber == child.Title && // x.Series.ReleaseYear == child.ParentRequest.ReleaseDate.Year.ToString()); //} var availableEpisode = new List <AvailabilityModel>(); foreach (var season in child.SeasonRequests) { foreach (var episode in season.Episodes) { if (episode.Available) { continue; } var foundEp = await seriesEpisodes.AnyAsync( x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == episode.Season.SeasonNumber); if (foundEp) { availableEpisode.Add(new AvailabilityModel { Id = episode.Id }); episode.Available = true; } } } //TODO Partial avilability notifications here if (availableEpisode.Any()) { //await _hub.Clients.Clients(NotificationHub.AdminConnectionIds) // .SendAsync(NotificationHub.NotificationEvent, "Sonarr Availability Checker found some new available episodes!"); await _tvRequest.Save(); } //foreach(var c in availableEpisode) //{ // await _tvRepo.MarkEpisodeAsAvailable(c.Id); //} // Check to see if all of the episodes in all seasons are available for this request var allAvailable = child.SeasonRequests.All(x => x.Episodes.All(c => c.Available)); if (allAvailable) { await _hub.Clients.Clients(NotificationHub.AdminConnectionIds) .SendAsync(NotificationHub.NotificationEvent, "Sonarr Availability Checker found some new available Shows!"); child.Available = true; child.MarkedAsAvailable = DateTime.UtcNow; _logger.LogInformation("[ARR_AC] - Child request {0} is now available, sending notification", $"{child.Title} - {child.Id}"); // We have ful-fulled this request! await _tvRequest.Save(); await _notification.Notify(new NotificationOptions { DateTime = DateTime.Now, NotificationType = NotificationType.RequestAvailable, RequestId = child.Id, RequestType = RequestType.TvShow, Recipient = child.RequestedUser.Email }); } } await _tvRequest.Save(); }
public async Task Execute(IJobExecutionContext context) { var settings = await _settings.GetSettingsAsync(); if (!settings.Enable || !settings.EnableWatchlistImport) { _logger.LogDebug($"Not enabled. Plex Enabled: {settings.Enable}, Watchlist Enabled: {settings.EnableWatchlistImport}"); return; } var plexUsersWithTokens = _ombiUserManager.Users.Where(x => x.UserType == UserType.PlexUser && x.MediaServerToken != null).ToList(); _logger.LogInformation($"Found {plexUsersWithTokens.Count} users with tokens"); await NotifyClient("Starting Watchlist Import"); foreach (var user in plexUsersWithTokens) { try { _logger.LogDebug($"Starting Watchlist Import for {user.UserName} with token {user.MediaServerToken}"); var watchlist = await _plexApi.GetWatchlist(user.MediaServerToken, context?.CancellationToken ?? CancellationToken.None); if (watchlist == null || !(watchlist.MediaContainer?.Metadata?.Any() ?? false)) { _logger.LogDebug($"No watchlist found for {user.UserName}"); continue; } var items = watchlist.MediaContainer.Metadata; _logger.LogDebug($"Items found in watchlist: {watchlist.MediaContainer.totalSize}"); foreach (var item in items) { _logger.LogDebug($"Processing {item.title} {item.type}"); var providerIds = await GetProviderIds(user.MediaServerToken, item, context?.CancellationToken ?? CancellationToken.None); if (!providerIds.TheMovieDb.HasValue()) { _logger.LogWarning($"No TheMovieDb Id found for {item.title}, could not import via Plex WatchList"); // We need a MovieDbId to support this; continue; } // Check to see if we have already imported this item var alreadyImported = _watchlistRepo.GetAll().Any(x => x.TmdbId == providerIds.TheMovieDb); if (alreadyImported) { _logger.LogDebug($"{item.title} already imported via Plex WatchList, skipping"); continue; } switch (item.type) { case "show": await ProcessShow(int.Parse(providerIds.TheMovieDb), user); break; case "movie": await ProcessMovie(int.Parse(providerIds.TheMovieDb), user); break; } } } catch (Exception ex) { _logger.LogError(ex, $"Exception thrown when importing watchlist for user {user.UserName}"); continue; } } await NotifyClient("Finished Watchlist Import"); }
public async Task Start(NewsletterSettings settings, bool test) { if (!settings.Enabled) { return; } var template = await _templateRepo.GetTemplate(NotificationAgent.Email, NotificationType.Newsletter); if (!template.Enabled) { return; } var emailSettings = await _emailSettings.GetSettingsAsync(); if (!ValidateConfiguration(emailSettings)) { return; } try { var customization = await _customizationSettings.GetSettingsAsync(); // Get the Content var plexContent = _plex.GetAll().Include(x => x.Episodes).AsNoTracking(); var embyContent = _emby.GetAll().Include(x => x.Episodes).AsNoTracking(); var lidarrContent = _lidarrAlbumRepository.GetAll().Where(x => x.FullyAvailable).AsNoTracking(); var addedLog = _recentlyAddedLog.GetAll(); var addedPlexMovieLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Parent).Select(x => x.ContentId).ToHashSet(); var addedEmbyMoviesLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Emby && x.ContentType == ContentType.Parent).Select(x => x.ContentId).ToHashSet(); var addedAlbumLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Lidarr && x.ContentType == ContentType.Album).Select(x => x.AlbumId).ToHashSet(); var addedPlexEpisodesLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Episode); var addedEmbyEpisodesLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Emby && x.ContentType == ContentType.Episode); // Filter out the ones that we haven't sent yet var plexContentMoviesToSend = plexContent.Where(x => x.Type == PlexMediaTypeEntity.Movie && x.HasTheMovieDb && !addedPlexMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))); var embyContentMoviesToSend = embyContent.Where(x => x.Type == EmbyMediaType.Movie && x.HasTheMovieDb && !addedEmbyMoviesLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))); var lidarrContentAlbumsToSend = lidarrContent.Where(x => !addedAlbumLogIds.Contains(x.ForeignAlbumId)).ToHashSet(); _log.LogInformation("Plex Movies to send: {0}", plexContentMoviesToSend.Count()); _log.LogInformation("Emby Movies to send: {0}", embyContentMoviesToSend.Count()); _log.LogInformation("Albums to send: {0}", lidarrContentAlbumsToSend.Count()); var plexEpisodesToSend = FilterPlexEpisodes(_plex.GetAllEpisodes().Include(x => x.Series).Where(x => x.Series.HasTvDb).AsNoTracking(), addedPlexEpisodesLogIds); var embyEpisodesToSend = FilterEmbyEpisodes(_emby.GetAllEpisodes().Include(x => x.Series).Where(x => x.Series.HasTvDb).AsNoTracking(), addedEmbyEpisodesLogIds); _log.LogInformation("Plex Episodes to send: {0}", plexEpisodesToSend.Count()); _log.LogInformation("Emby Episodes to send: {0}", embyEpisodesToSend.Count()); var plexSettings = await _plexSettings.GetSettingsAsync(); var embySettings = await _embySettings.GetSettingsAsync(); var body = string.Empty; if (test) { var plexm = plexContent.Where(x => x.Type == PlexMediaTypeEntity.Movie).OrderByDescending(x => x.AddedAt).Take(10); var embym = embyContent.Where(x => x.Type == EmbyMediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10); var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet(); var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); var lidarr = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); body = await BuildHtml(plexm, embym, plext, embyt, lidarr, settings, embySettings, plexSettings); } else { body = await BuildHtml(plexContentMoviesToSend, embyContentMoviesToSend, plexEpisodesToSend, embyEpisodesToSend, lidarrContentAlbumsToSend, settings, embySettings, plexSettings); if (body.IsNullOrEmpty()) { return; } } if (!test) { // Get the users to send it to var users = await _userManager.GetUsersInRoleAsync(OmbiRoles.ReceivesNewsletter); if (!users.Any()) { return; } foreach (var emails in settings.ExternalEmails) { users.Add(new OmbiUser { UserName = emails, Email = emails }); } var messageContent = ParseTemplate(template, customization); var email = new NewsletterTemplate(); var html = email.LoadTemplate(messageContent.Subject, messageContent.Message, body, customization.Logo); var bodyBuilder = new BodyBuilder { HtmlBody = html, }; var message = new MimeMessage { Body = bodyBuilder.ToMessageBody(), Subject = messageContent.Subject }; foreach (var user in users) { // Get the users to send it to if (user.Email.IsNullOrEmpty()) { continue; } // BCC the messages message.Bcc.Add(new MailboxAddress(user.Email.Trim(), user.Email.Trim())); } // Send the email await _email.Send(message, emailSettings); // Now add all of this to the Recently Added log var recentlyAddedLog = new HashSet <RecentlyAddedLog>(); foreach (var p in plexContentMoviesToSend) { recentlyAddedLog.Add(new RecentlyAddedLog { AddedAt = DateTime.Now, Type = RecentlyAddedType.Plex, ContentType = ContentType.Parent, ContentId = StringHelper.IntParseLinq(p.TheMovieDbId), }); } foreach (var p in plexEpisodesToSend) { recentlyAddedLog.Add(new RecentlyAddedLog { AddedAt = DateTime.Now, Type = RecentlyAddedType.Plex, ContentType = ContentType.Episode, ContentId = StringHelper.IntParseLinq(p.Series.TvDbId), EpisodeNumber = p.EpisodeNumber, SeasonNumber = p.SeasonNumber }); } foreach (var e in embyContentMoviesToSend) { if (e.Type == EmbyMediaType.Movie) { recentlyAddedLog.Add(new RecentlyAddedLog { AddedAt = DateTime.Now, Type = RecentlyAddedType.Emby, ContentType = ContentType.Parent, ContentId = StringHelper.IntParseLinq(e.TheMovieDbId), }); } } foreach (var p in embyEpisodesToSend) { recentlyAddedLog.Add(new RecentlyAddedLog { AddedAt = DateTime.Now, Type = RecentlyAddedType.Emby, ContentType = ContentType.Episode, ContentId = StringHelper.IntParseLinq(p.Series.TvDbId), EpisodeNumber = p.EpisodeNumber, SeasonNumber = p.SeasonNumber }); } await _recentlyAddedLog.AddRange(recentlyAddedLog); } else { var admins = await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin); foreach (var a in admins) { if (a.Email.IsNullOrEmpty()) { continue; } var messageContent = ParseTemplate(template, customization); var email = new NewsletterTemplate(); var html = email.LoadTemplate(messageContent.Subject, messageContent.Message, body, customization.Logo); await _email.Send( new NotificationMessage { Message = html, Subject = messageContent.Subject, To = a.Email }, emailSettings); } } } catch (Exception e) { _log.LogError(e, "Error when attempting to create newsletter"); throw; } }