diff --git a/frontend/src/Activity/History/Details/HistoryDetails.js b/frontend/src/Activity/History/Details/HistoryDetails.js
index 361844b77..0da11f141 100644
--- a/frontend/src/Activity/History/Details/HistoryDetails.js
+++ b/frontend/src/Activity/History/Details/HistoryDetails.js
@@ -1,7 +1,8 @@
import PropTypes from 'prop-types';
import React from 'react';
-import formatDateTime from 'Utilities/Date/formatDateTime';
import formatAge from 'Utilities/Number/formatAge';
+import formatDateTime from 'Utilities/Date/formatDateTime';
+import formatPreferredWordScore from 'Utilities/Number/formatPreferredWordScore';
import Link from 'Components/Link/Link';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
@@ -22,6 +23,7 @@ function HistoryDetails(props) {
const {
indexer,
releaseGroup,
+ preferredWordScore,
nzbInfoUrl,
downloadClient,
downloadId,
@@ -56,6 +58,14 @@ function HistoryDetails(props) {
/>
}
+ {
+ !!preferredWordScore &&
+
+ }
+
{
!!nzbInfoUrl &&
@@ -86,7 +96,7 @@ function HistoryDetails(props) {
}
{
- !!indexer &&
+ !!(age || ageHours || ageMinutes) &&
}
+
+ {
+ !!preferredWordScore &&
+
+ }
);
}
if (eventType === 'episodeFileDeleted') {
const {
- reason
+ reason,
+ preferredWordScore
} = data;
let reasonMessage = '';
@@ -195,6 +215,14 @@ function HistoryDetails(props) {
title="Reason"
data={reasonMessage}
/>
+
+ {
+ !!preferredWordScore &&
+
+ }
);
}
diff --git a/frontend/src/Activity/History/HistoryRow.css b/frontend/src/Activity/History/HistoryRow.css
index 669377fdb..07a392d71 100644
--- a/frontend/src/Activity/History/HistoryRow.css
+++ b/frontend/src/Activity/History/HistoryRow.css
@@ -10,6 +10,12 @@
width: 80px;
}
+.preferredWordScore {
+ composes: cell from '~Components/Table/Cells/TableRowCell.css';
+
+ width: 55px;
+}
+
.releaseGroup {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
diff --git a/frontend/src/Activity/History/HistoryRow.js b/frontend/src/Activity/History/HistoryRow.js
index 454913412..7b892be6a 100644
--- a/frontend/src/Activity/History/HistoryRow.js
+++ b/frontend/src/Activity/History/HistoryRow.js
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
+import formatPreferredWordScore from 'Utilities/Number/formatPreferredWordScore';
import { icons } from 'Helpers/Props';
import IconButton from 'Components/Link/IconButton';
import RelativeDateCellConnector from 'Components/Table/Cells/RelativeDateCellConnector';
@@ -194,6 +195,17 @@ class HistoryRow extends Component {
);
}
+ if (name === 'preferredWordScore') {
+ return (
+
+ {formatPreferredWordScore(data.preferredWordScore)}
+
+ );
+ }
+
if (name === 'releaseGroup') {
return (
- {preferredWordScore > 0 && `+${preferredWordScore}`}
- {preferredWordScore < 0 && preferredWordScore}
+ {formatPreferredWordScore(preferredWordScore)}
diff --git a/frontend/src/Store/Actions/historyActions.js b/frontend/src/Store/Actions/historyActions.js
index abe9c16bf..3d4a52d13 100644
--- a/frontend/src/Store/Actions/historyActions.js
+++ b/frontend/src/Store/Actions/historyActions.js
@@ -1,7 +1,9 @@
+import React from 'react';
import { createAction } from 'redux-actions';
import createAjaxRequest from 'Utilities/createAjaxRequest';
import serverSideCollectionHandlers from 'Utilities/serverSideCollectionHandlers';
-import { filterTypes, sortDirections } from 'Helpers/Props';
+import { filterTypes, icons, sortDirections } from 'Helpers/Props';
+import Icon from 'Components/Icon';
import { createThunk, handleThunks } from 'Store/thunks';
import createClearReducer from './Creators/Reducers/createClearReducer';
import createSetTableOptionReducer from './Creators/Reducers/createSetTableOptionReducer';
@@ -80,6 +82,15 @@ export const defaultState = {
label: 'Release Group',
isVisible: false
},
+ {
+ name: 'preferredWordScore',
+ columnLabel: 'Preferred Word Score',
+ label: React.createElement(Icon, {
+ name: icons.SCORE,
+ title: 'Preferred word score'
+ }),
+ isVisible: false
+ },
{
name: 'details',
columnLabel: 'Details',
diff --git a/frontend/src/Utilities/Number/formatPreferredWordScore.js b/frontend/src/Utilities/Number/formatPreferredWordScore.js
new file mode 100644
index 000000000..93024e0de
--- /dev/null
+++ b/frontend/src/Utilities/Number/formatPreferredWordScore.js
@@ -0,0 +1,16 @@
+
+function formatPreferredWordScore(input) {
+ const score = Number(input);
+
+ if (score > 0) {
+ return `+${score}`;
+ }
+
+ if (score < 0) {
+ return score;
+ }
+
+ return '';
+}
+
+export default formatPreferredWordScore;
diff --git a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/GetSceneNameFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/GetSceneNameFixture.cs
new file mode 100644
index 000000000..ae64e2c12
--- /dev/null
+++ b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/GetSceneNameFixture.cs
@@ -0,0 +1,199 @@
+using System.Collections.Generic;
+using System.IO;
+using FizzWare.NBuilder;
+using FluentAssertions;
+using Moq;
+using NUnit.Framework;
+using NzbDrone.Core.MediaFiles;
+using NzbDrone.Core.MediaFiles.EpisodeImport;
+using NzbDrone.Core.Parser.Model;
+using NzbDrone.Core.Profiles.Qualities;
+using NzbDrone.Core.Qualities;
+using NzbDrone.Core.Test.Framework;
+using NzbDrone.Core.Tv;
+using NzbDrone.Test.Common;
+using NzbDrone.Core.Languages;
+using NzbDrone.Core.Profiles.Languages;
+
+namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
+{
+ [TestFixture]
+ public class GetSceneNameFixture : CoreTest
+ {
+ private LocalEpisode _localEpisode;
+ private string _seasonName = "series.title.s02.dvdrip.x264-ingot";
+ private string _episodeName = "series.title.s02e23.dvdrip.x264-ingot";
+
+ [SetUp]
+ public void Setup()
+ {
+ var series = Builder.CreateNew()
+ .With(e => e.QualityProfile = new QualityProfile { Items = Qualities.QualityFixture.GetDefaultQualities() })
+ .With(l => l.LanguageProfile = new LanguageProfile
+ {
+ Cutoff = Language.Spanish,
+ Languages = Languages.LanguageFixture.GetDefaultLanguages()
+ })
+ .With(s => s.Path = @"C:\Test\TV\Series Title".AsOsAgnostic())
+ .Build();
+
+ var episode = Builder.CreateNew()
+ .Build();
+
+ _localEpisode = new LocalEpisode
+ {
+ Series = series,
+ Episodes = new List {episode},
+ Path = Path.Combine(series.Path, "Series Title - S02E23 - Episode Title.mkv"),
+ Quality = new QualityModel(Quality.Bluray720p),
+ ReleaseGroup = "DRONE"
+ };
+ }
+
+ private void GivenExistingFileOnDisk()
+ {
+ Mocker.GetMock()
+ .Setup(s => s.GetFilesWithRelativePath(It.IsAny(), It.IsAny()))
+ .Returns(new List());
+ }
+
+ [Test]
+ public void should_use_download_client_item_title_as_scene_name()
+ {
+ _localEpisode.DownloadClientEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = _episodeName
+ };
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .Be(_episodeName);
+ }
+
+ [Test]
+ public void should_not_use_download_client_item_title_as_scene_name_if_full_season()
+ {
+ _localEpisode.DownloadClientEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = _seasonName,
+ FullSeason = true
+ };
+
+ _localEpisode.Path = Path.Combine(@"C:\Test\Unsorted TV", _seasonName, _episodeName)
+ .AsOsAgnostic();
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .BeNull();
+ }
+
+ [Test]
+ public void should_not_use_download_client_item_title_as_scene_name_if_there_are_other_video_files()
+ {
+ _localEpisode.OtherVideoFiles = true;
+ _localEpisode.DownloadClientEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = _seasonName,
+ FullSeason = false
+ };
+
+ _localEpisode.Path = Path.Combine(@"C:\Test\Unsorted TV", _seasonName, _episodeName)
+ .AsOsAgnostic();
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .BeNull();
+ }
+
+ [Test]
+ public void should_use_file_name_as_scenename_only_if_it_looks_like_scenename()
+ {
+ _localEpisode.Path = Path.Combine(@"C:\Test\Unsorted TV", _seasonName, _episodeName + ".mkv")
+ .AsOsAgnostic();
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .Be(_episodeName);
+ }
+
+ [Test]
+ public void should_not_use_file_name_as_scenename_if_it_doesnt_look_like_scenename()
+ {
+ _localEpisode.Path = Path.Combine(@"C:\Test\Unsorted TV", _episodeName, "aaaaa.mkv")
+ .AsOsAgnostic();
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .BeNull();
+ }
+
+ [Test]
+ public void should_use_folder_name_as_scenename_only_if_it_looks_like_scenename()
+ {
+ _localEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = _episodeName
+ };
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .Be(_episodeName);
+ }
+
+ [Test]
+ public void should_not_use_folder_name_as_scenename_if_it_doesnt_look_like_scenename()
+ {
+ _localEpisode.Path = Path.Combine(@"C:\Test\Unsorted TV", _episodeName, "aaaaa.mkv")
+ .AsOsAgnostic();
+
+ _localEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = "aaaaa"
+ };
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .BeNull();
+ }
+
+ [Test]
+ public void should_not_use_folder_name_as_scenename_if_it_is_for_a_full_season()
+ {
+ _localEpisode.Path = Path.Combine(@"C:\Test\Unsorted TV", _episodeName, "aaaaa.mkv")
+ .AsOsAgnostic();
+
+ _localEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = _seasonName,
+ FullSeason = true
+ };
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .BeNull();
+ }
+
+ [Test]
+ public void should_not_use_folder_name_as_scenename_if_there_are_other_video_files()
+ {
+ _localEpisode.OtherVideoFiles = true;
+ _localEpisode.Path = Path.Combine(@"C:\Test\Unsorted TV", _episodeName, "aaaaa.mkv")
+ .AsOsAgnostic();
+
+ _localEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = _seasonName,
+ FullSeason = false
+ };
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .BeNull();
+ }
+
+ [TestCase(".mkv")]
+ [TestCase(".par2")]
+ [TestCase(".nzb")]
+ public void should_remove_extension_from_nzb_title_for_scene_name(string extension)
+ {
+ _localEpisode.DownloadClientEpisodeInfo = new ParsedEpisodeInfo
+ {
+ ReleaseTitle = _episodeName + extension
+ };
+
+ SceneNameCalculator.GetSceneName(_localEpisode).Should()
+ .Be(_episodeName);
+ }
+ }
+}
diff --git a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/ImportApprovedEpisodesFixture.cs
similarity index 75%
rename from src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs
rename to src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/ImportApprovedEpisodesFixture.cs
index 2a423c765..dd3cd5791 100644
--- a/src/NzbDrone.Core.Test/MediaFiles/ImportApprovedEpisodesFixture.cs
+++ b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/ImportApprovedEpisodesFixture.cs
@@ -21,7 +21,7 @@ using NzbDrone.Test.Common;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Profiles.Languages;
-namespace NzbDrone.Core.Test.MediaFiles
+namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
{
[TestFixture]
public class ImportApprovedEpisodesFixture : CoreTest
@@ -169,112 +169,6 @@ namespace NzbDrone.Core.Test.MediaFiles
Times.Never());
}
- [Test]
- public void should_use_nzb_title_as_scene_name()
- {
- GivenNewDownload();
- _downloadClientItem.Title = "malcolm.in.the.middle.s02e05.dvdrip.xvid-ingot";
-
- Subject.Import(new List { _approvedDecisions.First() }, true, _downloadClientItem);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == _downloadClientItem.Title)));
- }
-
- [TestCase(".mkv")]
- [TestCase(".par2")]
- [TestCase(".nzb")]
- public void should_remove_extension_from_nzb_title_for_scene_name(string extension)
- {
- GivenNewDownload();
- var title = "malcolm.in.the.middle.s02e05.dvdrip.xvid-ingot";
-
- _downloadClientItem.Title = title + extension;
-
- Subject.Import(new List { _approvedDecisions.First() }, true, _downloadClientItem);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == title)));
- }
-
- [Test]
- public void should_not_use_nzb_title_as_scene_name_if_full_season()
- {
- GivenNewDownload();
- _approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "malcolm.in.the.middle.s02e23.dvdrip.xvid-ingot.mkv");
- _downloadClientItem.Title = "malcolm.in.the.middle.s02.dvdrip.xvid-ingot";
-
- Subject.Import(new List { _approvedDecisions.First() }, true, _downloadClientItem);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == "malcolm.in.the.middle.s02e23.dvdrip.xvid-ingot")));
- }
-
- [Test]
- public void should_use_file_name_as_scenename_only_if_it_looks_like_scenename()
- {
- GivenNewDownload();
- _approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "series.title.s02e23.dvdrip.xvid-ingot.mkv");
-
- Subject.Import(new List { _approvedDecisions.First() }, true);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == "series.title.s02e23.dvdrip.xvid-ingot")));
- }
-
- [Test]
- public void should_not_use_file_name_as_scenename_if_it_doesnt_looks_like_scenename()
- {
- GivenNewDownload();
- _approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "aaaaa.mkv");
-
- Subject.Import(new List { _approvedDecisions.First() }, true);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == null)));
- }
-
- [Test]
- public void should_use_folder_name_as_scenename_only_if_it_looks_like_scenename()
- {
- GivenNewDownload();
- _approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "aaaaa.mkv");
- _approvedDecisions.First().LocalEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo
- {
- ReleaseTitle = "series.title.s02e23.dvdrip.xvid-ingot"
- };
-
- Subject.Import(new List { _approvedDecisions.First() }, true);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == "series.title.s02e23.dvdrip.xvid-ingot")));
- }
-
- [Test]
- public void should_not_use_folder_name_as_scenename_if_it_doesnt_looks_like_scenename()
- {
- GivenNewDownload();
- _approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "aaaaa.mkv");
- _approvedDecisions.First().LocalEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo
- {
- ReleaseTitle = "aaaaa.mkv"
- };
-
- Subject.Import(new List { _approvedDecisions.First() }, true);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == null)));
- }
-
- [Test]
- public void should_not_use_folder_name_as_scenename_if_it_is_for_a_full_season()
- {
- GivenNewDownload();
- _approvedDecisions.First().LocalEpisode.Path = Path.Combine(_downloadClientItem.OutputPath.ToString(), "aaaaa.mkv");
- _approvedDecisions.First().LocalEpisode.FolderEpisodeInfo = new ParsedEpisodeInfo
- {
- ReleaseTitle = "series.title.s02.dvdrip.xvid-ingot.mkv",
- FullSeason = true
- };
-
- Subject.Import(new List { _approvedDecisions.First() }, true);
-
- Mocker.GetMock().Verify(v => v.Add(It.Is(c => c.SceneName == null)));
- }
-
[Test]
public void should_import_larger_files_first()
{
diff --git a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs
index b2f4c444a..ad844cca2 100644
--- a/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs
+++ b/src/NzbDrone.Core.Test/MediaFiles/EpisodeImport/Specifications/UpgradeSpecificationFixture.cs
@@ -287,14 +287,11 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.Setup(s => s.DownloadPropersAndRepacks)
.Returns(ProperDownloadTypes.DoNotPrefer);
- Mocker.GetMock()
- .Setup(s => s.Calculate(It.IsAny(), It.IsAny(), 0))
- .Returns(5);
-
Mocker.GetMock()
.Setup(s => s.Calculate(It.IsAny(), It.IsAny()))
.Returns(10);
+ _localEpisode.PreferredWordScore = 5;
_localEpisode.Quality = new QualityModel(Quality.Bluray1080p);
_localEpisode.Episodes = Builder.CreateListOfSize(1)
@@ -364,14 +361,11 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.Setup(s => s.DownloadPropersAndRepacks)
.Returns(ProperDownloadTypes.DoNotPrefer);
- Mocker.GetMock()
- .Setup(s => s.Calculate(It.IsAny(), It.IsAny(), 0))
- .Returns(5);
-
Mocker.GetMock()
.Setup(s => s.Calculate(It.IsAny(), It.IsAny()))
.Returns(1);
+ _localEpisode.PreferredWordScore = 5;
_localEpisode.Quality = new QualityModel(Quality.Bluray1080p);
_localEpisode.Episodes = Builder.CreateListOfSize(1)
@@ -397,14 +391,11 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
.Setup(s => s.DownloadPropersAndRepacks)
.Returns(ProperDownloadTypes.DoNotPrefer);
- Mocker.GetMock()
- .Setup(s => s.Calculate(It.IsAny(), It.IsAny(), 0))
- .Returns(5);
-
Mocker.GetMock()
.Setup(s => s.Calculate(It.IsAny(), It.IsAny()))
.Returns(5);
+ _localEpisode.PreferredWordScore = 5;
_localEpisode.Quality = new QualityModel(Quality.Bluray1080p);
_localEpisode.Episodes = Builder.CreateListOfSize(1)
diff --git a/src/NzbDrone.Core/History/EpisodeHistory.cs b/src/NzbDrone.Core/History/EpisodeHistory.cs
index 933e05d7e..d6016cbde 100644
--- a/src/NzbDrone.Core/History/EpisodeHistory.cs
+++ b/src/NzbDrone.Core/History/EpisodeHistory.cs
@@ -26,9 +26,7 @@ namespace NzbDrone.Core.History
public EpisodeHistoryEventType EventType { get; set; }
public Dictionary Data { get; set; }
public Language Language { get; set; }
-
public string DownloadId { get; set; }
-
}
public enum EpisodeHistoryEventType
diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs
index de1730bc6..274256974 100644
--- a/src/NzbDrone.Core/History/HistoryService.cs
+++ b/src/NzbDrone.Core/History/HistoryService.cs
@@ -39,11 +39,13 @@ namespace NzbDrone.Core.History
IHandle
{
private readonly IHistoryRepository _historyRepository;
+ private readonly IEpisodeFilePreferredWordCalculator _episodeFilePreferredWordCalculator;
private readonly Logger _logger;
- public HistoryService(IHistoryRepository historyRepository, Logger logger)
+ public HistoryService(IHistoryRepository historyRepository, IEpisodeFilePreferredWordCalculator episodeFilePreferredWordCalculator, Logger logger)
{
_historyRepository = historyRepository;
+ _episodeFilePreferredWordCalculator = episodeFilePreferredWordCalculator;
_logger = logger;
}
@@ -148,7 +150,7 @@ namespace NzbDrone.Core.History
SeriesId = episode.SeriesId,
EpisodeId = episode.Id,
DownloadId = message.DownloadId,
- Language = message.Episode.ParsedEpisodeInfo.Language
+ Language = message.Episode.ParsedEpisodeInfo.Language,
};
history.Data.Add("Indexer", message.Episode.Release.Indexer);
@@ -166,6 +168,7 @@ namespace NzbDrone.Core.History
history.Data.Add("TvdbId", message.Episode.Release.TvdbId.ToString());
history.Data.Add("TvRageId", message.Episode.Release.TvRageId.ToString());
history.Data.Add("Protocol", ((int)message.Episode.Release.DownloadProtocol).ToString());
+ history.Data.Add("PreferredWordScore", message.Episode.PreferredWordScore.ToString());
if (!message.Episode.ParsedEpisodeInfo.ReleaseHash.IsNullOrWhiteSpace())
{
@@ -216,6 +219,7 @@ namespace NzbDrone.Core.History
history.Data.Add("ImportedPath", Path.Combine(message.EpisodeInfo.Series.Path, message.ImportedEpisode.RelativePath));
history.Data.Add("DownloadClient", message.DownloadClientInfo?.Type);
history.Data.Add("DownloadClientName", message.DownloadClientInfo?.Name);
+ history.Data.Add("PreferredWordScore", message.EpisodeInfo.PreferredWordScore.ToString());
_historyRepository.Insert(history);
}
@@ -258,6 +262,8 @@ namespace NzbDrone.Core.History
return;
}
+ var episodeFilePreferredWordScore = _episodeFilePreferredWordCalculator.Calculate(message.EpisodeFile.Series, message.EpisodeFile);
+
foreach (var episode in message.EpisodeFile.Episodes.Value)
{
var history = new EpisodeHistory
@@ -272,6 +278,7 @@ namespace NzbDrone.Core.History
};
history.Data.Add("Reason", message.Reason.ToString());
+ history.Data.Add("PreferredWordScore", episodeFilePreferredWordScore.ToString());
_historyRepository.Insert(history);
}
diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Aggregation/AggregationService.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Aggregation/AggregationService.cs
index 0362b3e31..32ab5ffcf 100644
--- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Aggregation/AggregationService.cs
+++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Aggregation/AggregationService.cs
@@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.IO;
using NLog;
using NzbDrone.Common.Disk;
+using NzbDrone.Common.Extensions;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Download;
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
using NzbDrone.Core.MediaFiles.MediaInfo;
+using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation
@@ -52,6 +54,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation
}
localEpisode.Size = _diskProvider.GetFileSize(localEpisode.Path);
+ localEpisode.SceneName = localEpisode.SceneSource ? SceneNameCalculator.GetSceneName(localEpisode) : null;
if (isMediaFile && (!localEpisode.ExistingFile || _configService.EnableMediaInfo))
{
diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Aggregation/Aggregators/AggregatePreferredWordScore.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Aggregation/Aggregators/AggregatePreferredWordScore.cs
new file mode 100644
index 000000000..9c1b4d706
--- /dev/null
+++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Aggregation/Aggregators/AggregatePreferredWordScore.cs
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+using NzbDrone.Core.Download;
+using NzbDrone.Core.Parser.Model;
+using NzbDrone.Core.Profiles.Releases;
+
+namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
+{
+ public class AggregatePreferredWordScore : IAggregateLocalEpisode
+ {
+ private readonly IPreferredWordService _preferredWordService;
+
+ public AggregatePreferredWordScore(IPreferredWordService preferredWordService)
+ {
+ _preferredWordService = preferredWordService;
+ }
+
+ public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles)
+ {
+ var series = localEpisode.Series;
+ var scores = new List();
+
+ if (localEpisode.FileEpisodeInfo != null)
+ {
+ scores.Add(_preferredWordService.Calculate(series, localEpisode.FileEpisodeInfo.ReleaseTitle, 0));
+ }
+
+ if (localEpisode.SceneName != null)
+ {
+ scores.Add(_preferredWordService.Calculate(series, localEpisode.SceneName, 0));
+ }
+
+ localEpisode.PreferredWordScore = scores.MaxOrDefault();
+
+ return localEpisode;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs
index 8d5417da1..035ad9921 100644
--- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs
+++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/ImportApprovedEpisodes.cs
@@ -4,11 +4,9 @@ using System.IO;
using System.Linq;
using NLog;
using NzbDrone.Common.Disk;
-using NzbDrone.Common.Exceptions;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.MediaFiles.Events;
using NzbDrone.Core.Messaging.Events;
-using NzbDrone.Core.Parser;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Download;
@@ -106,7 +104,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
if (newDownload)
{
episodeFile.OriginalFilePath = GetOriginalFilePath(downloadClientItem, localEpisode);
- episodeFile.SceneName = GetSceneName(downloadClientItem, localEpisode);
var moveResult = _episodeFileUpgrader.UpgradeEpisodeFile(episodeFile, localEpisode, copyOnly);
oldFiles = moveResult.OldFiles;
@@ -196,38 +193,5 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
return Path.GetFileName(path);
}
-
- private string GetSceneName(DownloadClientItem downloadClientItem, LocalEpisode localEpisode)
- {
- if (downloadClientItem != null)
- {
- var title = Parser.Parser.RemoveFileExtension(downloadClientItem.Title);
-
- var parsedTitle = Parser.Parser.ParseTitle(title);
-
- if (parsedTitle != null && !parsedTitle.FullSeason)
- {
- return title;
- }
- }
-
- var fileName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath());
-
- if (SceneChecker.IsSceneTitle(fileName))
- {
- return fileName;
- }
-
- var folderTitle = localEpisode.FolderEpisodeInfo?.ReleaseTitle;
-
- if (localEpisode.FolderEpisodeInfo?.FullSeason == false &&
- folderTitle.IsNotNullOrWhiteSpace() &&
- SceneChecker.IsSceneTitle(folderTitle))
- {
- return folderTitle;
- }
-
- return null;
- }
}
}
diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/SceneNameCalculator.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/SceneNameCalculator.cs
new file mode 100644
index 000000000..e91e0b559
--- /dev/null
+++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/SceneNameCalculator.cs
@@ -0,0 +1,39 @@
+using System.IO;
+using NzbDrone.Common.Extensions;
+using NzbDrone.Core.Parser;
+using NzbDrone.Core.Parser.Model;
+
+namespace NzbDrone.Core.MediaFiles.EpisodeImport
+{
+ public static class SceneNameCalculator
+ {
+ public static string GetSceneName(LocalEpisode localEpisode)
+ {
+ var downloadClientInfo = localEpisode.DownloadClientEpisodeInfo;
+
+ if (downloadClientInfo != null && !downloadClientInfo.FullSeason)
+ {
+ return Parser.Parser.RemoveFileExtension(downloadClientInfo.ReleaseTitle);
+ }
+
+ var fileName = Path.GetFileNameWithoutExtension(localEpisode.Path.CleanFilePath());
+
+ if (SceneChecker.IsSceneTitle(fileName))
+ {
+ return fileName;
+ }
+
+ var folderTitle = localEpisode.FolderEpisodeInfo?.ReleaseTitle;
+
+ if (!otherVideoFiles &&
+ localEpisode.FolderEpisodeInfo?.FullSeason == false &&
+ folderTitle.IsNotNullOrWhiteSpace() &&
+ SceneChecker.IsSceneTitle(folderTitle))
+ {
+ return folderTitle;
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs
index 6b6508617..88affb5a1 100644
--- a/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs
+++ b/src/NzbDrone.Core/MediaFiles/EpisodeImport/Specifications/UpgradeSpecification.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System.Linq;
+using System.Linq;
using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine;
@@ -14,7 +13,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
public class UpgradeSpecification : IImportDecisionEngineSpecification
{
private readonly IConfigService _configService;
- private readonly IPreferredWordService _preferredWordService;
private readonly IEpisodeFilePreferredWordCalculator _episodeFilePreferredWordCalculator;
private readonly Logger _logger;
@@ -24,7 +22,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
Logger logger)
{
_configService = configService;
- _preferredWordService = preferredWordService;
_episodeFilePreferredWordCalculator = episodeFilePreferredWordCalculator;
_logger = logger;
}
@@ -34,7 +31,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
var downloadPropersAndRepacks = _configService.DownloadPropersAndRepacks;
var qualityComparer = new QualityModelComparer(localEpisode.Series.QualityProfile);
var languageComparer = new LanguageComparer(localEpisode.Series.LanguageProfile);
- var preferredWordScore = GetPreferredWordScore(localEpisode);
+ var preferredWordScore = localEpisode.PreferredWordScore;
foreach (var episode in localEpisode.Episodes.Where(e => e.EpisodeFileId > 0))
{
@@ -85,28 +82,5 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
return Decision.Accept();
}
-
- private int GetPreferredWordScore(LocalEpisode localEpisode)
- {
- var series = localEpisode.Series;
- var scores = new List();
-
- if (localEpisode.FileEpisodeInfo != null)
- {
- scores.Add(_preferredWordService.Calculate(series, localEpisode.FileEpisodeInfo.ReleaseTitle, 0));
- }
-
- if (localEpisode.FolderEpisodeInfo != null)
- {
- scores.Add(_preferredWordService.Calculate(series, localEpisode.FolderEpisodeInfo.ReleaseTitle, 0));
- }
-
- if (localEpisode.DownloadClientEpisodeInfo != null)
- {
- scores.Add(_preferredWordService.Calculate(series, localEpisode.DownloadClientEpisodeInfo.ReleaseTitle, 0));
- }
-
- return scores.MaxOrDefault();
- }
}
}
diff --git a/src/NzbDrone.Core/Parser/Model/LocalEpisode.cs b/src/NzbDrone.Core/Parser/Model/LocalEpisode.cs
index 4e05abec9..8df57e3a6 100644
--- a/src/NzbDrone.Core/Parser/Model/LocalEpisode.cs
+++ b/src/NzbDrone.Core/Parser/Model/LocalEpisode.cs
@@ -28,7 +28,9 @@ namespace NzbDrone.Core.Parser.Model
public bool ExistingFile { get; set; }
public bool SceneSource { get; set; }
public string ReleaseGroup { get; set; }
-
+ public string SceneName { get; set; }
+ public int PreferredWordScore { get; set; }
+
public int SeasonNumber
{
get