mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-11 12:02:35 +02:00
New: Add OnDelete Notification to TraktConnection
to remove movies from Trakt Collection when they are removed from Radarr Add OnDelete Notification to TraktConnection to remove movies from Trakt Collection when they are removed from Radarr skip the deleteHandler if the delete Event was triggered for reason: Upgrade change migration from 180 to 182 since 180 and 181 are already in plan to be used address comments regarding helpText for OnDelete and move check for OnUpgrade deletion reason into trakt connection OnDelete handler reuse TraktCollectMoviesResource for OnDelete trakt api should just ignore the other properties anyway add WithDefaultValue to migration add unit test case for onDelete to fix unit testcase for onDelete
This commit is contained in:
parent
261e598c99
commit
e033ce1eff
@ -59,11 +59,13 @@ class Notification extends Component {
|
||||
onDownload,
|
||||
onUpgrade,
|
||||
onRename,
|
||||
onDelete,
|
||||
onHealthIssue,
|
||||
supportsOnGrab,
|
||||
supportsOnDownload,
|
||||
supportsOnUpgrade,
|
||||
supportsOnRename,
|
||||
supportsOnDelete,
|
||||
supportsOnHealthIssue
|
||||
} = this.props;
|
||||
|
||||
@ -84,6 +86,13 @@ class Notification extends Component {
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnDelete && onDelete &&
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
On Delete
|
||||
</Label>
|
||||
}
|
||||
|
||||
{
|
||||
supportsOnDownload && onDownload &&
|
||||
<Label kind={kinds.SUCCESS}>
|
||||
@ -113,7 +122,7 @@ class Notification extends Component {
|
||||
}
|
||||
|
||||
{
|
||||
!onGrab && !onDownload && !onRename && !onHealthIssue &&
|
||||
!onGrab && !onDownload && !onRename && !onHealthIssue && !onDelete &&
|
||||
<Label
|
||||
kind={kinds.DISABLED}
|
||||
outline={true}
|
||||
@ -150,9 +159,11 @@ Notification.propTypes = {
|
||||
onDownload: PropTypes.bool.isRequired,
|
||||
onUpgrade: PropTypes.bool.isRequired,
|
||||
onRename: PropTypes.bool.isRequired,
|
||||
onDelete: PropTypes.bool.isRequired,
|
||||
onHealthIssue: PropTypes.bool.isRequired,
|
||||
supportsOnGrab: PropTypes.bool.isRequired,
|
||||
supportsOnDownload: PropTypes.bool.isRequired,
|
||||
supportsOnDelete: PropTypes.bool.isRequired,
|
||||
supportsOnUpgrade: PropTypes.bool.isRequired,
|
||||
supportsOnRename: PropTypes.bool.isRequired,
|
||||
supportsOnHealthIssue: PropTypes.bool.isRequired,
|
||||
|
@ -19,11 +19,13 @@ function NotificationEventItems(props) {
|
||||
onDownload,
|
||||
onUpgrade,
|
||||
onRename,
|
||||
onDelete,
|
||||
onHealthIssue,
|
||||
supportsOnGrab,
|
||||
supportsOnDownload,
|
||||
supportsOnUpgrade,
|
||||
supportsOnRename,
|
||||
supportsOnDelete,
|
||||
supportsOnHealthIssue,
|
||||
includeHealthWarnings
|
||||
} = item;
|
||||
@ -84,6 +86,17 @@ function NotificationEventItems(props) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="onDelete"
|
||||
helpText="On Delete"
|
||||
isDisabled={!supportsOnDelete.value}
|
||||
{...onDelete}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
|
@ -17,10 +17,12 @@ protected override void MapToResource(NotificationResource resource, Notificatio
|
||||
resource.OnDownload = definition.OnDownload;
|
||||
resource.OnUpgrade = definition.OnUpgrade;
|
||||
resource.OnRename = definition.OnRename;
|
||||
resource.OnDelete = definition.OnDelete;
|
||||
resource.SupportsOnGrab = definition.SupportsOnGrab;
|
||||
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
||||
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
||||
resource.SupportsOnRename = definition.SupportsOnRename;
|
||||
resource.SupportsOnDelete = definition.SupportsOnDelete;
|
||||
resource.Tags = definition.Tags;
|
||||
}
|
||||
|
||||
@ -32,10 +34,12 @@ protected override void MapToModel(NotificationDefinition definition, Notificati
|
||||
definition.OnDownload = resource.OnDownload;
|
||||
definition.OnUpgrade = resource.OnUpgrade;
|
||||
definition.OnRename = resource.OnRename;
|
||||
definition.OnDelete = resource.OnDelete;
|
||||
definition.SupportsOnGrab = resource.SupportsOnGrab;
|
||||
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
||||
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
||||
definition.SupportsOnRename = resource.SupportsOnRename;
|
||||
definition.SupportsOnDelete = resource.SupportsOnDelete;
|
||||
definition.Tags = resource.Tags;
|
||||
}
|
||||
|
||||
|
@ -8,10 +8,12 @@ public class NotificationResource : ProviderResource
|
||||
public bool OnDownload { get; set; }
|
||||
public bool OnUpgrade { get; set; }
|
||||
public bool OnRename { get; set; }
|
||||
public bool OnDelete { get; set; }
|
||||
public bool SupportsOnGrab { get; set; }
|
||||
public bool SupportsOnDownload { get; set; }
|
||||
public bool SupportsOnUpgrade { get; set; }
|
||||
public bool SupportsOnRename { get; set; }
|
||||
public bool SupportsOnDelete { get; set; }
|
||||
public HashSet<int> Tags { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,11 @@ public override void OnMovieRename(Movie movie)
|
||||
TestLogger.Info("OnRename was called");
|
||||
}
|
||||
|
||||
public override void OnDelete(DeleteMessage message)
|
||||
{
|
||||
TestLogger.Info("OnDelete was called");
|
||||
}
|
||||
|
||||
public override void OnHealthIssue(NzbDrone.Core.HealthCheck.HealthCheck artist)
|
||||
{
|
||||
TestLogger.Info("OnHealthIssue was called");
|
||||
@ -100,6 +105,7 @@ public void should_support_all_if_implemented()
|
||||
notification.SupportsOnDownload.Should().BeTrue();
|
||||
notification.SupportsOnUpgrade.Should().BeTrue();
|
||||
notification.SupportsOnRename.Should().BeTrue();
|
||||
notification.SupportsOnDelete.Should().BeTrue();
|
||||
notification.SupportsOnHealthIssue.Should().BeTrue();
|
||||
}
|
||||
|
||||
@ -112,6 +118,7 @@ public void should_support_none_if_none_are_implemented()
|
||||
notification.SupportsOnDownload.Should().BeFalse();
|
||||
notification.SupportsOnUpgrade.Should().BeFalse();
|
||||
notification.SupportsOnRename.Should().BeFalse();
|
||||
notification.SupportsOnDelete.Should().BeFalse();
|
||||
notification.SupportsOnHealthIssue.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(182)]
|
||||
public class on_delete_notification : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Notifications").AddColumn("OnDelete").AsBoolean().WithDefaultValue(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -86,6 +86,7 @@ public static void Map()
|
||||
.Ignore(i => i.SupportsOnDownload)
|
||||
.Ignore(i => i.SupportsOnUpgrade)
|
||||
.Ignore(i => i.SupportsOnRename)
|
||||
.Ignore(i => i.SupportsOnDelete)
|
||||
.Ignore(i => i.SupportsOnHealthIssue);
|
||||
|
||||
Mapper.Entity<MetadataDefinition>("Metadata").RegisterModel()
|
||||
|
20
src/NzbDrone.Core/Notifications/DeleteMessage.cs
Normal file
20
src/NzbDrone.Core/Notifications/DeleteMessage.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Movies;
|
||||
|
||||
namespace NzbDrone.Core.Notifications
|
||||
{
|
||||
public class DeleteMessage
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public Movie Movie { get; set; }
|
||||
public MovieFile MovieFile { get; set; }
|
||||
|
||||
public DeleteMediaFileReason Reason { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Message;
|
||||
}
|
||||
}
|
||||
}
|
@ -11,10 +11,12 @@ public interface INotification : IProvider
|
||||
void OnDownload(DownloadMessage message);
|
||||
void OnMovieRename(Movie movie);
|
||||
void OnHealthIssue(HealthCheck.HealthCheck healthCheck);
|
||||
void OnDelete(DeleteMessage deleteMessage);
|
||||
bool SupportsOnGrab { get; }
|
||||
bool SupportsOnDownload { get; }
|
||||
bool SupportsOnUpgrade { get; }
|
||||
bool SupportsOnRename { get; }
|
||||
bool SupportsOnHealthIssue { get; }
|
||||
bool SupportsOnDelete { get; }
|
||||
}
|
||||
}
|
||||
|
@ -46,11 +46,16 @@ public virtual void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void OnDelete(DeleteMessage deleteMessage)
|
||||
{
|
||||
}
|
||||
|
||||
public bool SupportsOnGrab => HasConcreteImplementation("OnGrab");
|
||||
public bool SupportsOnRename => HasConcreteImplementation("OnMovieRename");
|
||||
public bool SupportsOnDownload => HasConcreteImplementation("OnDownload");
|
||||
public bool SupportsOnUpgrade => SupportsOnDownload;
|
||||
public bool SupportsOnHealthIssue => HasConcreteImplementation("OnHealthIssue");
|
||||
public bool SupportsOnDelete => HasConcreteImplementation("OnDelete");
|
||||
|
||||
protected TSettings Settings => (TSettings)Definition.Settings;
|
||||
|
||||
|
@ -9,13 +9,15 @@ public class NotificationDefinition : ProviderDefinition
|
||||
public bool OnUpgrade { get; set; }
|
||||
public bool OnRename { get; set; }
|
||||
public bool OnHealthIssue { get; set; }
|
||||
public bool OnDelete { get; set; }
|
||||
public bool SupportsOnGrab { get; set; }
|
||||
public bool SupportsOnDownload { get; set; }
|
||||
public bool SupportsOnUpgrade { get; set; }
|
||||
public bool SupportsOnRename { get; set; }
|
||||
public bool SupportsOnHealthIssue { get; set; }
|
||||
public bool SupportsOnDelete { get; set; }
|
||||
public bool IncludeHealthWarnings { get; set; }
|
||||
|
||||
public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnHealthIssue;
|
||||
public override bool Enable => OnGrab || OnDownload || (OnDownload && OnUpgrade) || OnHealthIssue || OnDelete;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ public interface INotificationFactory : IProviderFactory<INotification, Notifica
|
||||
List<INotification> OnUpgradeEnabled();
|
||||
List<INotification> OnRenameEnabled();
|
||||
List<INotification> OnHealthIssueEnabled();
|
||||
List<INotification> OnDeleteEnabled();
|
||||
}
|
||||
|
||||
public class NotificationFactory : ProviderFactory<INotification, NotificationDefinition>, INotificationFactory
|
||||
@ -48,6 +49,11 @@ public List<INotification> OnHealthIssueEnabled()
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnHealthIssue).ToList();
|
||||
}
|
||||
|
||||
public List<INotification> OnDeleteEnabled()
|
||||
{
|
||||
return GetAvailableProviders().Where(n => ((NotificationDefinition)n.Definition).OnDelete).ToList();
|
||||
}
|
||||
|
||||
public override void SetProviderCharacteristics(INotification provider, NotificationDefinition definition)
|
||||
{
|
||||
base.SetProviderCharacteristics(provider, definition);
|
||||
@ -57,6 +63,7 @@ public override void SetProviderCharacteristics(INotification provider, Notifica
|
||||
definition.SupportsOnUpgrade = provider.SupportsOnUpgrade;
|
||||
definition.SupportsOnRename = provider.SupportsOnRename;
|
||||
definition.SupportsOnHealthIssue = provider.SupportsOnHealthIssue;
|
||||
definition.SupportsOnDelete = provider.SupportsOnDelete;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ public class NotificationService
|
||||
: IHandle<MovieRenamedEvent>,
|
||||
IHandle<MovieGrabbedEvent>,
|
||||
IHandle<MovieDownloadedEvent>,
|
||||
IHandle<HealthCheckFailedEvent>
|
||||
IHandle<HealthCheckFailedEvent>,
|
||||
IHandle<MovieFileDeletedEvent>
|
||||
{
|
||||
private readonly INotificationFactory _notificationFactory;
|
||||
private readonly Logger _logger;
|
||||
@ -172,5 +173,29 @@ public void Handle(HealthCheckFailedEvent message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(MovieFileDeletedEvent message)
|
||||
{
|
||||
var deleteMessage = new DeleteMessage();
|
||||
deleteMessage.Message = GetMessage(message.MovieFile.Movie, message.MovieFile.Quality);
|
||||
deleteMessage.MovieFile = message.MovieFile;
|
||||
deleteMessage.Movie = message.MovieFile.Movie;
|
||||
deleteMessage.Reason = message.Reason;
|
||||
|
||||
foreach (var notification in _notificationFactory.OnDeleteEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ShouldHandleMovie(notification.Definition, message.MovieFile.Movie))
|
||||
{
|
||||
notification.OnDelete(deleteMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnDelete notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,14 @@ public override void OnDownload(DownloadMessage message)
|
||||
_traktService.AddMovieToCollection(Settings, message.Movie, message.MovieFile);
|
||||
}
|
||||
|
||||
public override void OnDelete(DeleteMessage message)
|
||||
{
|
||||
if (message.Reason != MediaFiles.DeleteMediaFileReason.Upgrade)
|
||||
{
|
||||
_traktService.RemoveMovieFromCollection(Settings, message.Movie, message.MovieFile);
|
||||
}
|
||||
}
|
||||
|
||||
public override ValidationResult Test()
|
||||
{
|
||||
var failures = new List<ValidationFailure>();
|
||||
|
@ -12,6 +12,7 @@ public interface ITraktProxy
|
||||
HttpRequest GetOAuthRequest(string callbackUrl);
|
||||
TraktAuthRefreshResource RefreshAuthToken(string refreshToken);
|
||||
void AddToCollection(TraktCollectMoviesResource payload, string accessToken);
|
||||
void RemoveFromCollection(TraktCollectMoviesResource payload, string accessToken);
|
||||
HttpRequest BuildTraktRequest(string resource, HttpMethod method, string accessToken);
|
||||
}
|
||||
|
||||
@ -50,6 +51,24 @@ public void AddToCollection(TraktCollectMoviesResource payload, string accessTok
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveFromCollection(TraktCollectMoviesResource payload, string accessToken)
|
||||
{
|
||||
var request = BuildTraktRequest("sync/collection/remove", HttpMethod.POST, accessToken);
|
||||
|
||||
request.Headers.ContentType = "application/json";
|
||||
request.SetContent(payload.ToJson());
|
||||
|
||||
try
|
||||
{
|
||||
_httpClient.Execute(request);
|
||||
}
|
||||
catch (HttpException ex)
|
||||
{
|
||||
_logger.Error(ex, "Unable to post payload {0}", payload);
|
||||
throw new TraktException("Unable to post payload", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetUserName(string accessToken)
|
||||
{
|
||||
var request = BuildTraktRequest("users/settings", HttpMethod.GET, accessToken);
|
||||
|
@ -19,6 +19,7 @@ public interface ITraktService
|
||||
HttpRequest GetOAuthRequest(string callbackUrl);
|
||||
TraktAuthRefreshResource RefreshAuthToken(string refreshToken);
|
||||
void AddMovieToCollection(TraktSettings settings, Movie movie, MovieFile movieFile);
|
||||
void RemoveMovieFromCollection(TraktSettings settings, Movie movie, MovieFile movieFile);
|
||||
string GetUserName(string accessToken);
|
||||
ValidationFailure Test(TraktSettings settings);
|
||||
}
|
||||
@ -75,6 +76,27 @@ public ValidationFailure Test(TraktSettings settings)
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveMovieFromCollection(TraktSettings settings, Movie movie, MovieFile movieFile)
|
||||
{
|
||||
var payload = new TraktCollectMoviesResource
|
||||
{
|
||||
Movies = new List<TraktCollectMovie>()
|
||||
};
|
||||
|
||||
payload.Movies.Add(new TraktCollectMovie
|
||||
{
|
||||
Title = movie.Title,
|
||||
Year = movie.Year,
|
||||
Ids = new TraktMovieIdsResource
|
||||
{
|
||||
Tmdb = movie.TmdbId,
|
||||
Imdb = movie.ImdbId ?? "",
|
||||
}
|
||||
});
|
||||
|
||||
_proxy.RemoveFromCollection(payload, settings.AccessToken);
|
||||
}
|
||||
|
||||
public void AddMovieToCollection(TraktSettings settings, Movie movie, MovieFile movieFile)
|
||||
{
|
||||
var payload = new TraktCollectMoviesResource
|
||||
|
@ -9,11 +9,13 @@ public class NotificationResource : ProviderResource
|
||||
public bool OnDownload { get; set; }
|
||||
public bool OnUpgrade { get; set; }
|
||||
public bool OnRename { get; set; }
|
||||
public bool OnDelete { get; set; }
|
||||
public bool OnHealthIssue { get; set; }
|
||||
public bool SupportsOnGrab { get; set; }
|
||||
public bool SupportsOnDownload { get; set; }
|
||||
public bool SupportsOnUpgrade { get; set; }
|
||||
public bool SupportsOnRename { get; set; }
|
||||
public bool SupportsOnDelete { get; set; }
|
||||
public bool SupportsOnHealthIssue { get; set; }
|
||||
public bool IncludeHealthWarnings { get; set; }
|
||||
public string TestCommand { get; set; }
|
||||
@ -34,11 +36,13 @@ public override NotificationResource ToResource(NotificationDefinition definitio
|
||||
resource.OnDownload = definition.OnDownload;
|
||||
resource.OnUpgrade = definition.OnUpgrade;
|
||||
resource.OnRename = definition.OnRename;
|
||||
resource.OnDelete = definition.OnDelete;
|
||||
resource.OnHealthIssue = definition.OnHealthIssue;
|
||||
resource.SupportsOnGrab = definition.SupportsOnGrab;
|
||||
resource.SupportsOnDownload = definition.SupportsOnDownload;
|
||||
resource.SupportsOnUpgrade = definition.SupportsOnUpgrade;
|
||||
resource.SupportsOnRename = definition.SupportsOnRename;
|
||||
resource.SupportsOnDelete = definition.SupportsOnDelete;
|
||||
resource.SupportsOnHealthIssue = definition.SupportsOnHealthIssue;
|
||||
resource.IncludeHealthWarnings = definition.IncludeHealthWarnings;
|
||||
|
||||
@ -58,11 +62,13 @@ public override NotificationDefinition ToModel(NotificationResource resource)
|
||||
definition.OnDownload = resource.OnDownload;
|
||||
definition.OnUpgrade = resource.OnUpgrade;
|
||||
definition.OnRename = resource.OnRename;
|
||||
definition.OnDelete = resource.OnDelete;
|
||||
definition.OnHealthIssue = resource.OnHealthIssue;
|
||||
definition.SupportsOnGrab = resource.SupportsOnGrab;
|
||||
definition.SupportsOnDownload = resource.SupportsOnDownload;
|
||||
definition.SupportsOnUpgrade = resource.SupportsOnUpgrade;
|
||||
definition.SupportsOnRename = resource.SupportsOnRename;
|
||||
definition.SupportsOnDelete = resource.SupportsOnDelete;
|
||||
definition.SupportsOnHealthIssue = resource.SupportsOnHealthIssue;
|
||||
definition.IncludeHealthWarnings = resource.IncludeHealthWarnings;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user