Your ROOT_URL in app.ini is https://git.cloudchain.link/ but you are visiting https://dash.bss.nz/open-source-mirrors/Readarr/commit/9c6d78d4794aa5b691c9d38f77a5f977245ea736 You should set ROOT_URL correctly, otherwise the web may not work correctly.

Cleanup and updates for XEM

SceneSource added to signify to lookup via scene name
Use Episodes for naming instead of EpisodeNumbers (in ParseResult)
pull/6/head
Mark McDowall 13 years ago
parent c9c967fa1d
commit 9c6d78d479

@ -175,6 +175,18 @@ namespace NzbDrone.Common.Test
Console.WriteLine(new DirectoryInfo(@"C:\DRIVERS").LastWriteTimeUtc);
}
[Test]
public void IsChildOfPath_should_return_true_when_it_is_a_child()
{
Mocker.Resolve<DiskProvider>().IsChildOfPath(@"C:\Test\TV", @"C:\Test").Should().BeTrue();
}
[Test]
public void IsChildOfPath_should_return_false_when_it_is_not_a_child()
{
Mocker.Resolve<DiskProvider>().IsChildOfPath(@"C:\NOT_Test\TV", @"C:\Test").Should().BeFalse();
}
private void VerifyCopy()
{
BinFolder.Refresh();

@ -235,5 +235,13 @@ namespace NzbDrone.Common
{
Directory.SetLastWriteTimeUtc(path, dateTime);
}
public virtual bool IsChildOfPath(string child, string parent)
{
if (Path.GetFullPath(child).StartsWith(Path.GetFullPath(parent)))
return true;
return false;
}
}
}

@ -23,5 +23,8 @@
<NamedTestSelector>
<TestName>NzbDrone.Core.Test.Integeration.ServiceIntegerationFixture.should_be_able_to_submit_exceptions</TestName>
</NamedTestSelector>
<NamedTestSelector>
<TestName>NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests.ImportFileFixture.import_unparsable_file_should_skip</TestName>
</NamedTestSelector>
</IgnoredTests>
</ProjectConfiguration>

@ -32,6 +32,9 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
{
_customStartDateSpecification = Mocker.Resolve<CustomStartDateSpecification>();
firstEpisode = new Episode { AirDate = DateTime.Today };
secondEpisode = new Episode { AirDate = DateTime.Today };
fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(c => c.CustomStartDate = null)
@ -43,6 +46,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Series = fakeSeries,
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
Episodes = new List<Episode> { firstEpisode, secondEpisode }
};
parseResultSingle = new EpisodeParseResult
@ -51,16 +55,8 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Series = fakeSeries,
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
Episodes = new List<Episode> { firstEpisode }
};
firstEpisode = new Episode { AirDate = DateTime.Today };
secondEpisode = new Episode { AirDate = DateTime.Today };
var singleEpisodeList = new List<Episode> { firstEpisode };
var doubleEpisodeList = new List<Episode> { firstEpisode, secondEpisode };
Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList);
Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList);
}
private void WithFirstEpisodeLastYear()

@ -31,6 +31,12 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Mocker.Resolve<QualityUpgradeSpecification>();
_upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>();
firstFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true };
secondFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true };
var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = null } };
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = secondFile }, new Episode { EpisodeFile = null } };
var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.QualityProfile = new QualityProfile { Cutoff = QualityTypes.Bluray1080p })
.Build();
@ -41,6 +47,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Quality = new Quality(QualityTypes.DVD, true),
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
Episodes = doubleEpisodeList
};
parseResultSingle = new EpisodeParseResult
@ -49,17 +56,8 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Quality = new Quality(QualityTypes.DVD, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
Episodes = singleEpisodeList
};
firstFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true };
secondFile = new EpisodeFile { Quality = QualityTypes.Bluray1080p, Proper = true };
var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = null } };
var doubleEpisodeList = new List<Episode> { new Episode { EpisodeFile = firstFile }, new Episode { EpisodeFile = secondFile }, new Episode { EpisodeFile = null } };
Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList);
Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList);
}
private void WithFirstFileUpgradable()
@ -73,9 +71,9 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
}
[Test]
public void should_return_false_if_single_episode_doesnt_exist_on_disk()
public void should_return_true_if_single_episode_doesnt_exist_on_disk()
{
Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(new List<Episode>());
parseResultSingle.Episodes = new List<Episode>();
_upgradeDisk.IsSatisfiedBy(parseResultSingle).Should().BeTrue();
}

@ -31,6 +31,13 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Mocker.Resolve<QualityUpgradeSpecification>();
_upgradeHistory = Mocker.Resolve<UpgradeHistorySpecification>();
var singleEpisodeList = new List<Episode> { new Episode { SeasonNumber = 12, EpisodeNumber = 3 } };
var doubleEpisodeList = new List<Episode> {
new Episode { SeasonNumber = 12, EpisodeNumber = 3 },
new Episode { SeasonNumber = 12, EpisodeNumber = 4 },
new Episode { SeasonNumber = 12, EpisodeNumber = 5 }
};
var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.QualityProfile = new QualityProfile { Cutoff = QualityTypes.Bluray1080p })
.Build();
@ -41,6 +48,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Quality = new Quality(QualityTypes.DVD, true),
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
Episodes = doubleEpisodeList
};
parseResultSingle = new EpisodeParseResult
@ -49,21 +57,12 @@ namespace NzbDrone.Core.Test.ProviderTests.DecisionEngineTests
Quality = new Quality(QualityTypes.DVD, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
Episodes = singleEpisodeList
};
firstQuality = new Quality(QualityTypes.Bluray1080p, true);
secondQuality = new Quality(QualityTypes.Bluray1080p, true);
var singleEpisodeList = new List<Episode> { new Episode { SeasonNumber = 12, EpisodeNumber = 3 } };
var doubleEpisodeList = new List<Episode> {
new Episode { SeasonNumber = 12, EpisodeNumber = 3 },
new Episode { SeasonNumber = 12, EpisodeNumber = 4 },
new Episode { SeasonNumber = 12, EpisodeNumber = 5 }
};
Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultSingle)).Returns(singleEpisodeList);
Mocker.GetMock<EpisodeProvider>().Setup(c => c.GetEpisodesByParseResult(parseResultMulti)).Returns(doubleEpisodeList);
Mocker.GetMock<HistoryProvider>().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 3)).Returns(firstQuality);
Mocker.GetMock<HistoryProvider>().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 4)).Returns(secondQuality);
Mocker.GetMock<HistoryProvider>().Setup(c => c.GetBestQualityInHistory(fakeSeries.SeriesId, 12, 5)).Returns<Quality>(null);

@ -201,6 +201,9 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
Mocker.GetMock<DiskProvider>(MockBehavior.Strict)
.Setup(e => e.GetSize(fileName)).Returns(90000000000);
Mocker.GetMock<DiskProvider>(MockBehavior.Strict)
.Setup(e => e.IsChildOfPath(fileName, fakeSeries.Path)).Returns(false);
Mocker.GetMock<EpisodeProvider>()
.Setup(c => c.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>()))
.Returns(new List<Episode>());
@ -416,5 +419,47 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never());
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
}
[Test]
public void should_set_parseResult_SceneSource_if_not_in_series_Path()
{
var series = Builder<Series>
.CreateNew()
.With(s => s.Path == @"C:\Test\TV\30 Rock")
.Build();
const string path = @"C:\Test\Unsorted TV\30 Rock\30.rock.s01e01.pilot.mkv";
Mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>()))
.Returns(new List<Episode>());
Mocker.GetMock<DiskProvider>().Setup(s => s.IsChildOfPath(path, series.Path))
.Returns(false);
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path);
Mocker.Verify<EpisodeProvider>(s => s.GetEpisodesByParseResult(It.Is<EpisodeParseResult>(p => p.SceneSource)), Times.Once());
}
[Test]
public void should_not_set_parseResult_SceneSource_if_in_series_Path()
{
var series = Builder<Series>
.CreateNew()
.With(s => s.Path == @"C:\Test\TV\30 Rock")
.Build();
const string path = @"C:\Test\TV\30 Rock\30.rock.s01e01.pilot.mkv";
Mocker.GetMock<EpisodeProvider>().Setup(s => s.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>()))
.Returns(new List<Episode>());
Mocker.GetMock<DiskProvider>().Setup(s => s.IsChildOfPath(path, series.Path))
.Returns(true);
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path);
Mocker.Verify<EpisodeProvider>(s => s.GetEpisodesByParseResult(It.Is<EpisodeParseResult>(p => p.SceneSource == false)), Times.Once());
}
}
}

@ -43,6 +43,7 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(c => c.Quality = new Quality(QualityTypes.DVD, false))
.With(c => c.Series = Builder<Series>.CreateNew().Build())
.With(c => c.EpisodeNumbers = new List<int>{2})
.With(c => c.Episodes = episodes)
.Build();
}
@ -191,6 +192,11 @@ namespace NzbDrone.Core.Test.ProviderTests
.With(c => c.Title = "My Series Name")
.Build();
var fakeEpisodes = new List<Episode>();
foreach(var episode in episodes)
fakeEpisodes.Add(Builder<Episode>.CreateNew().With(e => e.EpisodeNumber = episode).Build());
var parsResult = new EpisodeParseResult()
{
AirDate = DateTime.Now,
@ -198,7 +204,8 @@ namespace NzbDrone.Core.Test.ProviderTests
Quality = new Quality(quality, proper),
SeasonNumber = seasons,
Series = series,
EpisodeTitle = title
EpisodeTitle = title,
Episodes = fakeEpisodes
};
return Mocker.Resolve<DownloadProvider>().GetDownloadTitle(parsResult);

@ -13,6 +13,8 @@ namespace NzbDrone.Core.Datastore.Migrations
Database.AddColumn("Episodes", new Column("SceneAbsoluteEpisodeNumber", DbType.Int32, ColumnProperty.Null));
Database.AddColumn("Episodes", new Column("SceneSeasonNumber", DbType.Int32, ColumnProperty.Null));
Database.AddColumn("Episodes", new Column("SceneEpisodeNumber", DbType.Int32, ColumnProperty.Null));
Database.AddColumn("Series", new Column("UseSceneNumbering", DbType.Boolean, ColumnProperty.Null));
}
}
}

@ -46,6 +46,10 @@ namespace NzbDrone.Core.Model
public string ReleaseGroup { get; set; }
public bool SceneSource { get; set; }
public IList<Episode> Episodes { get; set; }
public override string ToString()
{

@ -227,6 +227,7 @@
<Compile Include="Datastore\MigrationLogger.cs" />
<Compile Include="Datastore\MigrationsHelper.cs" />
<Compile Include="Datastore\CustomeMapper.cs" />
<Compile Include="Datastore\Migrations\Migration20121016.cs" />
<Compile Include="Datastore\Migrations\Migration20121012.cs" />
<Compile Include="Datastore\Migrations\Migration20120919.cs" />
<Compile Include="Datastore\Migrations\Migration20120918.cs" />
@ -334,6 +335,7 @@
<Compile Include="Jobs\UpdateInfoJob.cs" />
<Compile Include="Providers\StatsProvider.cs" />
<Compile Include="Providers\XemCommunicationProvider.cs" />
<Compile Include="Providers\XemProvider.cs" />
<Compile Include="Repository\MetadataDefinition.cs" />
<Compile Include="Repository\Search\SearchHistoryItem.cs" />
<Compile Include="Repository\Search\SearchHistory.cs" />

@ -29,9 +29,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine
return true;
}
var episodes = _episodeProvider.GetEpisodesByParseResult(subject);
if (episodes.Any(episode => episode.AirDate > subject.Series.CustomStartDate.Value))
if (subject.Episodes.Any(episode => episode.AirDate > subject.Series.CustomStartDate.Value))
{
logger.Debug("One or more episodes aired after cutoff, downloading.");
return true;

@ -42,6 +42,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine
}
var episodes = _episodeProvider.GetEpisodesByParseResult(subject);
subject.Episodes = episodes;
//return monitored if any of the episodes are monitored
if (episodes.Any(episode => !episode.Ignored))

@ -24,7 +24,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
{
foreach (var file in _episodeProvider.GetEpisodesByParseResult(subject).Select(c => c.EpisodeFile).Where(c => c != null))
foreach (var file in subject.Episodes.Select(c => c.EpisodeFile).Where(c => c != null))
{
logger.Trace("Comparing file quality with report. Existing file is {0} proper:{1}", file.Quality, file.Proper);
if (!_qualityUpgradeSpecification.IsSatisfiedBy(new Quality { QualityType = file.Quality, Proper = file.Proper }, subject.Quality, subject.Series.QualityProfile.Cutoff))

@ -27,7 +27,7 @@ namespace NzbDrone.Core.Providers.DecisionEngine
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
{
foreach (var episode in _episodeProvider.GetEpisodesByParseResult(subject))
foreach (var episode in subject.Episodes)
{
var bestQualityInHistory = _historyProvider.GetBestQualityInHistory(subject.Series.SeriesId, episode.SeasonNumber, episode.EpisodeNumber);
if (bestQualityInHistory != null)

@ -122,6 +122,9 @@ namespace NzbDrone.Core.Providers
if (parseResult == null)
return null;
if (!_diskProvider.IsChildOfPath(filePath, series.Path))
parseResult.SceneSource = true;
parseResult.SeriesTitle = series.Title; //replaces the nasty path as title to help with logging
parseResult.Series = series;
@ -203,6 +206,7 @@ namespace NzbDrone.Core.Providers
var parseResult = Parser.ParsePath(episodeFile.Path);
parseResult.Series = series;
parseResult.Quality = new Quality{ QualityType = episodeFile.Quality, Proper = episodeFile.Proper };
parseResult.Episodes = episodes;
var message = _downloadProvider.GetDownloadTitle(parseResult);

@ -48,13 +48,13 @@ namespace NzbDrone.Core.Providers
var provider = GetActiveDownloadClient();
bool success = provider.DownloadNzb(parseResult.NzbUrl, GetDownloadTitle(parseResult));
bool success = provider.DownloadNzb(parseResult.NzbUrl, downloadTitle);
if (success)
{
logger.Trace("Download added to Queue: {0}", downloadTitle);
foreach (var episode in _episodeProvider.GetEpisodesByParseResult(parseResult))
foreach (var episode in parseResult.Episodes)
{
var history = new History
{
@ -127,9 +127,9 @@ namespace NzbDrone.Core.Providers
//Show Name - 1x01 - Episode Name
var episodeString = new List<String>();
foreach (var episode in parseResult.EpisodeNumbers)
foreach (var episode in parseResult.Episodes)
{
episodeString.Add(String.Format("{0}x{1:00}", parseResult.SeasonNumber, episode));
episodeString.Add(String.Format("{0}x{1:00}", parseResult.SeasonNumber, episode.EpisodeNumber));
}
var epNumberString = String.Join("-", episodeString);

@ -188,11 +188,20 @@ namespace NzbDrone.Core.Providers
foreach (var episodeNumber in parseResult.EpisodeNumbers)
{
var episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber);
if (episodeInfo == null && parseResult.AirDate != null)
Episode episodeInfo;
if (parseResult.SceneSource && parseResult.Series.UseSceneNumbering)
episodeInfo = GetEpisodeFromSceneNumbering(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber);
else
{
episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate.Value);
episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.SeasonNumber, episodeNumber);
if (episodeInfo == null && parseResult.AirDate != null)
{
episodeInfo = GetEpisode(parseResult.Series.SeriesId, parseResult.AirDate.Value);
}
}
//if still null we should add the temp episode
if (episodeInfo == null && autoAddNew)
{
@ -440,5 +449,21 @@ namespace NzbDrone.Core.Providers
{
_database.UpdateMany(episodes);
}
public virtual Episode GetEpisodeFromSceneNumbering(int seriesId, int seasonNumber, int episodeNumber)
{
var episode = _database.Fetch<Episode, Series, EpisodeFile>(@"SELECT * FROM Episodes
INNER JOIN Series ON Episodes.SeriesId = Series.SeriesId
LEFT JOIN EpisodeFiles ON Episodes.EpisodeFileId = EpisodeFiles.EpisodeFileId
WHERE Episodes.SeriesId = @0 AND Episodes.SceneSeasonNumber = @1 AND Episodes.SceneEpisodeNumber = @2", seriesId, seasonNumber, episodeNumber).SingleOrDefault();
if (episode == null)
return null;
if (episode.EpisodeFileId == 0)
episode.EpisodeFile = null;
return episode;
}
}
}

@ -247,6 +247,7 @@ namespace NzbDrone.Core.Providers.Indexer
{
episodeParseResult.Age = DateTime.Now.Date.Subtract(item.PublishDate.Date).Days;
episodeParseResult.OriginalString = title;
episodeParseResult.SceneSource = true;
}
_logger.Trace("Parsed: {0} from: {1}", episodeParseResult, item.Title.Text);

@ -112,6 +112,8 @@ namespace NzbDrone.Core.Providers
parseResult.NzbUrl = item.NzbUrl;
parseResult.Series = series;
parseResult.Indexer = item.Indexer;
parseResult.Episodes = _episodeProvider.GetEpisodesByParseResult(parseResult);
parseResult.SceneSource = true;
logger.Info("Forcing Download of: {0}", item.ReportTitle);
_downloadProvider.DownloadReport(parseResult);

@ -319,6 +319,8 @@ namespace NzbDrone.Core.Providers
continue;
}
episodeParseResult.Episodes = _episodeProvider.GetEpisodesByParseResult(episodeParseResult);
item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
if (item.SearchError == ReportRejectionType.None)
{
@ -403,6 +405,8 @@ namespace NzbDrone.Core.Providers
continue;
}
episodeParseResult.Episodes = _episodeProvider.GetEpisodesByParseResult(episodeParseResult);
item.SearchError = _allowedDownloadSpecification.IsSatisfiedBy(episodeParseResult);
if (item.SearchError == ReportRejectionType.None)
{

@ -50,6 +50,8 @@ namespace NzbDrone.Core.Repository
public DateTime? CustomStartDate { get; set; }
public bool UseSceneNumbering { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="Series"/> is hidden.
/// </summary>

Loading…
Cancel
Save