diff --git a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs index c01b1efdc..64c5cbc79 100644 --- a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs +++ b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingProxyFixture.cs @@ -34,8 +34,8 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene mappings.Should().NotBeEmpty(); - mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.CleanTitle)); - mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.SceneName)); + mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.SearchTerm)); + mappings.Should().NotContain(c => string.IsNullOrWhiteSpace(c.ParseTerm)); mappings.Should().NotContain(c => c.TvdbId == 0); } diff --git a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingServiceFixture.cs b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingServiceFixture.cs index ebfec9944..55bed6ad5 100644 --- a/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingServiceFixture.cs +++ b/NzbDrone.Core.Test/DataAugmentationFixture/Scene/SceneMappingServiceFixture.cs @@ -6,12 +6,13 @@ using NUnit.Framework; using NzbDrone.Core.DataAugmentation.Scene; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common; +using FluentAssertions; namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene { [TestFixture] - public class SceneMappingServiceFixture : DbTest + public class SceneMappingServiceFixture : CoreTest { private List _fakeMappings; @@ -20,6 +21,18 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene public void Setup() { _fakeMappings = Builder.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 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene public void UpdateMappings_purge_existing_mapping_and_add_new_ones() { Mocker.GetMock().Setup(c => c.Fetch()).Returns(_fakeMappings); + Mocker.GetMock().Setup(c => c.All()).Returns(_fakeMappings); Subject.Execute(new UpdateSceneMappingCommand()); @@ -75,7 +89,16 @@ namespace NzbDrone.Core.Test.DataAugmentationFixture.Scene Mocker.GetMock().Verify(c => c.Fetch(), Times.Once()); Mocker.GetMock().Verify(c => c.Purge(), Times.Once()); Mocker.GetMock().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); + } } + + } } diff --git a/NzbDrone.Core.Test/ParserTests/ParserFixture.cs b/NzbDrone.Core.Test/ParserTests/ParserFixture.cs index 518ebcbc2..cc43055e2 100644 --- a/NzbDrone.Core.Test/ParserTests/ParserFixture.cs +++ b/NzbDrone.Core.Test/ParserTests/ParserFixture.cs @@ -85,7 +85,7 @@ namespace NzbDrone.Core.Test.ParserTests result.EpisodeNumbers.Should().HaveCount(1); result.SeasonNumber.Should().Be(seasonNumber); 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)] @@ -159,7 +159,7 @@ namespace NzbDrone.Core.Test.ParserTests var result = Parser.Parser.ParseTitle(postTitle); result.SeasonNumber.Should().Be(season); 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 @@ namespace NzbDrone.Core.Test.ParserTests var result = Parser.Parser.ParseTitle(postTitle); var airDate = new DateTime(year, month, day); 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.EpisodeNumbers.Should().BeNull(); } @@ -232,7 +232,7 @@ namespace NzbDrone.Core.Test.ParserTests { var result = Parser.Parser.ParseTitle(postTitle); 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.FullSeason.Should().BeTrue(); } @@ -244,7 +244,7 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("Parenthood.2010", "parenthood2010")] 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); } @@ -256,7 +256,7 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("24", "24")] public void Normalize_Title(string dirty, string clean) { - var result = Parser.Parser.NormalizeTitle(dirty); + var result = Parser.Parser.CleanSeriesTitle(dirty); result.Should().Be(clean); } @@ -284,7 +284,7 @@ namespace NzbDrone.Core.Test.ParserTests foreach (var s in dirtyFormat) { var dirty = String.Format(s, word); - Parser.Parser.NormalizeTitle(dirty).Should().Be("wordword"); + Parser.Parser.CleanSeriesTitle(dirty).Should().Be("wordword"); } } @@ -310,7 +310,7 @@ namespace NzbDrone.Core.Test.ParserTests foreach (var s in dirtyFormat) { 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 @@ namespace NzbDrone.Core.Test.ParserTests public void parse_series_name(string postTitle, string title) { 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)] @@ -372,7 +372,7 @@ namespace NzbDrone.Core.Test.ParserTests { 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.FullSeason.Should().BeTrue(); } diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMapping.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMapping.cs index 9c846de37..011096f15 100644 --- a/NzbDrone.Core/DataAugmentation/Scene/SceneMapping.cs +++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMapping.cs @@ -5,13 +5,15 @@ namespace NzbDrone.Core.DataAugmentation.Scene { public class SceneMapping : ModelBase { - public string CleanTitle { get; set; } + [JsonProperty("CleanTitle")] + public string ParseTerm { get; set; } [JsonProperty("Title")] - public string SceneName { get; set; } + public string SearchTerm { get; set; } [JsonProperty("Id")] public int TvdbId { get; set; } + public int SeasonNumber { get; set; } } } \ No newline at end of file diff --git a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs index 406e2d6de..962b861c9 100644 --- a/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs +++ b/NzbDrone.Core/DataAugmentation/Scene/SceneMappingService.cs @@ -4,6 +4,7 @@ using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Messaging; using NzbDrone.Core.Lifecycle; +using NzbDrone.Core.Parser; namespace NzbDrone.Core.DataAugmentation.Scene { @@ -18,8 +19,6 @@ namespace NzbDrone.Core.DataAugmentation.Scene IExecute { - private static readonly object mutex = new object(); - private readonly ISceneMappingRepository _repository; private readonly ISceneMappingProxy _sceneMappingProxy; private readonly Logger _logger; @@ -38,71 +37,76 @@ namespace NzbDrone.Core.DataAugmentation.Scene 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 GetTvDbId(string cleanName) { - lock (mutex) - { - var mapping = _gettvdbIdCache.Find(cleanName); + var mapping = _gettvdbIdCache.Find(cleanName.CleanSeriesTitle()); - if (mapping == null) - return null; + if (mapping == null) + return null; - return mapping.TvdbId; - } + return mapping.TvdbId; } - public void HandleAsync(ApplicationStartedEvent message) - { - if (!_repository.HasItems()) - { - UpdateMappings(); - } - } - private void UpdateMappings() { + _logger.Info("Updating Scene mapping"); + try { var mappings = _sceneMappingProxy.Fetch(); - lock (mutex) + if (mappings.Any()) { - if (mappings.Any()) - { - _repository.Purge(); - _repository.InsertMany(mappings); + _repository.Purge(); - _gettvdbIdCache.Clear(); - _getSceneNameCache.Clear(); - - foreach (var sceneMapping in mappings) - { - _getSceneNameCache.Set(sceneMapping.TvdbId.ToString(), sceneMapping); - _gettvdbIdCache.Set(sceneMapping.CleanTitle, sceneMapping); - } - } - else + foreach (var sceneMapping in mappings) { - _logger.Warn("Received empty list of mapping. will not update."); + sceneMapping.ParseTerm = sceneMapping.ParseTerm.CleanSeriesTitle(); } + + _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(); + _getSceneNameCache.Clear(); + + foreach (var sceneMapping in mappings) + { + _getSceneNameCache.Set(sceneMapping.TvdbId.ToString(), sceneMapping); + _gettvdbIdCache.Set(sceneMapping.ParseTerm.CleanSeriesTitle(), sceneMapping); + } + } + + + public void HandleAsync(ApplicationStartedEvent message) + { + UpdateMappings(); } public void Execute(UpdateSceneMappingCommand message) diff --git a/NzbDrone.Core/Datastore/Migration/002_Remove_tvrage_imdb_unique_constraint.cs b/NzbDrone.Core/Datastore/Migration/002_Remove_tvrage_imdb_unique_constraint.cs index 89ff7c61a..c6a179b32 100644 --- a/NzbDrone.Core/Datastore/Migration/002_Remove_tvrage_imdb_unique_constraint.cs +++ b/NzbDrone.Core/Datastore/Migration/002_Remove_tvrage_imdb_unique_constraint.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.Datastore.Migration { [Tags("")] [Migration(2)] - public class Remove_tvrage_imdb_unique_constraint : NzbDroneMigrationBase + public class remove_tvrage_imdb_unique_constraint : NzbDroneMigrationBase { protected override void MainDbUpgrade() { diff --git a/NzbDrone.Core/Datastore/Migration/003_remove_clean_title_from_scene_mapping.cs b/NzbDrone.Core/Datastore/Migration/003_remove_clean_title_from_scene_mapping.cs new file mode 100644 index 000000000..56db4aabd --- /dev/null +++ b/NzbDrone.Core/Datastore/Migration/003_remove_clean_title_from_scene_mapping.cs @@ -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(); + } + } +} diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index c1605b733..49ca56a47 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -207,12 +207,13 @@ - + + - + diff --git a/NzbDrone.Core/Parser/Parser.cs b/NzbDrone.Core/Parser/Parser.cs index 822e80c37..b8f5b35bb 100644 --- a/NzbDrone.Core/Parser/Parser.cs +++ b/NzbDrone.Core/Parser/Parser.cs @@ -214,7 +214,7 @@ namespace NzbDrone.Core.Parser }; } - result.SeriesTitle = NormalizeTitle(seriesName); + result.SeriesTitle = CleanSeriesTitle(seriesName); Logger.Trace("Episode Parsed. {0}", result); @@ -229,7 +229,7 @@ namespace NzbDrone.Core.Parser if (parseResult == null) { - return NormalizeTitle(title); + return CleanSeriesTitle(title); } return parseResult.SeriesTitle; @@ -240,7 +240,7 @@ namespace NzbDrone.Core.Parser Logger.Trace("Trying to parse quality for {0}", name); name = name.Trim(); - var normalizedName = NormalizeTitle(name); + var normalizedName = CleanSeriesTitle(name); var result = new QualityModel { Quality = Quality.Unknown }; result.Proper = (normalizedName.Contains("proper") || normalizedName.Contains("repack")); @@ -472,7 +472,7 @@ namespace NzbDrone.Core.Parser return true; } - public static string NormalizeTitle(string title) + public static string CleanSeriesTitle(this string title) { long number = 0; diff --git a/NzbDrone.Core/Tv/RefreshSeriesService.cs b/NzbDrone.Core/Tv/RefreshSeriesService.cs index b7b59b338..af6249595 100644 --- a/NzbDrone.Core/Tv/RefreshSeriesService.cs +++ b/NzbDrone.Core/Tv/RefreshSeriesService.cs @@ -71,7 +71,7 @@ namespace NzbDrone.Core.Tv series.AirTime = seriesInfo.AirTime; series.Overview = seriesInfo.Overview; series.Status = seriesInfo.Status; - series.CleanTitle = Parser.Parser.NormalizeTitle(seriesInfo.Title); + series.CleanTitle = Parser.Parser.CleanSeriesTitle(seriesInfo.Title); series.LastInfoSync = DateTime.UtcNow; series.Runtime = seriesInfo.Runtime; series.Images = seriesInfo.Images; diff --git a/NzbDrone.Core/Tv/SeriesService.cs b/NzbDrone.Core/Tv/SeriesService.cs index 131900626..01af36620 100644 --- a/NzbDrone.Core/Tv/SeriesService.cs +++ b/NzbDrone.Core/Tv/SeriesService.cs @@ -77,7 +77,7 @@ namespace NzbDrone.Core.Tv _logger.Info("Adding Series [{0}] Path: [{1}]", newSeries.Title, newSeries.Path); newSeries.Monitored = true; - newSeries.CleanTitle = Parser.Parser.NormalizeTitle(newSeries.Title); + newSeries.CleanTitle = Parser.Parser.CleanSeriesTitle(newSeries.Title); newSeries.SeasonFolder = _configService.UseSeasonFolder; newSeries.BacklogSetting = BacklogSettingType.Inherit; @@ -129,7 +129,7 @@ namespace NzbDrone.Core.Tv 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) diff --git a/UI/Episode/Search/Layout.js b/UI/Episode/Search/Layout.js index 628105170..cb4cf9fac 100644 --- a/UI/Episode/Search/Layout.js +++ b/UI/Episode/Search/Layout.js @@ -1,5 +1,5 @@ "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({ template: 'Episode/Search/LayoutTemplate', @@ -28,9 +28,9 @@ define(['app', 'Shared/Cells/FileSizeCell'], function () { cell : Backgrid.StringCell }, { - name : 'approved', - label: 'Approved', - cell : Backgrid.BooleanCell + name : 'rejections', + label: 'decision', + cell : NzbDrone.Shared.Cells.ApprovalStatusCell } ],