Fixed: Will no longer cause an error when trying to parse an anime episode with absolute number 0.
This commit is contained in:
parent
e978a425c2
commit
6dfbc3c290
|
@ -20,11 +20,11 @@ namespace NzbDrone.Api.Episodes
|
||||||
|
|
||||||
public Boolean HasFile { get; set; }
|
public Boolean HasFile { get; set; }
|
||||||
public Boolean Monitored { get; set; }
|
public Boolean Monitored { get; set; }
|
||||||
|
public Nullable<Int32> AbsoluteEpisodeNumber { get; set; }
|
||||||
public Nullable<Int32> SceneAbsoluteEpisodeNumber { get; set; }
|
public Nullable<Int32> SceneAbsoluteEpisodeNumber { get; set; }
|
||||||
public Int32 SceneEpisodeNumber { get; set; }
|
public Nullable<Int32> SceneEpisodeNumber { get; set; }
|
||||||
public Int32 SceneSeasonNumber { get; set; }
|
public Nullable<Int32> SceneSeasonNumber { get; set; }
|
||||||
public Int32 TvDbEpisodeId { get; set; }
|
public Int32 TvDbEpisodeId { get; set; }
|
||||||
public Int32? AbsoluteEpisodeNumber { get; set; }
|
|
||||||
public DateTime? EndTime { get; set; }
|
public DateTime? EndTime { get; set; }
|
||||||
public DateTime? GrabDate { get; set; }
|
public DateTime? GrabDate { get; set; }
|
||||||
public String SeriesTitle { get; set; }
|
public String SeriesTitle { get; set; }
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
.Returns(new List<String>());
|
.Returns(new List<String>());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WithEpisode(int seasonNumber, int episodeNumber, int sceneSeasonNumber, int sceneEpisodeNumber)
|
private void WithEpisode(Int32 seasonNumber, Int32 episodeNumber, Int32? sceneSeasonNumber, Int32? sceneEpisodeNumber)
|
||||||
{
|
{
|
||||||
var episode = Builder<Episode>.CreateNew()
|
var episode = Builder<Episode>.CreateNew()
|
||||||
.With(v => v.SeriesId == _xemSeries.Id)
|
.With(v => v.SeriesId == _xemSeries.Id)
|
||||||
|
@ -90,8 +90,8 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||||
WithEpisode(5, 1, 6, 12);
|
WithEpisode(5, 1, 6, 12);
|
||||||
|
|
||||||
// Season 7+ maps normally, so no mapping specified.
|
// Season 7+ maps normally, so no mapping specified.
|
||||||
WithEpisode(7, 1, 0, 0);
|
WithEpisode(7, 1, null, null);
|
||||||
WithEpisode(7, 2, 0, 0);
|
WithEpisode(7, 2, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SearchCriteriaBase> WatchForSearchCriteria()
|
private List<SearchCriteriaBase> WatchForSearchCriteria()
|
||||||
|
|
|
@ -530,10 +530,10 @@ namespace NzbDrone.Core.Test.OrganizerTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_use_standard_naming_when_anime_episode_has_absolute_number_of_zero()
|
public void should_use_standard_naming_when_anime_episode_has_no_absolute_number()
|
||||||
{
|
{
|
||||||
_series.SeriesType = SeriesTypes.Anime;
|
_series.SeriesType = SeriesTypes.Anime;
|
||||||
_episode1.AbsoluteEpisodeNumber = 0;
|
_episode1.AbsoluteEpisodeNumber = null;
|
||||||
|
|
||||||
_namingConfig.StandardEpisodeFormat = "{Series Title} - {season:0}x{episode:00} - {Episode Title}";
|
_namingConfig.StandardEpisodeFormat = "{Series Title} - {season:0}x{episode:00} - {Episode Title}";
|
||||||
_namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}";
|
_namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}";
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_find_episode_by_scene_numbering()
|
public void should_find_episode_by_scene_numbering()
|
||||||
{
|
{
|
||||||
Subject.FindEpisodesBySceneNumbering(_episode1.SeriesId, _episode1.SceneSeasonNumber, _episode1.SceneEpisodeNumber)
|
Subject.FindEpisodesBySceneNumbering(_episode1.SeriesId, _episode1.SceneSeasonNumber.Value, _episode1.SceneEpisodeNumber.Value)
|
||||||
.First()
|
.First()
|
||||||
.Id
|
.Id
|
||||||
.Should()
|
.Should()
|
||||||
|
@ -77,7 +77,7 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
{
|
{
|
||||||
_episode2 = Db.Insert(_episode2);
|
_episode2 = Db.Insert(_episode2);
|
||||||
|
|
||||||
Subject.FindEpisodesBySceneNumbering(_episode1.SeriesId, _episode1.SceneSeasonNumber, _episode1.SceneEpisodeNumber)
|
Subject.FindEpisodesBySceneNumbering(_episode1.SeriesId, _episode1.SceneSeasonNumber.Value, _episode1.SceneEpisodeNumber.Value)
|
||||||
.Should()
|
.Should()
|
||||||
.HaveCount(2);
|
.HaveCount(2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
|
|
||||||
Subject.RefreshEpisodeInfo(GetSeries(), GetEpisodes());
|
Subject.RefreshEpisodeInfo(GetSeries(), GetEpisodes());
|
||||||
|
|
||||||
_insertedEpisodes.All(e => e.AbsoluteEpisodeNumber == 0 || !e.AbsoluteEpisodeNumber.HasValue).Should().BeTrue();
|
_insertedEpisodes.All(e => !e.AbsoluteEpisodeNumber.HasValue).Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -197,7 +197,7 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
|
|
||||||
Subject.RefreshEpisodeInfo(GetAnimeSeries(), episodes);
|
Subject.RefreshEpisodeInfo(GetAnimeSeries(), episodes);
|
||||||
|
|
||||||
_insertedEpisodes.All(e => e.AbsoluteEpisodeNumber > 0).Should().BeTrue();
|
_insertedEpisodes.All(e => e.AbsoluteEpisodeNumber.HasValue).Should().BeTrue();
|
||||||
_updatedEpisodes.Should().BeEmpty();
|
_updatedEpisodes.Should().BeEmpty();
|
||||||
_deletedEpisodes.Should().BeEmpty();
|
_deletedEpisodes.Should().BeEmpty();
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
GivenAnimeEpisodes(episodes);
|
GivenAnimeEpisodes(episodes);
|
||||||
|
|
||||||
var existingEpisodes = episodes.JsonClone();
|
var existingEpisodes = episodes.JsonClone();
|
||||||
existingEpisodes.ForEach(e => e.AbsoluteEpisodeNumber = 0);
|
existingEpisodes.ForEach(e => e.AbsoluteEpisodeNumber = null);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodeBySeries(It.IsAny<Int32>()))
|
Mocker.GetMock<IEpisodeService>().Setup(c => c.GetEpisodeBySeries(It.IsAny<Int32>()))
|
||||||
.Returns(existingEpisodes);
|
.Returns(existingEpisodes);
|
||||||
|
@ -217,7 +217,7 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
Subject.RefreshEpisodeInfo(GetAnimeSeries(), episodes);
|
Subject.RefreshEpisodeInfo(GetAnimeSeries(), episodes);
|
||||||
|
|
||||||
_insertedEpisodes.Should().BeEmpty();
|
_insertedEpisodes.Should().BeEmpty();
|
||||||
_updatedEpisodes.All(e => e.AbsoluteEpisodeNumber > 0).Should().BeTrue();
|
_updatedEpisodes.All(e => e.AbsoluteEpisodeNumber.HasValue).Should().BeTrue();
|
||||||
_deletedEpisodes.Should().BeEmpty();
|
_deletedEpisodes.Should().BeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,10 +261,9 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
episodes[0].AbsoluteEpisodeNumber = 0;
|
episodes[0].AbsoluteEpisodeNumber = null;
|
||||||
episodes[0].SeasonNumber.Should().NotBe(episodes[1].SeasonNumber);
|
episodes[0].SeasonNumber.Should().NotBe(episodes[1].SeasonNumber);
|
||||||
episodes[0].EpisodeNumber.Should().NotBe(episodes[1].EpisodeNumber);
|
episodes[0].EpisodeNumber.Should().NotBe(episodes[1].EpisodeNumber);
|
||||||
episodes[0].AbsoluteEpisodeNumber.Should().NotBe(episodes[1].AbsoluteEpisodeNumber);
|
|
||||||
|
|
||||||
GivenAnimeEpisodes(episodes);
|
GivenAnimeEpisodes(episodes);
|
||||||
|
|
||||||
|
@ -286,17 +285,17 @@ namespace NzbDrone.Core.Test.TvTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_ignore_episodes_with_absolute_episode_of_zero_in_distinct_by_absolute()
|
public void should_ignore_episodes_with_no_absolute_episode_in_distinct_by_absolute()
|
||||||
{
|
{
|
||||||
var episodes = Builder<Episode>.CreateListOfSize(10)
|
var episodes = Builder<Episode>.CreateListOfSize(10)
|
||||||
.Build()
|
.Build()
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
episodes[0].AbsoluteEpisodeNumber = 0;
|
episodes[0].AbsoluteEpisodeNumber = null;
|
||||||
episodes[1].AbsoluteEpisodeNumber = 0;
|
episodes[1].AbsoluteEpisodeNumber = null;
|
||||||
episodes[2].AbsoluteEpisodeNumber = 0;
|
episodes[2].AbsoluteEpisodeNumber = null;
|
||||||
episodes[3].AbsoluteEpisodeNumber = 0;
|
episodes[3].AbsoluteEpisodeNumber = null;
|
||||||
episodes[4].AbsoluteEpisodeNumber = 0;
|
episodes[4].AbsoluteEpisodeNumber = null;
|
||||||
|
|
||||||
GivenAnimeEpisodes(episodes);
|
GivenAnimeEpisodes(episodes);
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,9 @@ namespace NzbDrone.Core.DataAugmentation.Xem
|
||||||
|
|
||||||
foreach (var episode in episodes)
|
foreach (var episode in episodes)
|
||||||
{
|
{
|
||||||
episode.SceneAbsoluteEpisodeNumber = 0;
|
episode.SceneAbsoluteEpisodeNumber = null;
|
||||||
episode.SceneSeasonNumber = 0;
|
episode.SceneSeasonNumber = null;
|
||||||
episode.SceneEpisodeNumber = 0;
|
episode.SceneEpisodeNumber = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var mapping in mappings)
|
foreach (var mapping in mappings)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(65)]
|
||||||
|
public class make_scene_numbering_nullable : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Execute.Sql("UPDATE Episodes SET AbsoluteEpisodeNumber = NULL WHERE AbsoluteEpisodeNumber = 0");
|
||||||
|
Execute.Sql("UPDATE Episodes SET SceneAbsoluteEpisodeNumber = NULL WHERE SceneAbsoluteEpisodeNumber = 0");
|
||||||
|
Execute.Sql("UPDATE Episodes SET SceneSeasonNumber = NULL, SceneEpisodeNumber = NULL WHERE SceneSeasonNumber = 0 AND SceneEpisodeNumber = 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -139,32 +139,24 @@ namespace NzbDrone.Core.Download
|
||||||
var downloadClientHistory = downloadClient.GetItems().ToList();
|
var downloadClientHistory = downloadClient.GetItems().ToList();
|
||||||
foreach (var downloadItem in downloadClientHistory)
|
foreach (var downloadItem in downloadClientHistory)
|
||||||
{
|
{
|
||||||
try
|
var trackingId = String.Format("{0}-{1}", downloadClient.Definition.Id, downloadItem.DownloadClientId);
|
||||||
|
TrackedDownload trackedDownload;
|
||||||
|
|
||||||
|
if (newTrackedDownloads.ContainsKey(trackingId)) continue;
|
||||||
|
|
||||||
|
if (!oldTrackedDownloads.TryGetValue(trackingId, out trackedDownload))
|
||||||
{
|
{
|
||||||
var trackingId = String.Format("{0}-{1}", downloadClient.Definition.Id, downloadItem.DownloadClientId);
|
trackedDownload = GetTrackedDownload(trackingId, downloadClient.Definition.Id, downloadItem, grabbedHistory);
|
||||||
TrackedDownload trackedDownload;
|
|
||||||
|
|
||||||
if (newTrackedDownloads.ContainsKey(trackingId)) continue;
|
if (trackedDownload == null) continue;
|
||||||
|
|
||||||
if (!oldTrackedDownloads.TryGetValue(trackingId, out trackedDownload))
|
_logger.Debug("[{0}] Started tracking download with id {1}.", downloadItem.Title, trackingId);
|
||||||
{
|
stateChanged = true;
|
||||||
trackedDownload = GetTrackedDownload(trackingId, downloadClient.Definition.Id, downloadItem,
|
|
||||||
grabbedHistory);
|
|
||||||
|
|
||||||
if (trackedDownload == null) continue;
|
|
||||||
|
|
||||||
_logger.Debug("[{0}] Started tracking download with id {1}.", downloadItem.Title, trackingId);
|
|
||||||
stateChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
trackedDownload.DownloadItem = downloadItem;
|
|
||||||
|
|
||||||
newTrackedDownloads[trackingId] = trackedDownload;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.ErrorException("An error occured while tracking download." + downloadItem.Title, e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trackedDownload.DownloadItem = downloadItem;
|
||||||
|
|
||||||
|
newTrackedDownloads[trackingId] = trackedDownload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,34 +235,42 @@ namespace NzbDrone.Core.Download
|
||||||
Status = TrackedDownloadStatus.Ok,
|
Status = TrackedDownloadStatus.Ok,
|
||||||
};
|
};
|
||||||
|
|
||||||
var historyItems = grabbedHistory.Where(h =>
|
|
||||||
{
|
|
||||||
var downloadClientId = h.Data.GetValueOrDefault(DOWNLOAD_CLIENT_ID);
|
|
||||||
|
|
||||||
if (downloadClientId == null) return false;
|
try
|
||||||
|
|
||||||
return downloadClientId.Equals(trackedDownload.DownloadItem.DownloadClientId);
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
|
|
||||||
if (parsedEpisodeInfo == null) return null;
|
|
||||||
|
|
||||||
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
|
||||||
|
|
||||||
if (remoteEpisode.Series == null)
|
|
||||||
{
|
{
|
||||||
if (historyItems.Empty()) return null;
|
var historyItems = grabbedHistory.Where(h =>
|
||||||
|
{
|
||||||
|
var downloadClientId = h.Data.GetValueOrDefault(DOWNLOAD_CLIENT_ID);
|
||||||
|
|
||||||
trackedDownload.Status = TrackedDownloadStatus.Warning;
|
if (downloadClientId == null) return false;
|
||||||
trackedDownload.StatusMessages.Add(new TrackedDownloadStatusMessage(
|
|
||||||
trackedDownload.DownloadItem.Title,
|
|
||||||
"Series title mismatch, automatic import is not possible")
|
|
||||||
);
|
|
||||||
|
|
||||||
remoteEpisode = _parsingService.Map(parsedEpisodeInfo, historyItems.First().SeriesId, historyItems.Select(h => h.EpisodeId));
|
return downloadClientId.Equals(trackedDownload.DownloadItem.DownloadClientId);
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
|
var parsedEpisodeInfo = Parser.Parser.ParseTitle(trackedDownload.DownloadItem.Title);
|
||||||
|
if (parsedEpisodeInfo == null) return null;
|
||||||
|
|
||||||
|
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0);
|
||||||
|
if (remoteEpisode.Series == null)
|
||||||
|
{
|
||||||
|
if (historyItems.Empty()) return null;
|
||||||
|
|
||||||
|
trackedDownload.Status = TrackedDownloadStatus.Warning;
|
||||||
|
trackedDownload.StatusMessages.Add(new TrackedDownloadStatusMessage(
|
||||||
|
trackedDownload.DownloadItem.Title,
|
||||||
|
"Series title mismatch, automatic import is not possible")
|
||||||
|
);
|
||||||
|
|
||||||
|
remoteEpisode = _parsingService.Map(parsedEpisodeInfo, historyItems.First().SeriesId, historyItems.Select(h => h.EpisodeId));
|
||||||
|
}
|
||||||
|
|
||||||
|
trackedDownload.RemoteEpisode = remoteEpisode;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.DebugException("Failed to find episode for " + downloadItem.Title, e);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
trackedDownload.RemoteEpisode = remoteEpisode;
|
|
||||||
|
|
||||||
return trackedDownload;
|
return trackedDownload;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace NzbDrone.Core.Download
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (FailedDownloadForRecentRelease(downloadClient, trackedDownload, grabbedItems))
|
if (FailedDownloadForRecentRelease(downloadClient, trackedDownload, grabbedItems))
|
||||||
{
|
{
|
||||||
_logger.Debug("[{0}] Recent release Failed, do not blacklist.", trackedDownload.DownloadItem.Title);
|
_logger.Debug("[{0}] Recent release Failed, do not blacklist.", trackedDownload.DownloadItem.Title);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -102,13 +102,14 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
var sceneSeasonGroups = episodes.GroupBy(v =>
|
var sceneSeasonGroups = episodes.GroupBy(v =>
|
||||||
{
|
{
|
||||||
if (v.SceneSeasonNumber == 0 && v.SceneEpisodeNumber == 0)
|
if (v.SceneSeasonNumber.HasValue && v.SceneEpisodeNumber.HasValue)
|
||||||
|
{
|
||||||
|
return v.SceneSeasonNumber.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return v.SeasonNumber;
|
return v.SeasonNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.SceneSeasonNumber;
|
|
||||||
|
|
||||||
}).Distinct();
|
}).Distinct();
|
||||||
|
|
||||||
foreach (var sceneSeasonEpisodes in sceneSeasonGroups)
|
foreach (var sceneSeasonEpisodes in sceneSeasonGroups)
|
||||||
|
@ -118,10 +119,10 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
var episode = sceneSeasonEpisodes.First();
|
var episode = sceneSeasonEpisodes.First();
|
||||||
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, sceneSeasonEpisodes.ToList());
|
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, sceneSeasonEpisodes.ToList());
|
||||||
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
||||||
if (episode.SceneSeasonNumber == 0 && episode.SceneEpisodeNumber == 0)
|
if (episode.SceneSeasonNumber.HasValue && episode.SceneEpisodeNumber.HasValue)
|
||||||
searchSpec.EpisodeNumber = episode.EpisodeNumber;
|
searchSpec.EpisodeNumber = episode.SceneEpisodeNumber.Value;
|
||||||
else
|
else
|
||||||
searchSpec.EpisodeNumber = episode.SceneEpisodeNumber;
|
searchSpec.EpisodeNumber = episode.EpisodeNumber;
|
||||||
|
|
||||||
var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
var decisions = Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
downloadDecisions.AddRange(decisions);
|
downloadDecisions.AddRange(decisions);
|
||||||
|
@ -152,19 +153,10 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
{
|
{
|
||||||
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, new List<Episode>{episode});
|
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, new List<Episode>{episode});
|
||||||
|
|
||||||
if (series.UseSceneNumbering)
|
if (series.UseSceneNumbering && episode.SceneSeasonNumber.HasValue && episode.SceneEpisodeNumber.HasValue)
|
||||||
{
|
{
|
||||||
if (episode.SceneSeasonNumber > 0 && episode.SceneEpisodeNumber > 0)
|
searchSpec.EpisodeNumber = episode.SceneEpisodeNumber.Value;
|
||||||
{
|
searchSpec.SeasonNumber = episode.SceneSeasonNumber.Value;
|
||||||
searchSpec.EpisodeNumber = episode.SceneEpisodeNumber;
|
|
||||||
searchSpec.SeasonNumber = episode.SceneSeasonNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
searchSpec.EpisodeNumber = episode.EpisodeNumber;
|
|
||||||
searchSpec.SeasonNumber = episode.SeasonNumber;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -187,16 +179,18 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
private List<DownloadDecision> SearchAnime(Series series, Episode episode)
|
private List<DownloadDecision> SearchAnime(Series series, Episode episode)
|
||||||
{
|
{
|
||||||
var searchSpec = Get<AnimeEpisodeSearchCriteria>(series, new List<Episode> { episode });
|
var searchSpec = Get<AnimeEpisodeSearchCriteria>(series, new List<Episode> { episode });
|
||||||
searchSpec.AbsoluteEpisodeNumber = episode.SceneAbsoluteEpisodeNumber.GetValueOrDefault(0);
|
|
||||||
|
|
||||||
if (searchSpec.AbsoluteEpisodeNumber == 0)
|
if (episode.SceneAbsoluteEpisodeNumber.HasValue)
|
||||||
{
|
{
|
||||||
searchSpec.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber.GetValueOrDefault(0);
|
searchSpec.AbsoluteEpisodeNumber = episode.SceneAbsoluteEpisodeNumber.Value;
|
||||||
}
|
}
|
||||||
|
else if (episode.AbsoluteEpisodeNumber.HasValue)
|
||||||
if (searchSpec.AbsoluteEpisodeNumber == 0)
|
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException("AbsoluteEpisodeNumber", "Can not search for an episode absolute episode number of zero");
|
searchSpec.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("AbsoluteEpisodeNumber", "Can not search for an episode without an absolute episode number");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
return Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec);
|
||||||
|
@ -232,7 +226,7 @@ namespace NzbDrone.Core.IndexerSearch
|
||||||
spec.Series = series;
|
spec.Series = series;
|
||||||
spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
|
spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
|
||||||
episodes.Select(e => e.SeasonNumber)
|
episodes.Select(e => e.SeasonNumber)
|
||||||
.Concat(episodes.Select(e => e.SceneSeasonNumber)
|
.Concat(episodes.Select(e => e.SceneSeasonNumber.Value)
|
||||||
.Distinct()));
|
.Distinct()));
|
||||||
|
|
||||||
spec.Episodes = episodes;
|
spec.Episodes = episodes;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.Indexers;
|
using NzbDrone.Core.Indexers;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -39,7 +40,11 @@ namespace NzbDrone.Core.MetadataSource.Tvdb
|
||||||
var episode = new Episode();
|
var episode = new Episode();
|
||||||
episode.SeasonNumber = item.TryGetValue("SeasonNumber", 0);
|
episode.SeasonNumber = item.TryGetValue("SeasonNumber", 0);
|
||||||
episode.EpisodeNumber = item.TryGetValue("EpisodeNumber", 0);
|
episode.EpisodeNumber = item.TryGetValue("EpisodeNumber", 0);
|
||||||
episode.AbsoluteEpisodeNumber = item.TryGetValue("absolute_number", 0);
|
|
||||||
|
if (item.TryGetValue("absolute_number").IsNotNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
episode.AbsoluteEpisodeNumber = item.TryGetValue("absolute_number", 0);
|
||||||
|
}
|
||||||
|
|
||||||
return episode;
|
return episode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,7 @@
|
||||||
<Compile Include="Datastore\Migration\061_clear_bad_scene_names.cs" />
|
<Compile Include="Datastore\Migration\061_clear_bad_scene_names.cs" />
|
||||||
<Compile Include="Datastore\Migration\060_remove_enable_from_indexers.cs" />
|
<Compile Include="Datastore\Migration\060_remove_enable_from_indexers.cs" />
|
||||||
<Compile Include="Datastore\Migration\062_convert_quality_models.cs" />
|
<Compile Include="Datastore\Migration\062_convert_quality_models.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\065_make_scene_numbering_nullable.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
|
||||||
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace NzbDrone.Core.Organizer
|
||||||
pattern = namingConfig.DailyEpisodeFormat;
|
pattern = namingConfig.DailyEpisodeFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (series.SeriesType == SeriesTypes.Anime && episodes.All(e => e.AbsoluteEpisodeNumber > 0))
|
if (series.SeriesType == SeriesTypes.Anime && episodes.All(e => e.AbsoluteEpisodeNumber.HasValue))
|
||||||
{
|
{
|
||||||
pattern = namingConfig.AnimeEpisodeFormat;
|
pattern = namingConfig.AnimeEpisodeFormat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ namespace NzbDrone.Core.Tv
|
||||||
public Boolean Monitored { get; set; }
|
public Boolean Monitored { get; set; }
|
||||||
public Nullable<Int32> AbsoluteEpisodeNumber { get; set; }
|
public Nullable<Int32> AbsoluteEpisodeNumber { get; set; }
|
||||||
public Nullable<Int32> SceneAbsoluteEpisodeNumber { get; set; }
|
public Nullable<Int32> SceneAbsoluteEpisodeNumber { get; set; }
|
||||||
public int SceneSeasonNumber { get; set; }
|
public Nullable<Int32> SceneSeasonNumber { get; set; }
|
||||||
public int SceneEpisodeNumber { get; set; }
|
public Nullable<Int32> SceneEpisodeNumber { get; set; }
|
||||||
public Ratings Ratings { get; set; }
|
public Ratings Ratings { get; set; }
|
||||||
public List<MediaCover.MediaCover> Images { get; set; }
|
public List<MediaCover.MediaCover> Images { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -183,10 +183,10 @@ namespace NzbDrone.Core.Tv
|
||||||
episode.AbsoluteEpisodeNumber = tvdbEpisode.AbsoluteEpisodeNumber;
|
episode.AbsoluteEpisodeNumber = tvdbEpisode.AbsoluteEpisodeNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Return all episodes with abs 0, but distinct by abs for ones greater than 0
|
//Return all episodes with no abs number, but distinct for those with abs number
|
||||||
return traktEpisodes.Where(e => e.AbsoluteEpisodeNumber > 0)
|
return traktEpisodes.Where(e => e.AbsoluteEpisodeNumber.HasValue)
|
||||||
.DistinctBy(e => e.AbsoluteEpisodeNumber)
|
.DistinctBy(e => e.AbsoluteEpisodeNumber.Value)
|
||||||
.Concat(traktEpisodes.Where(e => e.AbsoluteEpisodeNumber == 0))
|
.Concat(traktEpisodes.Where(e => !e.AbsoluteEpisodeNumber.HasValue))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
if (series.SeriesType == SeriesTypes.Anime)
|
if (series.SeriesType == SeriesTypes.Anime)
|
||||||
{
|
{
|
||||||
if (episode.AbsoluteEpisodeNumber > 0)
|
if (episode.AbsoluteEpisodeNumber.HasValue)
|
||||||
{
|
{
|
||||||
var matchingEpisode = existingEpisodes.FirstOrDefault(e => e.AbsoluteEpisodeNumber == episode.AbsoluteEpisodeNumber);
|
var matchingEpisode = existingEpisodes.FirstOrDefault(e => e.AbsoluteEpisodeNumber == episode.AbsoluteEpisodeNumber);
|
||||||
|
|
||||||
|
@ -209,10 +209,10 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
if (series.SeriesType == SeriesTypes.Anime)
|
if (series.SeriesType == SeriesTypes.Anime)
|
||||||
{
|
{
|
||||||
var withAbs = episodes.Where(e => e.AbsoluteEpisodeNumber > 0)
|
var withAbs = episodes.Where(e => e.AbsoluteEpisodeNumber.HasValue)
|
||||||
.OrderBy(e => e.AbsoluteEpisodeNumber);
|
.OrderBy(e => e.AbsoluteEpisodeNumber);
|
||||||
|
|
||||||
var withoutAbs = episodes.Where(e => e.AbsoluteEpisodeNumber == 0)
|
var withoutAbs = episodes.Where(e => !e.AbsoluteEpisodeNumber.HasValue)
|
||||||
.OrderBy(e => e.SeasonNumber)
|
.OrderBy(e => e.SeasonNumber)
|
||||||
.ThenBy(e => e.EpisodeNumber);
|
.ThenBy(e => e.EpisodeNumber);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ define(
|
||||||
episodes = this.cellValue.get(episodeField);
|
episodes = this.cellValue.get(episodeField);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!absoluteEpisodeNumber) {
|
if (absoluteEpisodeNumber === undefined) {
|
||||||
absoluteEpisodeNumber = this.cellValue.get(absoluteEpisodeField);
|
absoluteEpisodeNumber = this.cellValue.get(absoluteEpisodeField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ define(
|
||||||
|
|
||||||
result = '{0}x{1}'.format(seasonNumber, paddedEpisodes);
|
result = '{0}x{1}'.format(seasonNumber, paddedEpisodes);
|
||||||
|
|
||||||
if (absoluteEpisodeNumber > 0 && paddedAbsoluteEpisode) {
|
if (absoluteEpisodeNumber !== undefined && paddedAbsoluteEpisode) {
|
||||||
result += ' ({0})'.format(paddedAbsoluteEpisode);
|
result += ' ({0})'.format(paddedAbsoluteEpisode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ define(
|
||||||
return moment(this.airDate).format('L');
|
return moment(this.airDate).format('L');
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (this.series.seriesType === 'anime' && this.absoluteEpisodeNumber > 0) {
|
else if (this.series.seriesType === 'anime' && this.absoluteEpisodeNumber !== undefined) {
|
||||||
return '{0}x{1} ({2})'.format(this.seasonNumber, FormatHelpers.pad(this.episodeNumber, 2), FormatHelpers.pad(this.absoluteEpisodeNumber, 2));
|
return '{0}x{1} ({2})'.format(this.seasonNumber, FormatHelpers.pad(this.episodeNumber, 2), FormatHelpers.pad(this.absoluteEpisodeNumber, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ define(
|
||||||
|
|
||||||
if (this.model.get('sceneSeasonNumber') > 0 ||
|
if (this.model.get('sceneSeasonNumber') > 0 ||
|
||||||
this.model.get('sceneEpisodeNumber') > 0 ||
|
this.model.get('sceneEpisodeNumber') > 0 ||
|
||||||
(this.model.has('sceneAbsoluteEpisodeNumber') && this.model.get('sceneAbsoluteEpisodeNumber') > 0) ||
|
this.model.has('sceneAbsoluteEpisodeNumber') ||
|
||||||
alternateTitles.length > 0)
|
alternateTitles.length > 0)
|
||||||
{
|
{
|
||||||
this.templateFunction = Marionette.TemplateCache.get(this.template);
|
this.templateFunction = Marionette.TemplateCache.get(this.template);
|
||||||
|
|
|
@ -15,7 +15,7 @@ define(
|
||||||
|
|
||||||
if (SeriesCollection.get(this.model.get('seriesId')).get('seriesType') === 'anime') {
|
if (SeriesCollection.get(this.model.get('seriesId')).get('seriesType') === 'anime') {
|
||||||
|
|
||||||
if (this.model.get('seasonNumber') > 0 && this.model.get('absoluteEpisodeNumber') === 0) {
|
if (this.model.get('seasonNumber') > 0 && !this.model.has('absoluteEpisodeNumber')) {
|
||||||
this.$el.html('<i class="icon-nd-form-warning" title="Episode does not have an absolute episode number"></i>');
|
this.$el.html('<i class="icon-nd-form-warning" title="Episode does not have an absolute episode number"></i>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue