Blacklisting will trigger episode search
This commit is contained in:
parent
68e40bca29
commit
8520fe3e0c
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications.RssSync;
|
||||
using NzbDrone.Core.Download;
|
||||
|
@ -17,9 +18,9 @@ using NzbDrone.Core.Test.Framework;
|
|||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class UpgradeHistorySpecificationFixture : CoreTest<UpgradeHistorySpecification>
|
||||
public class HistorySpecificationFixture : CoreTest<HistorySpecification>
|
||||
{
|
||||
private UpgradeHistorySpecification _upgradeHistory;
|
||||
private HistorySpecification _upgradeHistory;
|
||||
|
||||
private RemoteEpisode _parseResultMulti;
|
||||
private RemoteEpisode _parseResultSingle;
|
||||
|
@ -31,7 +32,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
public void Setup()
|
||||
{
|
||||
Mocker.Resolve<QualityUpgradableSpecification>();
|
||||
_upgradeHistory = Mocker.Resolve<UpgradeHistorySpecification>();
|
||||
_upgradeHistory = Mocker.Resolve<HistorySpecification>();
|
||||
|
||||
var singleEpisodeList = new List<Episode> { new Episode { Id = 1, SeasonNumber = 12, EpisodeNumber = 3 } };
|
||||
var doubleEpisodeList = new List<Episode> {
|
||||
|
@ -81,6 +82,18 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
Mocker.GetMock<IHistoryService>().Setup(c => c.GetBestQualityInHistory(2)).Returns(_upgradableQuality);
|
||||
}
|
||||
|
||||
private void GivenSabnzbdDownloadClient()
|
||||
{
|
||||
Mocker.GetMock<IProvideDownloadClient>()
|
||||
.Setup(c => c.GetDownloadClient()).Returns(Mocker.Resolve<SabnzbdClient>());
|
||||
}
|
||||
|
||||
private void GivenMostRecentForEpisode(HistoryEventType eventType)
|
||||
{
|
||||
Mocker.GetMock<IHistoryService>().Setup(s => s.MostRecentForEpisode(It.IsAny<int>()))
|
||||
.Returns(new History.History { EventType = eventType });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_upgradable_if_only_episode_is_upgradable()
|
||||
{
|
||||
|
@ -135,12 +148,38 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_using_sabnzbd()
|
||||
public void should_return_true_if_using_sabnzbd_and_nothing_in_history()
|
||||
{
|
||||
Mocker.GetMock<IProvideDownloadClient>()
|
||||
.Setup(c => c.GetDownloadClient()).Returns(Mocker.Resolve<SabnzbdClient>());
|
||||
GivenSabnzbdDownloadClient();
|
||||
|
||||
_upgradeHistory.IsSatisfiedBy(_parseResultMulti, new SeasonSearchCriteria()).Should().BeTrue();
|
||||
_upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_most_recent_in_history_is_grabbed()
|
||||
{
|
||||
GivenSabnzbdDownloadClient();
|
||||
GivenMostRecentForEpisode(HistoryEventType.Grabbed);
|
||||
|
||||
_upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_most_recent_in_history_is_failed()
|
||||
{
|
||||
GivenSabnzbdDownloadClient();
|
||||
GivenMostRecentForEpisode(HistoryEventType.DownloadFailed);
|
||||
|
||||
_upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_most_recent_in_history_is_imported()
|
||||
{
|
||||
GivenSabnzbdDownloadClient();
|
||||
GivenMostRecentForEpisode(HistoryEventType.DownloadFolderImported);
|
||||
|
||||
_upgradeHistory.IsSatisfiedBy(_parseResultMulti, null).Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,7 +121,6 @@
|
|||
<Compile Include="Download\DownloadClientTests\NzbgetProviderTests\DownloadNzbFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\NzbgetProviderTests\QueueFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\PneumaticProviderFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\SabProviderTests\QueueFixture.cs" />
|
||||
<Compile Include="Download\DownloadClientTests\SabProviderTests\SabProviderFixture.cs" />
|
||||
<Compile Include="Download\DownloadServiceFixture.cs" />
|
||||
<Compile Include="Download\FailedDownloadServiceFixture.cs" />
|
||||
|
@ -194,7 +193,7 @@
|
|||
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesBetweenDatesFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\RetentionSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\QualityAllowedByProfileSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\UpgradeHistorySpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\HistorySpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\UpgradeDiskSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\QualityUpgradeSpecificationFixture.cs" />
|
||||
<Compile Include="ProviderTests\DiskProviderTests\FreeDiskSpaceFixture.cs" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
|
@ -6,8 +7,8 @@ namespace NzbDrone.Core.Blacklisting
|
|||
{
|
||||
public class Blacklist : ModelBase
|
||||
{
|
||||
public int EpisodeId { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public List<int> EpisodeIds { get; set; }
|
||||
public string SourceTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
|
|
|
@ -15,10 +15,12 @@ namespace NzbDrone.Core.Blacklisting
|
|||
public class BlacklistService : IBlacklistService, IHandle<DownloadFailedEvent>
|
||||
{
|
||||
private readonly IBlacklistRepository _blacklistRepository;
|
||||
private readonly IRedownloadFailedDownloads _redownloadFailedDownloadService;
|
||||
|
||||
public BlacklistService(IBlacklistRepository blacklistRepository)
|
||||
public BlacklistService(IBlacklistRepository blacklistRepository, IRedownloadFailedDownloads redownloadFailedDownloadService)
|
||||
{
|
||||
_blacklistRepository = blacklistRepository;
|
||||
_redownloadFailedDownloadService = redownloadFailedDownloadService;
|
||||
}
|
||||
|
||||
public bool Blacklisted(string sourceTitle)
|
||||
|
@ -30,14 +32,16 @@ namespace NzbDrone.Core.Blacklisting
|
|||
{
|
||||
var blacklist = new Blacklist
|
||||
{
|
||||
SeriesId = message.Series.Id,
|
||||
EpisodeId = message.Episode.Id,
|
||||
SeriesId = message.SeriesId,
|
||||
EpisodeIds = message.EpisodeIds,
|
||||
SourceTitle = message.SourceTitle,
|
||||
Quality = message.Quality,
|
||||
Date = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_blacklistRepository.Insert(blacklist);
|
||||
|
||||
_redownloadFailedDownloadService.Redownload(message.SeriesId, message.EpisodeIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
|||
{
|
||||
Create.TableForModel("Blacklist")
|
||||
.WithColumn("SeriesId").AsInt32()
|
||||
.WithColumn("EpisodeId").AsInt32()
|
||||
.WithColumn("EpisodeIds").AsString()
|
||||
.WithColumn("SourceTitle").AsString()
|
||||
.WithColumn("Quality").AsString()
|
||||
.WithColumn("Date").AsDateTime();
|
||||
|
|
|
@ -3,18 +3,19 @@ using NzbDrone.Core.Download;
|
|||
using NzbDrone.Core.Download.Clients.Sabnzbd;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.MetadataSource.Trakt;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||
{
|
||||
public class UpgradeHistorySpecification : IDecisionEngineSpecification
|
||||
public class HistorySpecification : IDecisionEngineSpecification
|
||||
{
|
||||
private readonly IHistoryService _historyService;
|
||||
private readonly QualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
private readonly IProvideDownloadClient _downloadClientProvider;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public UpgradeHistorySpecification(IHistoryService historyService,
|
||||
public HistorySpecification(IHistoryService historyService,
|
||||
QualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
IProvideDownloadClient downloadClientProvider,
|
||||
Logger logger)
|
||||
|
@ -43,7 +44,17 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
|||
|
||||
if (_downloadClientProvider.GetDownloadClient().GetType() == typeof (SabnzbdClient))
|
||||
{
|
||||
_logger.Trace("Skipping history check in favour of blacklist");
|
||||
_logger.Trace("Performing history status check on report");
|
||||
foreach (var episode in subject.Episodes)
|
||||
{
|
||||
_logger.Trace("Checking current status of episode [{0}] in history", episode.Id);
|
||||
var mostRecent = _historyService.MostRecentForEpisode(episode.Id);
|
||||
|
||||
if (mostRecent != null && mostRecent.EventType == HistoryEventType.Grabbed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Messaging;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
|
@ -6,8 +7,8 @@ namespace NzbDrone.Core.Download
|
|||
{
|
||||
public class DownloadFailedEvent : IEvent
|
||||
{
|
||||
public Series Series { get; set; }
|
||||
public Episode Episode { get; set; }
|
||||
public Int32 SeriesId { get; set; }
|
||||
public List<Int32> EpisodeIds { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public String SourceTitle { get; set; }
|
||||
public String DownloadClient { get; set; }
|
||||
|
|
|
@ -41,15 +41,15 @@ namespace NzbDrone.Core.Download
|
|||
return;
|
||||
}
|
||||
|
||||
var recentHistory = _historyService.BetweenDates(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow, HistoryEventType.Grabbed);
|
||||
var grabbedHistory = _historyService.Grabbed();
|
||||
var failedHistory = _historyService.Failed();
|
||||
|
||||
foreach (var failedItem in failedItems)
|
||||
{
|
||||
var failedLocal = failedItem;
|
||||
var historyItems = recentHistory.Where(h => h.Data.ContainsKey(DOWNLOAD_CLIENT) &&
|
||||
h.Data[DOWNLOAD_CLIENT_ID].Equals(failedLocal.Id))
|
||||
.ToList();
|
||||
var historyItems = grabbedHistory.Where(h => h.Data.ContainsKey(DOWNLOAD_CLIENT) &&
|
||||
h.Data[DOWNLOAD_CLIENT_ID].Equals(failedLocal.Id))
|
||||
.ToList();
|
||||
|
||||
if (!historyItems.Any())
|
||||
{
|
||||
|
@ -64,18 +64,17 @@ namespace NzbDrone.Core.Download
|
|||
continue;
|
||||
}
|
||||
|
||||
foreach (var historyItem in historyItems)
|
||||
var historyItem = historyItems.First();
|
||||
|
||||
_eventAggregator.PublishEvent(new DownloadFailedEvent
|
||||
{
|
||||
_eventAggregator.PublishEvent(new DownloadFailedEvent
|
||||
{
|
||||
Series = historyItem.Series,
|
||||
Episode = historyItem.Episode,
|
||||
Quality = historyItem.Quality,
|
||||
SourceTitle = historyItem.SourceTitle,
|
||||
DownloadClient = historyItem.Data[DOWNLOAD_CLIENT],
|
||||
DownloadClientId = historyItem.Data[DOWNLOAD_CLIENT_ID]
|
||||
});
|
||||
}
|
||||
SeriesId = historyItem.SeriesId,
|
||||
EpisodeIds = historyItems.Select(h => h.EpisodeId).ToList(),
|
||||
Quality = historyItem.Quality,
|
||||
SourceTitle = historyItem.SourceTitle,
|
||||
DownloadClient = historyItem.Data[DOWNLOAD_CLIENT],
|
||||
DownloadClientId = historyItem.Data[DOWNLOAD_CLIENT_ID]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.IndexerSearch;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Download
|
||||
{
|
||||
public interface IRedownloadFailedDownloads
|
||||
{
|
||||
void Redownload(int seriesId, List<int> episodeIds);
|
||||
}
|
||||
|
||||
public class RedownloadFailedDownloadService : IRedownloadFailedDownloads
|
||||
{
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly ICommandExecutor _commandExecutor;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public RedownloadFailedDownloadService(IEpisodeService episodeService, ICommandExecutor commandExecutor, Logger logger)
|
||||
{
|
||||
_episodeService = episodeService;
|
||||
_commandExecutor = commandExecutor;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Redownload(int seriesId, List<int> episodeIds)
|
||||
{
|
||||
if (episodeIds.Count == 1)
|
||||
{
|
||||
_logger.Trace("Failed download only contains one episode, searching again");
|
||||
|
||||
_commandExecutor.PublishCommandAsync(new EpisodeSearchCommand
|
||||
{
|
||||
EpisodeIds = episodeIds.ToList()
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var seasonNumber = _episodeService.GetEpisode(episodeIds.First()).SeasonNumber;
|
||||
var episodesInSeason = _episodeService.GetEpisodesBySeason(seriesId, seasonNumber);
|
||||
|
||||
if (episodeIds.Count == episodesInSeason.Count)
|
||||
{
|
||||
_logger.Trace("Failed download was entire season, searching again");
|
||||
|
||||
_commandExecutor.PublishCommandAsync(new SeasonSearchCommand
|
||||
{
|
||||
SeriesId = seriesId,
|
||||
SeasonNumber = seasonNumber
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Trace("Failed download contains multiple episodes, probably a double episode, searching again");
|
||||
|
||||
_commandExecutor.PublishCommandAsync(new EpisodeSearchCommand
|
||||
{
|
||||
EpisodeIds = episodeIds.ToList()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Marr.Data.QGen;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
|
@ -15,6 +14,8 @@ namespace NzbDrone.Core.History
|
|||
List<QualityModel> GetBestQualityInHistory(int episodeId);
|
||||
List<History> BetweenDates(DateTime startDate, DateTime endDate, HistoryEventType eventType);
|
||||
List<History> Failed();
|
||||
List<History> Grabbed();
|
||||
History MostRecentForEpisode(int episodeId);
|
||||
}
|
||||
|
||||
public class HistoryRepository : BasicRepository<History>, IHistoryRepository
|
||||
|
@ -54,6 +55,18 @@ namespace NzbDrone.Core.History
|
|||
return Query.Where(h => h.EventType == HistoryEventType.DownloadFailed);
|
||||
}
|
||||
|
||||
public List<History> Grabbed()
|
||||
{
|
||||
return Query.Where(h => h.EventType == HistoryEventType.Grabbed);
|
||||
}
|
||||
|
||||
public History MostRecentForEpisode(int episodeId)
|
||||
{
|
||||
return Query.Where(h => h.EpisodeId == episodeId)
|
||||
.OrderByDescending(h => h.Date)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public override PagingSpec<History> GetPaged(PagingSpec<History> pagingSpec)
|
||||
{
|
||||
pagingSpec.Records = GetPagedQuery(pagingSpec).ToList();
|
||||
|
|
|
@ -20,6 +20,8 @@ namespace NzbDrone.Core.History
|
|||
PagingSpec<History> Paged(PagingSpec<History> pagingSpec);
|
||||
List<History> BetweenDates(DateTime startDate, DateTime endDate, HistoryEventType eventType);
|
||||
List<History> Failed();
|
||||
List<History> Grabbed();
|
||||
History MostRecentForEpisode(int episodeId);
|
||||
}
|
||||
|
||||
public class HistoryService : IHistoryService, IHandle<EpisodeGrabbedEvent>, IHandle<EpisodeImportedEvent>, IHandle<DownloadFailedEvent>
|
||||
|
@ -53,6 +55,16 @@ namespace NzbDrone.Core.History
|
|||
return _historyRepository.Failed();
|
||||
}
|
||||
|
||||
public List<History> Grabbed()
|
||||
{
|
||||
return _historyRepository.Grabbed();
|
||||
}
|
||||
|
||||
public History MostRecentForEpisode(int episodeId)
|
||||
{
|
||||
return _historyRepository.MostRecentForEpisode(episodeId);
|
||||
}
|
||||
|
||||
public void Purge()
|
||||
{
|
||||
_historyRepository.Purge();
|
||||
|
@ -122,20 +134,23 @@ namespace NzbDrone.Core.History
|
|||
|
||||
public void Handle(DownloadFailedEvent message)
|
||||
{
|
||||
var history = new History
|
||||
foreach (var episodeId in message.EpisodeIds)
|
||||
{
|
||||
EventType = HistoryEventType.DownloadFailed,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.Quality,
|
||||
SourceTitle = message.SourceTitle,
|
||||
SeriesId = message.Series.Id,
|
||||
EpisodeId = message.Episode.Id,
|
||||
};
|
||||
var history = new History
|
||||
{
|
||||
EventType = HistoryEventType.DownloadFailed,
|
||||
Date = DateTime.UtcNow,
|
||||
Quality = message.Quality,
|
||||
SourceTitle = message.SourceTitle,
|
||||
SeriesId = message.SeriesId,
|
||||
EpisodeId = episodeId,
|
||||
};
|
||||
|
||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||
history.Data.Add("DownloadClientId", message.DownloadClientId);
|
||||
history.Data.Add("DownloadClient", message.DownloadClient);
|
||||
history.Data.Add("DownloadClientId", message.DownloadClientId);
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
_historyRepository.Insert(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -223,7 +223,7 @@
|
|||
<Compile Include="DecisionEngine\QualityUpgradableSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\Search\SingleEpisodeSearchMatchSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\RssSync\UpgradeHistorySpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\RssSync\HistorySpecification.cs" />
|
||||
<Compile Include="DiskSpace\DiskSpace.cs" />
|
||||
<Compile Include="DiskSpace\DiskSpaceService.cs" />
|
||||
<Compile Include="Download\Clients\Sabnzbd\ConnectionInfoModel.cs" />
|
||||
|
@ -239,6 +239,7 @@
|
|||
<Compile Include="Download\DownloadClientType.cs" />
|
||||
<Compile Include="Download\FailedDownloadService.cs" />
|
||||
<Compile Include="Download\QueueItem.cs" />
|
||||
<Compile Include="Download\RedownloadFailedDownloadService.cs" />
|
||||
<Compile Include="Exceptions\BadRequestException.cs" />
|
||||
<Compile Include="Exceptions\DownstreamException.cs" />
|
||||
<Compile Include="Exceptions\NzbDroneClientException.cs" />
|
||||
|
@ -358,7 +359,6 @@
|
|||
<Compile Include="IndexerSearch\Definitions\SeasonSearchCriteria.cs" />
|
||||
<Compile Include="IndexerSearch\Definitions\SingleEpisodeSearchCriteria.cs" />
|
||||
<Compile Include="IndexerSearch\NzbSearchService.cs" />
|
||||
<Compile Include="IndexerSearch\SearchAndDownloadService.cs" />
|
||||
<Compile Include="Indexers\RssParserBase.cs" />
|
||||
<Compile Include="Indexers\RssSyncService.cs" />
|
||||
<Compile Include="Indexers\IndexerBase.cs" />
|
||||
|
|
Loading…
Reference in New Issue