示例#1
0
        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()));
        }
示例#2
0
        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");
                }
            }
        }
示例#3
0
        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
                });
            }
        }
示例#4
0
        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()));
        }
示例#5
0
        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()));
        }
示例#6
0
 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()));
 }
示例#7
0
        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);
        }
示例#8
0
        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();
        }
示例#9
0
        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");
        }
示例#10
0
        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;
            }
        }