You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Ombi/src/Ombi.Core/Senders/MovieSender.cs

259 lines
10 KiB

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Api.CouchPotato;
using Ombi.Api.DogNzb.Models;
using Ombi.Api.Radarr;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models.External;
using Ombi.Store.Entities.Requests;
using Ombi.Api.DogNzb;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using System.Collections.Generic;
using Ombi.Api.Radarr.Models;
using Microsoft.Extensions.Options;
using Ombi.Api.Sonarr;
namespace Ombi.Core.Senders
{
public class MovieSender : IMovieSender
{
public MovieSender(ISettingsService<RadarrSettings> radarrSettings, ISettingsService<Radarr4KSettings> radarr4kSettings, ILogger<MovieSender> log,
ISettingsService<DogNzbSettings> dogSettings, IDogNzbApi dogApi, ISettingsService<CouchPotatoSettings> cpSettings,
ICouchPotatoApi cpApi, IRepository<UserQualityProfiles> userProfiles, IRepository<RequestQueue> requestQueue, INotificationHelper notify,
IRadarrV3Api radarrV3Api)
{
_radarrSettings = radarrSettings;
_log = log;
_dogNzbSettings = dogSettings;
_dogNzbApi = dogApi;
_couchPotatoSettings = cpSettings;
_couchPotatoApi = cpApi;
_userProfiles = userProfiles;
_requestQueuRepository = requestQueue;
_notificationHelper = notify;
_radarrV3Api = radarrV3Api;
_radarr4KSettings = radarr4kSettings;
}
private readonly ISettingsService<RadarrSettings> _radarrSettings;
private readonly ISettingsService<Radarr4KSettings> _radarr4KSettings;
private readonly ILogger<MovieSender> _log;
private readonly IDogNzbApi _dogNzbApi;
private readonly ISettingsService<DogNzbSettings> _dogNzbSettings;
private readonly ISettingsService<CouchPotatoSettings> _couchPotatoSettings;
private readonly ICouchPotatoApi _couchPotatoApi;
private readonly IRepository<UserQualityProfiles> _userProfiles;
private readonly IRepository<RequestQueue> _requestQueuRepository;
private readonly INotificationHelper _notificationHelper;
private readonly IRadarrV3Api _radarrV3Api;
public async Task<SenderResult> Send(MovieRequests model, bool is4K)
{
try
{
var cpSettings = await _couchPotatoSettings.GetSettingsAsync();
RadarrSettings radarrSettings;
if (is4K)
{
radarrSettings = await _radarr4KSettings.GetSettingsAsync();
}
else
{
radarrSettings = await _radarrSettings.GetSettingsAsync();
}
if (radarrSettings.Enabled)
{
return await SendToRadarr(model, radarrSettings, is4K);
}
var dogSettings = await _dogNzbSettings.GetSettingsAsync();
if (dogSettings.Enabled)
{
await SendToDogNzb(model, dogSettings);
return new SenderResult
{
Success = true,
Sent = true,
};
}
if (cpSettings.Enabled)
{
return await SendToCp(model, cpSettings, cpSettings.DefaultProfileId);
}
}
catch (Exception e)
{
_log.LogError(e, "Error when sending movie to DVR app, added to the request queue");
// Check if already in request quee
var existingQueue = await _requestQueuRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id);
if (existingQueue != null)
{
existingQueue.RetryCount++;
existingQueue.Error = e.Message;
await _requestQueuRepository.SaveChangesAsync();
}
else
{
await _requestQueuRepository.Add(new RequestQueue
{
Dts = DateTime.UtcNow,
Error = e.Message,
RequestId = model.Id,
Type = RequestType.Movie,
RetryCount = 0
});
await _notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
}
}
return new SenderResult
{
Success = true,
Sent = false,
};
}
private async Task<SenderResult> SendToCp(FullBaseRequest model, CouchPotatoSettings cpSettings, string cpSettingsDefaultProfileId)
{
var result = await _couchPotatoApi.AddMovie(model.ImdbId, cpSettings.ApiKey, model.Title, cpSettings.FullUri, cpSettingsDefaultProfileId);
return new SenderResult { Success = result, Sent = true };
}
private async Task<DogNzbMovieAddResult> SendToDogNzb(FullBaseRequest model, DogNzbSettings settings)
{
var id = model.ImdbId;
return await _dogNzbApi.AddMovie(settings.ApiKey, id);
}
private async Task<SenderResult> SendToRadarr(MovieRequests model, RadarrSettings settings, bool is4k)
{
var qualityToUse = int.Parse(settings.DefaultQualityProfile);
var rootFolderPath = settings.DefaultRootPath;
var profiles = await _userProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId);
if (profiles != null)
{
if (is4k)
{
if (profiles.Radarr4KRootPath > 0)
{
var tempPath = await RadarrRootPath(profiles.Radarr4KRootPath, settings);
if (tempPath.HasValue())
{
rootFolderPath = tempPath;
}
}
if (profiles.Radarr4KQualityProfile > 0)
{
qualityToUse = profiles.Radarr4KQualityProfile;
}
}
else
{
if (profiles.RadarrRootPath > 0)
{
var tempPath = await RadarrRootPath(profiles.RadarrRootPath, settings);
if (tempPath.HasValue())
{
rootFolderPath = tempPath;
}
}
if (profiles.RadarrQualityProfile > 0)
{
qualityToUse = profiles.RadarrQualityProfile;
}
}
}
var tags = new List<int>();
if (settings.Tag.HasValue)
{
tags.Add(settings.Tag.Value);
}
if (settings.SendUserTags)
{
var userTag = await GetOrCreateTag(model, settings);
tags.Add(userTag.id);
}
// Overrides on the request take priority
if (model.QualityOverride > 0)
{
qualityToUse = model.QualityOverride;
}
if (model.RootPathOverride > 0)
{
rootFolderPath = await RadarrRootPath(model.RootPathOverride, settings);
}
List<MovieResponse> movies;
// Check if the movie already exists? Since it could be unmonitored
movies = await _radarrV3Api.GetMovies(settings.ApiKey, settings.FullUri);
var existingMovie = movies.FirstOrDefault(x => x.tmdbId == model.TheMovieDbId);
if (existingMovie == null)
{
var result = await _radarrV3Api.AddMovie(model.TheMovieDbId, model.Title, model.ReleaseDate.Year,
qualityToUse, rootFolderPath, settings.ApiKey, settings.FullUri, !settings.AddOnly,
settings.MinimumAvailability, tags);
if (!string.IsNullOrEmpty(result.Error?.message))
{
_log.LogError(LoggingEvents.RadarrCacher, result.Error.message);
return new SenderResult { Success = false, Message = result.Error.message, Sent = false };
}
if (!string.IsNullOrEmpty(result.title))
{
return new SenderResult { Success = true, Sent = false };
}
return new SenderResult { Success = true, Sent = false };
}
// We have the movie, check if we can request it or change the status
if (!existingMovie.monitored)
{
// let's set it to monitored and search for it
existingMovie.monitored = true;
await _radarrV3Api.UpdateMovie(existingMovie, settings.ApiKey, settings.FullUri);
// Search for it
if (!settings.AddOnly)
{
await _radarrV3Api.MovieSearch(new[] { existingMovie.id }, settings.ApiKey, settings.FullUri);
}
return new SenderResult { Success = true, Sent = true };
}
return new SenderResult { Success = false, Sent = false, Message = "Movie is already monitored" };
}
private async Task<string> RadarrRootPath(int overrideId, RadarrSettings settings)
{
var paths = await _radarrV3Api.GetRootFolders(settings.ApiKey, settings.FullUri);
var selectedPath = paths.FirstOrDefault(x => x.id == overrideId);
return selectedPath?.path ?? string.Empty;
}
private async Task<Tag> GetOrCreateTag(MovieRequests model, RadarrSettings s)
{
var tagName = model.RequestedUser.UserName;
// Does tag exist?
var allTags = await _radarrV3Api.GetTags(s.ApiKey, s.FullUri);
var existingTag = allTags.FirstOrDefault(x => x.label.Equals(tagName, StringComparison.InvariantCultureIgnoreCase));
existingTag ??= await _radarrV3Api.CreateTag(s.ApiKey, s.FullUri, tagName);
return existingTag;
}
}
}