mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
Merge pull request #238 from Sonarr/blacklisting-v2
Improved Blacklisting
This commit is contained in:
commit
29ca1bc9da
@ -3,6 +3,7 @@
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Api.Series;
|
||||
using NzbDrone.Core.Indexers;
|
||||
|
||||
namespace NzbDrone.Api.Blacklist
|
||||
{
|
||||
@ -13,6 +14,9 @@ public class BlacklistResource : RestResource
|
||||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public DownloadProtocol Protocol { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public SeriesResource Series { get; set; }
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ public class HistoryResource : RestResource
|
||||
public Boolean QualityCutoffNotMet { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public string NzbInfoUrl { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
public string DownloadId { get; set; }
|
||||
|
||||
|
@ -47,7 +47,7 @@ public void should_check_for_blacklisted_title_case_insensative()
|
||||
{
|
||||
Subject.Insert(_blacklist);
|
||||
|
||||
Subject.Blacklisted(_blacklist.SeriesId, _blacklist.SourceTitle.ToUpperInvariant()).Should().HaveCount(1);
|
||||
Subject.BlacklistedByTitle(_blacklist.SeriesId, _blacklist.SourceTitle.ToUpperInvariant()).Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,9 +28,12 @@ public void Setup()
|
||||
};
|
||||
|
||||
_event.Data.Add("publishedDate", DateTime.UtcNow.ToString("s") + "Z");
|
||||
_event.Data.Add("size", "1000");
|
||||
_event.Data.Add("indexer", "nzbs.org");
|
||||
_event.Data.Add("protocol", "1");
|
||||
_event.Data.Add("message", "Marked as failed");
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void should_add_to_repository()
|
||||
{
|
||||
@ -39,5 +42,17 @@ public void should_add_to_repository()
|
||||
Mocker.GetMock<IBlacklistRepository>()
|
||||
.Verify(v => v.Insert(It.Is<Blacklist>(b => b.EpisodeIds == _event.EpisodeIds)), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_to_repository_missing_size_and_protocol()
|
||||
{
|
||||
Subject.Handle(_event);
|
||||
|
||||
_event.Data.Remove("size");
|
||||
_event.Data.Remove("protocol");
|
||||
|
||||
Mocker.GetMock<IBlacklistRepository>()
|
||||
.Verify(v => v.Insert(It.Is<Blacklist>(b => b.EpisodeIds == _event.EpisodeIds)), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
@ -8,12 +9,17 @@ namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
public class Blacklist : ModelBase
|
||||
{
|
||||
public Int32 SeriesId { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public Series Series { get; set; }
|
||||
public List<Int32> EpisodeIds { get; set; }
|
||||
public String SourceTitle { get; set; }
|
||||
public List<int> EpisodeIds { get; set; }
|
||||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public DateTime? PublishedDate { get; set; }
|
||||
public long? Size { get; set; }
|
||||
public DownloadProtocol Protocol { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public string Message { get; set; }
|
||||
public string TorrentInfoHash { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
public interface IBlacklistRepository : IBasicRepository<Blacklist>
|
||||
{
|
||||
List<Blacklist> Blacklisted(int seriesId, string sourceTitle);
|
||||
List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle);
|
||||
List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash);
|
||||
List<Blacklist> BlacklistedBySeries(int seriesId);
|
||||
}
|
||||
|
||||
@ -19,12 +20,18 @@ public BlacklistRepository(IMainDatabase database, IEventAggregator eventAggrega
|
||||
{
|
||||
}
|
||||
|
||||
public List<Blacklist> Blacklisted(int seriesId, string sourceTitle)
|
||||
public List<Blacklist> BlacklistedByTitle(int seriesId, string sourceTitle)
|
||||
{
|
||||
return Query.Where(e => e.SeriesId == seriesId)
|
||||
.AndWhere(e => e.SourceTitle.Contains(sourceTitle));
|
||||
}
|
||||
|
||||
public List<Blacklist> BlacklistedByTorrentInfoHash(int seriesId, string torrentInfoHash)
|
||||
{
|
||||
return Query.Where(e => e.SeriesId == seriesId)
|
||||
.AndWhere(e => e.TorrentInfoHash.Contains(torrentInfoHash));
|
||||
}
|
||||
|
||||
public List<Blacklist> BlacklistedBySeries(int seriesId)
|
||||
{
|
||||
return Query.Where(b => b.SeriesId == seriesId);
|
||||
|
@ -3,20 +3,22 @@
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
|
||||
namespace NzbDrone.Core.Blacklisting
|
||||
{
|
||||
public interface IBlacklistService
|
||||
{
|
||||
bool Blacklisted(int seriesId, string sourceTitle, DateTime publishedDate);
|
||||
bool Blacklisted(int seriesId, ReleaseInfo release);
|
||||
PagingSpec<Blacklist> Paged(PagingSpec<Blacklist> pagingSpec);
|
||||
void Delete(int id);
|
||||
}
|
||||
|
||||
public class BlacklistService : IBlacklistService,
|
||||
|
||||
IExecute<ClearBlacklistCommand>,
|
||||
IHandle<DownloadFailedEvent>,
|
||||
IHandleAsync<SeriesDeletedEvent>
|
||||
@ -28,11 +30,29 @@ public BlacklistService(IBlacklistRepository blacklistRepository)
|
||||
_blacklistRepository = blacklistRepository;
|
||||
}
|
||||
|
||||
public bool Blacklisted(int seriesId, string sourceTitle, DateTime publishedDate)
|
||||
public bool Blacklisted(int seriesId, ReleaseInfo release)
|
||||
{
|
||||
var blacklisted = _blacklistRepository.Blacklisted(seriesId, sourceTitle);
|
||||
var blacklistedByTitle = _blacklistRepository.BlacklistedByTitle(seriesId, release.Title);
|
||||
|
||||
if (release.DownloadProtocol == DownloadProtocol.Torrent)
|
||||
{
|
||||
var torrentInfo = release as TorrentInfo;
|
||||
|
||||
return blacklisted.Any(item => HasSamePublishedDate(item, publishedDate));
|
||||
if (torrentInfo == null) return false;
|
||||
|
||||
if (torrentInfo.InfoHash.IsNullOrWhiteSpace())
|
||||
{
|
||||
return blacklistedByTitle.Where(b => b.Protocol == DownloadProtocol.Torrent)
|
||||
.Any(b => SameTorrent(b, torrentInfo));
|
||||
}
|
||||
|
||||
var blacklistedByTorrentInfohash = _blacklistRepository.BlacklistedByTitle(seriesId, torrentInfo.InfoHash);
|
||||
|
||||
return blacklistedByTorrentInfohash.Any(b => SameTorrent(b, torrentInfo));
|
||||
}
|
||||
|
||||
return blacklistedByTitle.Where(b => b.Protocol == DownloadProtocol.Usenet)
|
||||
.Any(b => SameNzb(b, release));
|
||||
}
|
||||
|
||||
public PagingSpec<Blacklist> Paged(PagingSpec<Blacklist> pagingSpec)
|
||||
@ -45,12 +65,58 @@ public void Delete(int id)
|
||||
_blacklistRepository.Delete(id);
|
||||
}
|
||||
|
||||
private static bool HasSamePublishedDate(Blacklist item, DateTime publishedDate)
|
||||
private bool SameNzb(Blacklist item, ReleaseInfo release)
|
||||
{
|
||||
if (item.PublishedDate == release.PublishDate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!HasSameIndexer(item, release.Indexer) &&
|
||||
HasSamePublishedDate(item, release.PublishDate) &&
|
||||
HasSameSize(item, release.Size))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool SameTorrent(Blacklist item, TorrentInfo release)
|
||||
{
|
||||
if (release.InfoHash.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
return release.InfoHash.Equals(item.TorrentInfoHash);
|
||||
}
|
||||
|
||||
return item.Indexer.Equals(release.Indexer, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
private bool HasSameIndexer(Blacklist item, string indexer)
|
||||
{
|
||||
if (item.Indexer.IsNullOrWhiteSpace())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return item.Indexer.Equals(indexer, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
private bool HasSamePublishedDate(Blacklist item, DateTime publishedDate)
|
||||
{
|
||||
if (!item.PublishedDate.HasValue) return true;
|
||||
|
||||
return item.PublishedDate.Value.AddDays(-2) <= publishedDate &&
|
||||
item.PublishedDate.Value.AddDays(2) >= publishedDate;
|
||||
return item.PublishedDate.Value.AddMinutes(-2) <= publishedDate &&
|
||||
item.PublishedDate.Value.AddMinutes(2) >= publishedDate;
|
||||
}
|
||||
|
||||
private bool HasSameSize(Blacklist item, long size)
|
||||
{
|
||||
if (!item.Size.HasValue) return true;
|
||||
|
||||
var difference = Math.Abs(item.Size.Value - size);
|
||||
|
||||
return difference <= 2.Megabytes();
|
||||
}
|
||||
|
||||
public void Execute(ClearBlacklistCommand message)
|
||||
@ -67,7 +133,12 @@ public void Handle(DownloadFailedEvent message)
|
||||
SourceTitle = message.SourceTitle,
|
||||
Quality = message.Quality,
|
||||
Date = DateTime.UtcNow,
|
||||
PublishedDate = DateTime.Parse(message.Data.GetValueOrDefault("publishedDate"))
|
||||
PublishedDate = DateTime.Parse(message.Data.GetValueOrDefault("publishedDate")),
|
||||
Size = Int64.Parse(message.Data.GetValueOrDefault("size", "0")),
|
||||
Indexer = message.Data.GetValueOrDefault("indexer"),
|
||||
Protocol = (DownloadProtocol)Convert.ToInt32(message.Data.GetValueOrDefault("protocol")),
|
||||
Message = message.Message,
|
||||
TorrentInfoHash = message.Data.GetValueOrDefault("torrentInfoHash")
|
||||
};
|
||||
|
||||
_blacklistRepository.Insert(blacklist);
|
||||
|
@ -0,0 +1,22 @@
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(83)]
|
||||
public class additonal_blacklist_columns : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Blacklist").AddColumn("Size").AsInt64().Nullable();
|
||||
Alter.Table("Blacklist").AddColumn("Protocol").AsInt32().Nullable();
|
||||
Alter.Table("Blacklist").AddColumn("Indexer").AsString().Nullable();
|
||||
Alter.Table("Blacklist").AddColumn("Message").AsString().Nullable();
|
||||
Alter.Table("Blacklist").AddColumn("TorrentInfoHash").AsString().Nullable();
|
||||
|
||||
Update.Table("Blacklist")
|
||||
.Set(new { Protocol = 1 })
|
||||
.AllRows();
|
||||
}
|
||||
}
|
||||
}
|
@ -20,14 +20,8 @@ public BlacklistSpecification(IBlacklistService blacklistService, Logger logger)
|
||||
public RejectionType Type { get { return RejectionType.Permanent; } }
|
||||
|
||||
public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||
{
|
||||
if (subject.Release.DownloadProtocol == DownloadProtocol.Torrent)
|
||||
{
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
|
||||
if (_blacklistService.Blacklisted(subject.Series.Id, subject.Release.Title, subject.Release.PublishDate))
|
||||
{
|
||||
if (_blacklistService.Blacklisted(subject.Series.Id, subject.Release))
|
||||
{
|
||||
_logger.Debug("{0} is blacklisted, rejecting.", subject.Release.Title);
|
||||
return Decision.Reject("Release is blacklisted");
|
||||
|
@ -6,9 +6,11 @@
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.Events;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Profiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
@ -78,77 +80,6 @@ public QualityModel GetBestQualityInHistory(Profile profile, int episodeId)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public void Handle(EpisodeGrabbedEvent message)
|
||||
{
|
||||
foreach (var episode in message.Episode.Episodes)
|
||||
{
|
||||
var history = new History
|
||||
{
|
||||
EventType = HistoryEventType.Grabbed,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.Episode.ParsedEpisodeInfo.Quality,
|
||||
SourceTitle = message.Episode.Release.Title,
|
||||
SeriesId = episode.SeriesId,
|
||||
EpisodeId = episode.Id,
|
||||
DownloadId = message.DownloadId
|
||||
};
|
||||
|
||||
history.Data.Add("Indexer", message.Episode.Release.Indexer);
|
||||
history.Data.Add("NzbInfoUrl", message.Episode.Release.InfoUrl);
|
||||
history.Data.Add("ReleaseGroup", message.Episode.ParsedEpisodeInfo.ReleaseGroup);
|
||||
history.Data.Add("Age", message.Episode.Release.Age.ToString());
|
||||
history.Data.Add("AgeHours", message.Episode.Release.AgeHours.ToString());
|
||||
history.Data.Add("AgeMinutes", message.Episode.Release.AgeMinutes.ToString());
|
||||
history.Data.Add("PublishedDate", message.Episode.Release.PublishDate.ToString("s") + "Z");
|
||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||
|
||||
if (!message.Episode.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace())
|
||||
{
|
||||
history.Data.Add("ReleaseHash", message.Episode.ParsedEpisodeInfo.ReleaseHash);
|
||||
}
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(EpisodeImportedEvent message)
|
||||
{
|
||||
if (!message.NewDownload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var downloadId = message.DownloadId;
|
||||
|
||||
if (downloadId.IsNullOrWhiteSpace())
|
||||
{
|
||||
downloadId = FindDownloadId(message);
|
||||
}
|
||||
|
||||
foreach (var episode in message.EpisodeInfo.Episodes)
|
||||
{
|
||||
var history = new History
|
||||
{
|
||||
EventType = HistoryEventType.DownloadFolderImported,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.EpisodeInfo.Quality,
|
||||
SourceTitle = message.ImportedEpisode.SceneName ?? Path.GetFileNameWithoutExtension(message.EpisodeInfo.Path),
|
||||
SeriesId = message.ImportedEpisode.SeriesId,
|
||||
EpisodeId = episode.Id,
|
||||
DownloadId = downloadId
|
||||
};
|
||||
|
||||
//Won't have a value since we publish this event before saving to DB.
|
||||
//history.Data.Add("FileId", message.ImportedEpisode.Id.ToString());
|
||||
history.Data.Add("DroppedPath", message.EpisodeInfo.Path);
|
||||
history.Data.Add("ImportedPath", Path.Combine(message.EpisodeInfo.Series.Path, message.ImportedEpisode.RelativePath));
|
||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string FindDownloadId(EpisodeImportedEvent trackedDownload)
|
||||
{
|
||||
_logger.Debug("Trying to find downloadId for {0} from history", trackedDownload.ImportedEpisode.Path);
|
||||
@ -194,6 +125,88 @@ private string FindDownloadId(EpisodeImportedEvent trackedDownload)
|
||||
return downloadId;
|
||||
}
|
||||
|
||||
public void Handle(EpisodeGrabbedEvent message)
|
||||
{
|
||||
foreach (var episode in message.Episode.Episodes)
|
||||
{
|
||||
var history = new History
|
||||
{
|
||||
EventType = HistoryEventType.Grabbed,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.Episode.ParsedEpisodeInfo.Quality,
|
||||
SourceTitle = message.Episode.Release.Title,
|
||||
SeriesId = episode.SeriesId,
|
||||
EpisodeId = episode.Id,
|
||||
DownloadId = message.DownloadId
|
||||
};
|
||||
|
||||
history.Data.Add("Indexer", message.Episode.Release.Indexer);
|
||||
history.Data.Add("NzbInfoUrl", message.Episode.Release.InfoUrl);
|
||||
history.Data.Add("ReleaseGroup", message.Episode.ParsedEpisodeInfo.ReleaseGroup);
|
||||
history.Data.Add("Age", message.Episode.Release.Age.ToString());
|
||||
history.Data.Add("AgeHours", message.Episode.Release.AgeHours.ToString());
|
||||
history.Data.Add("AgeMinutes", message.Episode.Release.AgeMinutes.ToString());
|
||||
history.Data.Add("PublishedDate", message.Episode.Release.PublishDate.ToString("s") + "Z");
|
||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||
history.Data.Add("Size", message.Episode.Release.Size.ToString());
|
||||
history.Data.Add("DownloadUrl", message.Episode.Release.DownloadUrl);
|
||||
history.Data.Add("Guid", message.Episode.Release.Guid);
|
||||
history.Data.Add("TvRageId", message.Episode.Release.TvRageId.ToString());
|
||||
history.Data.Add("Protocol", ((int)message.Episode.Release.DownloadProtocol).ToString());
|
||||
|
||||
if (!message.Episode.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace())
|
||||
{
|
||||
history.Data.Add("ReleaseHash", message.Episode.ParsedEpisodeInfo.ReleaseHash);
|
||||
}
|
||||
|
||||
var torrentRelease = message.Episode.Release as TorrentInfo;
|
||||
|
||||
if (torrentRelease != null)
|
||||
{
|
||||
history.Data.Add("TorrentInfoHash", torrentRelease.InfoHash);
|
||||
}
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(EpisodeImportedEvent message)
|
||||
{
|
||||
if (!message.NewDownload)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var downloadId = message.DownloadId;
|
||||
|
||||
if (downloadId.IsNullOrWhiteSpace())
|
||||
{
|
||||
downloadId = FindDownloadId(message);
|
||||
}
|
||||
|
||||
foreach (var episode in message.EpisodeInfo.Episodes)
|
||||
{
|
||||
var history = new History
|
||||
{
|
||||
EventType = HistoryEventType.DownloadFolderImported,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.EpisodeInfo.Quality,
|
||||
SourceTitle = message.ImportedEpisode.SceneName ?? Path.GetFileNameWithoutExtension(message.EpisodeInfo.Path),
|
||||
SeriesId = message.ImportedEpisode.SeriesId,
|
||||
EpisodeId = episode.Id,
|
||||
DownloadId = downloadId
|
||||
};
|
||||
|
||||
//Won't have a value since we publish this event before saving to DB.
|
||||
//history.Data.Add("FileId", message.ImportedEpisode.Id.ToString());
|
||||
history.Data.Add("DroppedPath", message.EpisodeInfo.Path);
|
||||
history.Data.Add("ImportedPath", Path.Combine(message.EpisodeInfo.Series.Path, message.ImportedEpisode.RelativePath));
|
||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
}
|
||||
}
|
||||
|
||||
public void Handle(DownloadFailedEvent message)
|
||||
{
|
||||
foreach (var episodeId in message.EpisodeIds)
|
||||
|
@ -254,6 +254,7 @@
|
||||
<Compile Include="Datastore\Migration\081_move_dot_prefix_to_transmission_category.cs" />
|
||||
<Compile Include="Datastore\Migration\079_dedupe_tags.cs" />
|
||||
<Compile Include="Datastore\Migration\070_delay_profile.cs" />
|
||||
<Compile Include="Datastore\Migration\083_additonal_blacklist_columns.cs" />
|
||||
<Compile Include="Datastore\Migration\082_add_fanzub_settings.cs" />
|
||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
||||
|
@ -1,19 +1,27 @@
|
||||
var vent = require('vent');
|
||||
var NzbDroneCell = require('../../Cells/NzbDroneCell');
|
||||
var BlacklistDetailsLayout = require('./Details/BlacklistDetailsLayout');
|
||||
|
||||
module.exports = NzbDroneCell.extend({
|
||||
className : 'blacklist-controls-cell',
|
||||
className : 'blacklist-actions-cell',
|
||||
|
||||
events : {
|
||||
'click' : '_delete'
|
||||
'click .x-details' : '_details',
|
||||
'click .x-delete' : '_delete'
|
||||
},
|
||||
|
||||
render : function() {
|
||||
this.$el.empty();
|
||||
this.$el.html('<i class="icon-sonarr-delete"></i>');
|
||||
this.$el.html('<i class="icon-sonarr-info x-details"></i>' +
|
||||
'<i class="icon-sonarr-delete x-delete"></i>');
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_details : function() {
|
||||
vent.trigger(vent.Commands.OpenModalCommand, new BlacklistDetailsLayout({ model : this.model }));
|
||||
},
|
||||
|
||||
_delete : function() {
|
||||
this.model.destroy();
|
||||
}
|
||||
|
14
src/UI/Activity/Blacklist/Details/BlacklistDetailsLayout.js
Normal file
14
src/UI/Activity/Blacklist/Details/BlacklistDetailsLayout.js
Normal file
@ -0,0 +1,14 @@
|
||||
var Marionette = require('marionette');
|
||||
var BlacklistDetailsView = require('./BlacklistDetailsView');
|
||||
|
||||
module.exports = Marionette.Layout.extend({
|
||||
template : 'Activity/Blacklist/Details/BlacklistDetailsLayoutTemplate',
|
||||
|
||||
regions : {
|
||||
bodyRegion : '.modal-body'
|
||||
},
|
||||
|
||||
onShow : function() {
|
||||
this.bodyRegion.show(new BlacklistDetailsView({ model : this.model }));
|
||||
}
|
||||
});
|
@ -0,0 +1,18 @@
|
||||
<div class="modal-content">
|
||||
<div class="history-detail-modal">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
|
||||
<h3>
|
||||
Blacklisted
|
||||
</h3>
|
||||
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn" data-dismiss="modal">close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,5 @@
|
||||
var Marionette = require('marionette');
|
||||
|
||||
module.exports = Marionette.ItemView.extend({
|
||||
template : 'Activity/Blacklist/Details/BlacklistDetailsViewTemplate'
|
||||
});
|
@ -0,0 +1,23 @@
|
||||
<dl class="dl-horizontal info">
|
||||
|
||||
<dt>Name:</dt>
|
||||
<dd>{{sourceTitle}}</dd>
|
||||
|
||||
{{#if protocol}}
|
||||
{{#unless_eq protocol compare="unknown"}}
|
||||
<dt>Protocol:</dt>
|
||||
<dd>{{protocol}}</dd>
|
||||
{{/unless_eq}}
|
||||
{{/if}}
|
||||
|
||||
{{#if indexer}}
|
||||
<dt>Indexer:</dt>
|
||||
<dd>{{indexer}}</dd>
|
||||
{{/if}}
|
||||
|
||||
|
||||
{{#if message}}
|
||||
<dt>Message:</dt>
|
||||
<dd>{{message}}</dd>
|
||||
{{/if}}
|
||||
</dl>
|
@ -236,3 +236,15 @@ td.delete-episode-file-cell {
|
||||
.age-cell {
|
||||
cursor : default;
|
||||
}
|
||||
|
||||
.blacklist-actions-cell {
|
||||
min-width : 55px;
|
||||
width : 55px;
|
||||
text-align : right !important;
|
||||
|
||||
i {
|
||||
.clickable();
|
||||
margin-left : 2px;
|
||||
margin-right : 2px;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user