Treat XEM aliases as SceneSeasonNumber

Fixed: Aliases used incorrectly when TVDB season number matched the seaon number of the alias
Closes #1140
This commit is contained in:
Mark McDowall 2016-02-11 21:00:25 -08:00
parent 44e09e2220
commit 942be364dc
16 changed files with 80 additions and 32 deletions

View File

@ -6,5 +6,6 @@ namespace NzbDrone.Api.Series
{
public string Title { get; set; }
public int SeasonNumber { get; set; }
public int SceneSeasonNumber { get; set; }
}
}

View File

@ -187,16 +187,15 @@ namespace NzbDrone.Core.Test.DataAugmentation.Scene
{
var mappings = new List<SceneMapping>
{
new SceneMapping { Title = "Working!!", ParseTerm = "working", SearchTerm = "Working!!", TvdbId = 100, SeasonNumber = -1 },
new SceneMapping { Title = "Working!!", ParseTerm = "working", SearchTerm = "Working!!", TvdbId = 100, SeasonNumber = 1 },
new SceneMapping { Title = "Working`!!", ParseTerm = "working", SearchTerm = "Working`!!", TvdbId = 100, SeasonNumber = 2 },
new SceneMapping { Title = "Working!!!", ParseTerm = "working", SearchTerm = "Working!!!", TvdbId = 100, SeasonNumber = 3 },
new SceneMapping { Title = "Working!!", ParseTerm = "working", SearchTerm = "Working!!", TvdbId = 100, SceneSeasonNumber = 1 },
new SceneMapping { Title = "Working`!!", ParseTerm = "working", SearchTerm = "Working`!!", TvdbId = 100, SceneSeasonNumber = 2 },
new SceneMapping { Title = "Working!!!", ParseTerm = "working", SearchTerm = "Working!!!", TvdbId = 100, SceneSeasonNumber = 3 },
};
Mocker.GetMock<ISceneMappingRepository>().Setup(c => c.All()).Returns(mappings);
var tvdbId = Subject.FindTvdbId(parseTitle);
var seasonNumber = Subject.GetSeasonNumber(parseTitle);
var seasonNumber = Subject.GetSceneSeasonNumber(parseTitle);
tvdbId.Should().Be(100);
seasonNumber.Should().Be(expectedSeasonNumber);
@ -217,7 +216,7 @@ namespace NzbDrone.Core.Test.DataAugmentation.Scene
foreach (var sceneMapping in _fakeMappings)
{
Subject.GetSceneNames(sceneMapping.TvdbId, _fakeMappings.Select(m => m.SeasonNumber)).Should().Contain(sceneMapping.SearchTerm);
Subject.GetSceneNamesBySeasonNumbers(sceneMapping.TvdbId, _fakeMappings.Select(m => m.SeasonNumber.Value)).Should().Contain(sceneMapping.SearchTerm);
Subject.FindTvdbId(sceneMapping.ParseTerm).Should().Be(sceneMapping.TvdbId);
}
}

View File

@ -52,7 +52,11 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
.Returns<int, int>((i, j) => _xemEpisodes.Where(d => d.SeasonNumber == j).ToList());
Mocker.GetMock<ISceneMappingService>()
.Setup(s => s.GetSceneNames(It.IsAny<int>(), It.IsAny<IEnumerable<int>>()))
.Setup(s => s.GetSceneNamesBySeasonNumbers(It.IsAny<int>(), It.IsAny<IEnumerable<int>>()))
.Returns(new List<string>());
Mocker.GetMock<ISceneMappingService>()
.Setup(s => s.GetSceneNamesBySceneSeasonNumbers(It.IsAny<int>(), It.IsAny<IEnumerable<int>>()))
.Returns(new List<string>());
}

View File

@ -210,7 +210,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenAbsoluteNumberingSeries();
Mocker.GetMock<ISceneMappingService>()
.Setup(s => s.GetSeasonNumber(_parsedEpisodeInfo.SeriesTitle))
.Setup(s => s.GetSceneSeasonNumber(_parsedEpisodeInfo.SeriesTitle))
.Returns(seasonNumber);
Mocker.GetMock<IEpisodeService>()
@ -234,7 +234,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenAbsoluteNumberingSeries();
Mocker.GetMock<ISceneMappingService>()
.Setup(s => s.GetSeasonNumber(_parsedEpisodeInfo.SeriesTitle))
.Setup(s => s.GetSceneSeasonNumber(_parsedEpisodeInfo.SeriesTitle))
.Returns(seasonNumber);
Mocker.GetMock<IEpisodeService>()
@ -258,7 +258,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
GivenAbsoluteNumberingSeries();
Mocker.GetMock<ISceneMappingService>()
.Setup(s => s.GetSeasonNumber(_parsedEpisodeInfo.SeriesTitle))
.Setup(s => s.GetSceneSeasonNumber(_parsedEpisodeInfo.SeriesTitle))
.Returns(seasonNumber);
Mocker.GetMock<IEpisodeService>()

View File

@ -6,7 +6,6 @@ namespace NzbDrone.Core.DataAugmentation.Scene
public class SceneMapping : ModelBase
{
public string Title { get; set; }
public string ParseTerm { get; set; }
[JsonProperty("searchTitle")]
@ -15,8 +14,9 @@ namespace NzbDrone.Core.DataAugmentation.Scene
public int TvdbId { get; set; }
[JsonProperty("season")]
public int SeasonNumber { get; set; }
public int? SeasonNumber { get; set; }
public int? SceneSeasonNumber { get; set; }
public string Type { get; set; }
}
}

View File

@ -14,10 +14,11 @@ namespace NzbDrone.Core.DataAugmentation.Scene
{
public interface ISceneMappingService
{
List<string> GetSceneNames(int tvdbId, IEnumerable<int> seasonNumbers);
List<string> GetSceneNamesBySeasonNumbers(int tvdbId, IEnumerable<int> seasonNumbers);
List<string> GetSceneNamesBySceneSeasonNumbers(int tvdbId, IEnumerable<int> sceneSeasonNumbers);
int? FindTvdbId(string title);
List<SceneMapping> FindByTvdbId(int tvdbId);
int? GetSeasonNumber(string title);
int? GetSceneSeasonNumber(string title);
}
public class SceneMappingService : ISceneMappingService,
@ -46,7 +47,7 @@ namespace NzbDrone.Core.DataAugmentation.Scene
_findByTvdbIdCache = cacheManager.GetCacheDictionary<List<SceneMapping>>(GetType(), "find_tvdb_id");
}
public List<string> GetSceneNames(int tvdbId, IEnumerable<int> seasonNumbers)
public List<string> GetSceneNamesBySeasonNumbers(int tvdbId, IEnumerable<int> seasonNumbers)
{
var names = _findByTvdbIdCache.Find(tvdbId.ToString());
@ -55,11 +56,25 @@ namespace NzbDrone.Core.DataAugmentation.Scene
return new List<string>();
}
return FilterNonEnglish(names.Where(s => seasonNumbers.Contains(s.SeasonNumber) ||
return FilterNonEnglish(names.Where(s => s.SeasonNumber.HasValue && seasonNumbers.Contains(s.SeasonNumber.Value) ||
s.SeasonNumber == -1)
.Select(m => m.SearchTerm).Distinct().ToList());
}
public List<string> GetSceneNamesBySceneSeasonNumbers(int tvdbId, IEnumerable<int> sceneSeasonNumbers)
{
var names = _findByTvdbIdCache.Find(tvdbId.ToString());
if (names == null)
{
return new List<string>();
}
return FilterNonEnglish(names.Where(s => s.SceneSeasonNumber.HasValue && sceneSeasonNumbers.Contains(s.SceneSeasonNumber.Value) ||
s.SceneSeasonNumber == -1)
.Select(m => m.SearchTerm).Distinct().ToList());
}
public int? FindTvdbId(string title)
{
var mapping = FindMapping(title);
@ -87,14 +102,16 @@ namespace NzbDrone.Core.DataAugmentation.Scene
return mappings;
}
public int? GetSeasonNumber(string title)
public int? GetSceneSeasonNumber(string title)
{
var mapping = FindMapping(title);
if (mapping == null)
{
return null;
}
return mapping.SeasonNumber;
return mapping.SceneSeasonNumber;
}
private void UpdateMappings()

View File

@ -106,7 +106,7 @@ namespace NzbDrone.Core.DataAugmentation.Xem
{
Title = n.Key,
SearchTerm = n.Key,
SeasonNumber = seasonNumber,
SceneSeasonNumber = seasonNumber,
TvdbId = series.Key
});
}

View File

@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(100)]
public class add_scene_season_number : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("SceneMappings").AlterColumn("SeasonNumber").AsInt32().Nullable();
Alter.Table("SceneMappings").AddColumn("SceneSeasonNumber").AsInt32().Nullable();
}
}
}

View File

@ -2,17 +2,14 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Download;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Queue;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.IndexerSearch
{

View File

@ -233,10 +233,12 @@ namespace NzbDrone.Core.IndexerSearch
var spec = new TSpec();
spec.Series = series;
spec.SceneTitles = _sceneMapping.GetSceneNames(series.TvdbId,
episodes.Select(e => e.SeasonNumber)
.Concat(episodes.Where(v => v.SceneSeasonNumber.HasValue).Select(e => e.SceneSeasonNumber.Value)
.Distinct()));
spec.SceneTitles = _sceneMapping.GetSceneNamesBySeasonNumbers(series.TvdbId, episodes.Select(e => e.SeasonNumber))
.Concat(_sceneMapping.GetSceneNamesBySceneSeasonNumbers(series.TvdbId,
episodes.Where(v => v.SceneSeasonNumber.HasValue)
.Select(e => e.SceneSeasonNumber.Value)))
.Distinct()
.ToList();
spec.Episodes = episodes;

View File

@ -274,6 +274,7 @@
<Compile Include="Datastore\Migration\091_added_indexerstatus.cs" />
<Compile Include="Datastore\Migration\093_naming_config_replace_characters.cs" />
<Compile Include="Datastore\Migration\092_add_unverifiedscenenumbering.cs" />
<Compile Include="Datastore\Migration\100_add_scene_season_number.cs" />
<Compile Include="Datastore\Migration\094_add_tvmazeid.cs" />
<Compile Include="Datastore\Migration\098_remove_titans_of_tv.cs">
<SubType>Code</SubType>

View File

@ -168,7 +168,7 @@ namespace NzbDrone.Core.Parser
if (parsedEpisodeInfo.IsAbsoluteNumbering)
{
var sceneSeasonNumber = _sceneMappingService.GetSeasonNumber(parsedEpisodeInfo.SeriesTitle);
var sceneSeasonNumber = _sceneMappingService.GetSceneSeasonNumber(parsedEpisodeInfo.SeriesTitle);
foreach (var absoluteEpisodeNumber in parsedEpisodeInfo.AbsoluteEpisodeNumbers)
{
@ -195,8 +195,7 @@ namespace NzbDrone.Core.Parser
if (episode == null)
{
episode = _episodeService.FindEpisode(series.Id, sceneSeasonNumber.Value,
absoluteEpisodeNumber);
episode = _episodeService.FindEpisode(series.Id, sceneSeasonNumber.Value, absoluteEpisodeNumber);
}
}

View File

@ -22,7 +22,7 @@ module.exports = NzbDroneCell.extend({
if (reqres.hasHandler(reqres.Requests.GetAlternateNameBySeasonNumber)) {
if (this.model.get('sceneSeasonNumber') > 0) {
alternateTitles = reqres.request(reqres.Requests.GetAlternateNameBySeasonNumber, this.model.get('seriesId'), this.model.get('sceneSeasonNumber'));
alternateTitles = reqres.request(reqres.Requests.GetAlternateNameBySceneSeasonNumber, this.model.get('seriesId'), this.model.get('sceneSeasonNumber'));
}
if (alternateTitles.length === 0) {

View File

@ -55,6 +55,10 @@
{{#if_eq seasonNumber compare="-1"}}
<span class="label label-default">{{title}}</span>
{{/if_eq}}
{{#if_eq sceneSeasonNumber compare="-1"}}
<span class="label label-default">{{title}}</span>
{{/if_eq}}
{{/each}}
</div>
</div>

View File

@ -182,6 +182,14 @@ module.exports = Marionette.Layout.extend({
return _.where(self.model.get('alternateTitles'), { seasonNumber : seasonNumber });
});
reqres.setHandler(reqres.Requests.GetAlternateNameBySceneSeasonNumber, function(seriesId, sceneSeasonNumber) {
if (self.model.get('id') !== seriesId) {
return [];
}
return _.where(self.model.get('alternateTitles'), { sceneSeasonNumber : sceneSeasonNumber });
});
$.when(this.episodeCollection.fetch(), this.episodeFileCollection.fetch()).done(function() {
var seasonCollectionView = new SeasonCollectionView({
collection : self.seasonCollection,

View File

@ -3,8 +3,9 @@ var Wreqr = require('./JsLibraries/backbone.wreqr');
var reqres = new Wreqr.RequestResponse();
reqres.Requests = {
GetEpisodeFileById : 'GetEpisodeFileById',
GetAlternateNameBySeasonNumber : 'GetAlternateNameBySeasonNumber'
GetEpisodeFileById : 'GetEpisodeFileById',
GetAlternateNameBySeasonNumber : 'GetAlternateNameBySeasonNumber',
GetAlternateNameBySceneSeasonNumber : 'GetAlternateNameBySceneSeasonNumber'
};
module.exports = reqres;