diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs b/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs index 10e34bf20..d1217c8b5 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.Logging; using Ombi.Api.Plex; using Ombi.Api.Plex.Models; using Ombi.Core.Authentication; @@ -8,9 +9,11 @@ using Ombi.Core.Models.Requests; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; +using Ombi.Hubs; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Quartz; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -25,10 +28,11 @@ namespace Ombi.Schedule.Jobs.Plex private readonly OmbiUserManager _ombiUserManager; private readonly IMovieRequestEngine _movieRequestEngine; private readonly ITvRequestEngine _tvRequestEngine; + private readonly IHubContext _hub; private readonly ILogger _logger; public PlexWatchlistImport(IPlexApi plexApi, ISettingsService settings, OmbiUserManager ombiUserManager, - IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine, + IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine, IHubContext hub, ILogger logger) { _plexApi = plexApi; @@ -36,6 +40,7 @@ namespace Ombi.Schedule.Jobs.Plex _ombiUserManager = ombiUserManager; _movieRequestEngine = movieRequestEngine; _tvRequestEngine = tvRequestEngine; + _hub = hub; _logger = logger; } @@ -44,48 +49,69 @@ namespace Ombi.Schedule.Jobs.Plex 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) { - var watchlist = await _plexApi.GetWatchlist(user.MediaServerToken, context?.CancellationToken ?? CancellationToken.None); - if (watchlist == null || !(watchlist.MediaContainer?.Metadata?.Any() ?? false)) + try { - return; - } - var items = watchlist.MediaContainer.Metadata; - foreach (var item in items) - { - var providerIds = await GetProviderIds(user.MediaServerToken, item, context?.CancellationToken ?? CancellationToken.None); - if (!providerIds.TheMovieDb.HasValue()) + _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)) { - // We need a MovieDbId to support this; + _logger.LogDebug($"No watchlist found for {user.UserName}"); return; } - switch (item.type) + + var items = watchlist.MediaContainer.Metadata; + _logger.LogDebug($"Items found in watchlist: {watchlist.MediaContainer.totalSize}"); + foreach (var item in items) { - case "show": - await ProcessShow(int.Parse(providerIds.TheMovieDb), user, context?.CancellationToken ?? CancellationToken.None); - break; - case "movie": - await ProcessMovie(int.Parse(providerIds.TheMovieDb), user, context?.CancellationToken ?? CancellationToken.None); - break; + _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; + return; + } + 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"); } - private async Task ProcessMovie(int theMovieDbId, OmbiUser user, CancellationToken cancellationToken) + private async Task ProcessMovie(int theMovieDbId, OmbiUser user) { _movieRequestEngine.SetUser(user); - var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist}); + var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist }); if (response.IsError) { if (response.ErrorCode == ErrorCode.AlreadyRequested) { + _logger.LogDebug($"Movie already requested for user '{user.UserName}'"); return; } _logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'"); @@ -97,7 +123,7 @@ namespace Ombi.Schedule.Jobs.Plex } - private async Task ProcessShow(int theMovieDbId, OmbiUser user, CancellationToken cancellationToken) + private async Task ProcessShow(int theMovieDbId, OmbiUser user) { _tvRequestEngine.SetUser(user); var response = await _tvRequestEngine.RequestTvShow(new TvRequestViewModelV2 { RequestAll = true, TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist }); @@ -105,6 +131,7 @@ namespace Ombi.Schedule.Jobs.Plex { if (response.ErrorCode == ErrorCode.AlreadyRequested) { + _logger.LogDebug($"Show already requested for user '{user.UserName}'"); return; } _logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'"); @@ -144,6 +171,15 @@ namespace Ombi.Schedule.Jobs.Plex return providerIds; } + private async Task NotifyClient(string message) + { + if (_hub?.Clients == null) + { + return; + } + await _hub?.Clients?.Clients(NotificationHub.AdminConnectionIds)? + .SendAsync(NotificationHub.NotificationEvent, $"Plex Watchlist Import - {message}"); + } public void Dispose() { } } }