1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-11-05 02:22:31 +01:00

cleaned up the mindfuck that was scene mapping.

This commit is contained in:
kay.one 2013-06-08 12:14:52 -07:00
parent 074d7f2df5
commit efa9cf6380
12 changed files with 119 additions and 68 deletions

View File

@ -34,8 +34,8 @@ public void fetch_should_return_list_of_mappings()
mappings.Should().NotBeEmpty(); mappings.Should().NotBeEmpty();
mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.CleanTitle)); mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.SearchTerm));
mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.SceneName)); mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.ParseTerm));
mappings.Should().NotContain(c => c.TvdbId == 0); mappings.Should().NotContain(c => c.TvdbId == 0);
} }

View File

@ -6,12 +6,13 @@
using NzbDrone.Core.DataAugmentation.Scene; using NzbDrone.Core.DataAugmentation.Scene;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
using FluentAssertions;
namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene
{ {
[TestFixture] [TestFixture]
public class SceneMappingServiceFixture : DbTest<SceneMappingService, SceneMapping> public class SceneMappingServiceFixture : CoreTest<SceneMappingService>
{ {
private List<SceneMapping> _fakeMappings; private List<SceneMapping> _fakeMappings;
@ -20,6 +21,18 @@ public class SceneMappingServiceFixture : DbTest<SceneMappingService, SceneMappi
public void Setup() public void Setup()
{ {
_fakeMappings = Builder<SceneMapping>.CreateListOfSize(5).BuildListOfNew(); _fakeMappings = Builder<SceneMapping>.CreateListOfSize(5).BuildListOfNew();
_fakeMappings[0].SearchTerm = "Words";
_fakeMappings[1].SearchTerm = "That";
_fakeMappings[2].SearchTerm = "Can";
_fakeMappings[3].SearchTerm = "Be";
_fakeMappings[4].SearchTerm = "Cleaned";
_fakeMappings[0].ParseTerm = "Words";
_fakeMappings[1].ParseTerm = "That";
_fakeMappings[2].ParseTerm = "Can";
_fakeMappings[3].ParseTerm = "Be";
_fakeMappings[4].ParseTerm = "Cleaned";
} }
@ -28,6 +41,7 @@ public void Setup()
public void UpdateMappings_purge_existing_mapping_and_add_new_ones() public void UpdateMappings_purge_existing_mapping_and_add_new_ones()
{ {
Mocker.GetMock<ISceneMappingProxy>().Setup(c => c.Fetch()).Returns(_fakeMappings); Mocker.GetMock<ISceneMappingProxy>().Setup(c => c.Fetch()).Returns(_fakeMappings);
Mocker.GetMock<ISceneMappingRepository>().Setup(c => c.All()).Returns(_fakeMappings);
Subject.Execute(new UpdateSceneMappingCommand()); Subject.Execute(new UpdateSceneMappingCommand());
@ -75,7 +89,16 @@ private void AssertMappingUpdated()
Mocker.GetMock<ISceneMappingProxy>().Verify(c => c.Fetch(), Times.Once()); Mocker.GetMock<ISceneMappingProxy>().Verify(c => c.Fetch(), Times.Once());
Mocker.GetMock<ISceneMappingRepository>().Verify(c => c.Purge(), Times.Once()); Mocker.GetMock<ISceneMappingRepository>().Verify(c => c.Purge(), Times.Once());
Mocker.GetMock<ISceneMappingRepository>().Verify(c => c.InsertMany(_fakeMappings), Times.Once()); Mocker.GetMock<ISceneMappingRepository>().Verify(c => c.InsertMany(_fakeMappings), Times.Once());
foreach (var sceneMapping in _fakeMappings)
{
Subject.GetSceneName(sceneMapping.TvdbId).Should().Be(sceneMapping.SearchTerm);
Subject.GetTvDbId(sceneMapping.ParseTerm).Should().Be(sceneMapping.TvdbId);
} }
}
} }
} }

View File

@ -85,7 +85,7 @@ public void ParseTitle_single(string postTitle, string title, int seasonNumber,
result.EpisodeNumbers.Should().HaveCount(1); result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(seasonNumber); result.SeasonNumber.Should().Be(seasonNumber);
result.EpisodeNumbers.First().Should().Be(episodeNumber); result.EpisodeNumbers.First().Should().Be(episodeNumber);
result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.CleanSeriesTitle(title));
} }
[TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)] [TestCase(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)]
@ -159,7 +159,7 @@ public void TitleParse_multi(string postTitle, string title, int season, int[] e
var result = Parser.Parser.ParseTitle(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season); result.SeasonNumber.Should().Be(season);
result.EpisodeNumbers.Should().BeEquivalentTo(episodes); result.EpisodeNumbers.Should().BeEquivalentTo(episodes);
result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.CleanSeriesTitle(title));
} }
@ -178,7 +178,7 @@ public void parse_daily_episodes(string postTitle, string title, int year, int m
var result = Parser.Parser.ParseTitle(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
var airDate = new DateTime(year, month, day); var airDate = new DateTime(year, month, day);
result.Should().NotBeNull(); result.Should().NotBeNull();
result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.CleanSeriesTitle(title));
result.AirDate.Should().Be(airDate); result.AirDate.Should().Be(airDate);
result.EpisodeNumbers.Should().BeNull(); result.EpisodeNumbers.Should().BeNull();
} }
@ -232,7 +232,7 @@ public void full_season_release_parse(string postTitle, string title, int season
{ {
var result = Parser.Parser.ParseTitle(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season); result.SeasonNumber.Should().Be(season);
result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(title)); result.SeriesTitle.Should().Be(Parser.Parser.CleanSeriesTitle(title));
result.EpisodeNumbers.Length.Should().Be(0); result.EpisodeNumbers.Length.Should().Be(0);
result.FullSeason.Should().BeTrue(); result.FullSeason.Should().BeTrue();
} }
@ -244,7 +244,7 @@ public void full_season_release_parse(string postTitle, string title, int season
[TestCase("Parenthood.2010", "parenthood2010")] [TestCase("Parenthood.2010", "parenthood2010")]
public void series_name_normalize(string parsedSeriesName, string seriesName) public void series_name_normalize(string parsedSeriesName, string seriesName)
{ {
var result = Parser.Parser.NormalizeTitle(parsedSeriesName); var result = Parser.Parser.CleanSeriesTitle(parsedSeriesName);
result.Should().Be(seriesName); result.Should().Be(seriesName);
} }
@ -256,7 +256,7 @@ public void series_name_normalize(string parsedSeriesName, string seriesName)
[TestCase("24", "24")] [TestCase("24", "24")]
public void Normalize_Title(string dirty, string clean) public void Normalize_Title(string dirty, string clean)
{ {
var result = Parser.Parser.NormalizeTitle(dirty); var result = Parser.Parser.CleanSeriesTitle(dirty);
result.Should().Be(clean); result.Should().Be(clean);
} }
@ -284,7 +284,7 @@ public void Normalize_removed_common_words(string word)
foreach (var s in dirtyFormat) foreach (var s in dirtyFormat)
{ {
var dirty = String.Format(s, word); var dirty = String.Format(s, word);
Parser.Parser.NormalizeTitle(dirty).Should().Be("wordword"); Parser.Parser.CleanSeriesTitle(dirty).Should().Be("wordword");
} }
} }
@ -310,7 +310,7 @@ public void Normalize_not_removed_common_words_in_the_middle(string word)
foreach (var s in dirtyFormat) foreach (var s in dirtyFormat)
{ {
var dirty = String.Format(s, word); var dirty = String.Format(s, word);
Parser.Parser.NormalizeTitle(dirty).Should().Be(("word" + word.ToLower() + "word")); Parser.Parser.CleanSeriesTitle(dirty).Should().Be(("word" + word.ToLower() + "word"));
} }
} }
@ -327,7 +327,7 @@ public void Normalize_not_removed_common_words_in_the_middle(string word)
public void parse_series_name(string postTitle, string title) public void parse_series_name(string postTitle, string title)
{ {
var result = Parser.Parser.ParseSeriesName(postTitle); var result = Parser.Parser.ParseSeriesName(postTitle);
result.Should().Be(Parser.Parser.NormalizeTitle(title)); result.Should().Be(Parser.Parser.CleanSeriesTitle(title));
} }
[TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)] [TestCase("Castle.2009.S01E14.English.HDTV.XviD-LOL", Language.English)]
@ -372,7 +372,7 @@ public void parse_season_info(string postTitle, string seriesName, int seasonNum
{ {
var result = Parser.Parser.ParseTitle(postTitle); var result = Parser.Parser.ParseTitle(postTitle);
result.SeriesTitle.Should().Be(Parser.Parser.NormalizeTitle(seriesName)); result.SeriesTitle.Should().Be(Parser.Parser.CleanSeriesTitle(seriesName));
result.SeasonNumber.Should().Be(seasonNumber); result.SeasonNumber.Should().Be(seasonNumber);
result.FullSeason.Should().BeTrue(); result.FullSeason.Should().BeTrue();
} }

View File

@ -5,13 +5,15 @@ namespace NzbDrone.Core.DataAugmentation.Scene
{ {
public class SceneMapping : ModelBase public class SceneMapping : ModelBase
{ {
public string CleanTitle { get; set; } [JsonProperty("CleanTitle")]
public string ParseTerm { get; set; }
[JsonProperty("Title")] [JsonProperty("Title")]
public string SceneName { get; set; } public string SearchTerm { get; set; }
[JsonProperty("Id")] [JsonProperty("Id")]
public int TvdbId { get; set; } public int TvdbId { get; set; }
public int SeasonNumber { get; set; } public int SeasonNumber { get; set; }
} }
} }

View File

@ -4,6 +4,7 @@
using NzbDrone.Common.Cache; using NzbDrone.Common.Cache;
using NzbDrone.Common.Messaging; using NzbDrone.Common.Messaging;
using NzbDrone.Core.Lifecycle; using NzbDrone.Core.Lifecycle;
using NzbDrone.Core.Parser;
namespace NzbDrone.Core.DataAugmentation.Scene namespace NzbDrone.Core.DataAugmentation.Scene
{ {
@ -18,8 +19,6 @@ public class SceneMappingService : ISceneMappingService,
IExecute<UpdateSceneMappingCommand> IExecute<UpdateSceneMappingCommand>
{ {
private static readonly object mutex = new object();
private readonly ISceneMappingRepository _repository; private readonly ISceneMappingRepository _repository;
private readonly ISceneMappingProxy _sceneMappingProxy; private readonly ISceneMappingProxy _sceneMappingProxy;
private readonly Logger _logger; private readonly Logger _logger;
@ -37,72 +36,77 @@ public SceneMappingService(ISceneMappingRepository repository, ISceneMappingProx
} }
public string GetSceneName(int tvdbId, int seasonNumber = -1) public string GetSceneName(int tvdbId, int seasonNumber = -1)
{
lock (mutex)
{ {
var mapping = _getSceneNameCache.Find(tvdbId.ToString()); var mapping = _getSceneNameCache.Find(tvdbId.ToString());
if (mapping == null) return null; if (mapping == null) return null;
return mapping.SceneName; return mapping.SearchTerm;
}
} }
public Nullable<Int32> GetTvDbId(string cleanName) public Nullable<Int32> GetTvDbId(string cleanName)
{ {
lock (mutex) var mapping = _gettvdbIdCache.Find(cleanName.CleanSeriesTitle());
{
var mapping = _gettvdbIdCache.Find(cleanName);
if (mapping == null) if (mapping == null)
return null; return null;
return mapping.TvdbId; return mapping.TvdbId;
} }
}
public void HandleAsync(ApplicationStartedEvent message)
{
if (!_repository.HasItems())
{
UpdateMappings();
}
}
private void UpdateMappings() private void UpdateMappings()
{ {
_logger.Info("Updating Scene mapping");
try try
{ {
var mappings = _sceneMappingProxy.Fetch(); var mappings = _sceneMappingProxy.Fetch();
lock (mutex)
{
if (mappings.Any()) if (mappings.Any())
{ {
_repository.Purge(); _repository.Purge();
foreach (var sceneMapping in mappings)
{
sceneMapping.ParseTerm = sceneMapping.ParseTerm.CleanSeriesTitle();
}
_repository.InsertMany(mappings); _repository.InsertMany(mappings);
}
else
{
_logger.Warn("Received empty list of mapping. will not update.");
}
}
catch (Exception ex)
{
_logger.ErrorException("Failed to Update Scene Mappings:", ex);
}
RefreshCache();
}
private void RefreshCache()
{
var mappings = _repository.All();
_gettvdbIdCache.Clear(); _gettvdbIdCache.Clear();
_getSceneNameCache.Clear(); _getSceneNameCache.Clear();
foreach (var sceneMapping in mappings) foreach (var sceneMapping in mappings)
{ {
_getSceneNameCache.Set(sceneMapping.TvdbId.ToString(), sceneMapping); _getSceneNameCache.Set(sceneMapping.TvdbId.ToString(), sceneMapping);
_gettvdbIdCache.Set(sceneMapping.CleanTitle, sceneMapping); _gettvdbIdCache.Set(sceneMapping.ParseTerm.CleanSeriesTitle(), sceneMapping);
} }
} }
else
public void HandleAsync(ApplicationStartedEvent message)
{ {
_logger.Warn("Received empty list of mapping. will not update."); UpdateMappings();
}
}
}
catch (Exception ex)
{
_logger.ErrorException("Failed to Update Scene Mappings:", ex);
}
} }
public void Execute(UpdateSceneMappingCommand message) public void Execute(UpdateSceneMappingCommand message)

View File

@ -5,7 +5,7 @@ namespace NzbDrone.Core.Datastore.Migration
{ {
[Tags("")] [Tags("")]
[Migration(2)] [Migration(2)]
public class Remove_tvrage_imdb_unique_constraint : NzbDroneMigrationBase public class remove_tvrage_imdb_unique_constraint : NzbDroneMigrationBase
{ {
protected override void MainDbUpgrade() protected override void MainDbUpgrade()
{ {

View File

@ -0,0 +1,21 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Tags("")]
[Migration(3)]
public class remove_renamed_scene_mapping_columns : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Delete.Table("SceneMappings");
Create.TableForModel("SceneMappings")
.WithColumn("TvdbId").AsInt32()
.WithColumn("SeasonNumber").AsInt32()
.WithColumn("SearchTerm").AsString()
.WithColumn("ParseTerm").AsString();
}
}
}

View File

@ -207,12 +207,13 @@
<Compile Include="Datastore\IWriteModels.cs" /> <Compile Include="Datastore\IWriteModels.cs" />
<Compile Include="Datastore\LazyList.cs" /> <Compile Include="Datastore\LazyList.cs" />
<Compile Include="Datastore\MappingExtensions.cs" /> <Compile Include="Datastore\MappingExtensions.cs" />
<Compile Include="Datastore\Migration\002_Remove_tvrage_imdb_unique_constraint.cs" /> <Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.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" />
<Compile Include="Datastore\Migration\Framework\MigrationOptions.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationOptions.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationLogger.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationLogger.cs" />
<Compile Include="Datastore\Migration\001_InitialSetup.cs" /> <Compile Include="Datastore\Migration\001_initialSetup.cs" />
<Compile Include="Datastore\Migration\Framework\NzbDroneMigrationBase.cs" /> <Compile Include="Datastore\Migration\Framework\NzbDroneMigrationBase.cs" />
<Compile Include="Datastore\MigrationType.cs" /> <Compile Include="Datastore\MigrationType.cs" />
<Compile Include="Datastore\ModelBase.cs" /> <Compile Include="Datastore\ModelBase.cs" />

View File

@ -214,7 +214,7 @@ private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchColle
}; };
} }
result.SeriesTitle = NormalizeTitle(seriesName); result.SeriesTitle = CleanSeriesTitle(seriesName);
Logger.Trace("Episode Parsed. {0}", result); Logger.Trace("Episode Parsed. {0}", result);
@ -229,7 +229,7 @@ public static string ParseSeriesName(string title)
if (parseResult == null) if (parseResult == null)
{ {
return NormalizeTitle(title); return CleanSeriesTitle(title);
} }
return parseResult.SeriesTitle; return parseResult.SeriesTitle;
@ -240,7 +240,7 @@ private static QualityModel ParseQuality(string name)
Logger.Trace("Trying to parse quality for {0}", name); Logger.Trace("Trying to parse quality for {0}", name);
name = name.Trim(); name = name.Trim();
var normalizedName = NormalizeTitle(name); var normalizedName = CleanSeriesTitle(name);
var result = new QualityModel { Quality = Quality.Unknown }; var result = new QualityModel { Quality = Quality.Unknown };
result.Proper = (normalizedName.Contains("proper") || normalizedName.Contains("repack")); result.Proper = (normalizedName.Contains("proper") || normalizedName.Contains("repack"));
@ -472,7 +472,7 @@ private static bool ValidateBeforeParsing(string title)
return true; return true;
} }
public static string NormalizeTitle(string title) public static string CleanSeriesTitle(this string title)
{ {
long number = 0; long number = 0;

View File

@ -71,7 +71,7 @@ private void RefreshSeriesInfo(Series series)
series.AirTime = seriesInfo.AirTime; series.AirTime = seriesInfo.AirTime;
series.Overview = seriesInfo.Overview; series.Overview = seriesInfo.Overview;
series.Status = seriesInfo.Status; series.Status = seriesInfo.Status;
series.CleanTitle = Parser.Parser.NormalizeTitle(seriesInfo.Title); series.CleanTitle = Parser.Parser.CleanSeriesTitle(seriesInfo.Title);
series.LastInfoSync = DateTime.UtcNow; series.LastInfoSync = DateTime.UtcNow;
series.Runtime = seriesInfo.Runtime; series.Runtime = seriesInfo.Runtime;
series.Images = seriesInfo.Images; series.Images = seriesInfo.Images;

View File

@ -77,7 +77,7 @@ public Series AddSeries(Series newSeries)
_logger.Info("Adding Series [{0}] Path: [{1}]", newSeries.Title, newSeries.Path); _logger.Info("Adding Series [{0}] Path: [{1}]", newSeries.Title, newSeries.Path);
newSeries.Monitored = true; newSeries.Monitored = true;
newSeries.CleanTitle = Parser.Parser.NormalizeTitle(newSeries.Title); newSeries.CleanTitle = Parser.Parser.CleanSeriesTitle(newSeries.Title);
newSeries.SeasonFolder = _configService.UseSeasonFolder; newSeries.SeasonFolder = _configService.UseSeasonFolder;
newSeries.BacklogSetting = BacklogSettingType.Inherit; newSeries.BacklogSetting = BacklogSettingType.Inherit;
@ -129,7 +129,7 @@ public Series FindByTitle(string title)
return FindByTvdbId(tvdbId.Value); return FindByTvdbId(tvdbId.Value);
} }
return _seriesRepository.FindByTitle(Parser.Parser.NormalizeTitle(title)); return _seriesRepository.FindByTitle(Parser.Parser.CleanSeriesTitle(title));
} }
public void SetSeriesType(int seriesId, SeriesTypes seriesTypes) public void SetSeriesType(int seriesId, SeriesTypes seriesTypes)

View File

@ -1,5 +1,5 @@
"use strict"; "use strict";
define(['app', 'Shared/Cells/FileSizeCell'], function () { define(['app', 'Shared/Cells/FileSizeCell', 'Shared/Cells/ApprovalStatusCell'], function () {
NzbDrone.Episode.Search.Layout = Backbone.Marionette.Layout.extend({ NzbDrone.Episode.Search.Layout = Backbone.Marionette.Layout.extend({
template: 'Episode/Search/LayoutTemplate', template: 'Episode/Search/LayoutTemplate',
@ -28,9 +28,9 @@ define(['app', 'Shared/Cells/FileSizeCell'], function () {
cell : Backgrid.StringCell cell : Backgrid.StringCell
}, },
{ {
name : 'approved', name : 'rejections',
label: 'Approved', label: 'decision',
cell : Backgrid.BooleanCell cell : NzbDrone.Shared.Cells.ApprovalStatusCell
} }
], ],