mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-14 11:23:42 +02:00
New: Show preferred word score in history
This commit is contained in:
parent
d898f55660
commit
8876c9194d
@ -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 &&
|
||||
<DescriptionListItem
|
||||
title="Preferred Word Score"
|
||||
data={formatPreferredWordScore(preferredWordScore)}
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
!!nzbInfoUrl &&
|
||||
<span>
|
||||
@ -86,7 +96,7 @@ function HistoryDetails(props) {
|
||||
}
|
||||
|
||||
{
|
||||
!!indexer &&
|
||||
!!(age || ageHours || ageMinutes) &&
|
||||
<DescriptionListItem
|
||||
title="Age (when grabbed)"
|
||||
data={formatAge(age, ageHours, ageMinutes)}
|
||||
@ -130,6 +140,7 @@ function HistoryDetails(props) {
|
||||
|
||||
if (eventType === 'downloadFolderImported') {
|
||||
const {
|
||||
preferredWordScore,
|
||||
droppedPath,
|
||||
importedPath
|
||||
} = data;
|
||||
@ -159,13 +170,22 @@ function HistoryDetails(props) {
|
||||
data={importedPath}
|
||||
/>
|
||||
}
|
||||
|
||||
{
|
||||
!!preferredWordScore &&
|
||||
<DescriptionListItem
|
||||
title="Preferred Word Score"
|
||||
data={formatPreferredWordScore(preferredWordScore)}
|
||||
/>
|
||||
}
|
||||
</DescriptionList>
|
||||
);
|
||||
}
|
||||
|
||||
if (eventType === 'episodeFileDeleted') {
|
||||
const {
|
||||
reason
|
||||
reason,
|
||||
preferredWordScore
|
||||
} = data;
|
||||
|
||||
let reasonMessage = '';
|
||||
@ -195,6 +215,14 @@ function HistoryDetails(props) {
|
||||
title="Reason"
|
||||
data={reasonMessage}
|
||||
/>
|
||||
|
||||
{
|
||||
!!preferredWordScore &&
|
||||
<DescriptionListItem
|
||||
title="Preferred Word Score"
|
||||
data={formatPreferredWordScore(preferredWordScore)}
|
||||
/>
|
||||
}
|
||||
</DescriptionList>
|
||||
);
|
||||
}
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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 (
|
||||
<TableRowCell
|
||||
key={name}
|
||||
className={styles.preferredWordScore}
|
||||
>
|
||||
{formatPreferredWordScore(data.preferredWordScore)}
|
||||
</TableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'releaseGroup') {
|
||||
return (
|
||||
<TableRowCell
|
||||
|
@ -191,7 +191,7 @@ class TableOptionsModal extends Component {
|
||||
<TableOptionsColumnDragSource
|
||||
key={name}
|
||||
name={name}
|
||||
label={label || columnLabel}
|
||||
label={columnLabel || label}
|
||||
isVisible={isVisible}
|
||||
isModifiable={true}
|
||||
index={index}
|
||||
@ -209,7 +209,7 @@ class TableOptionsModal extends Component {
|
||||
<TableOptionsColumn
|
||||
key={name}
|
||||
name={name}
|
||||
label={label || columnLabel}
|
||||
label={columnLabel || label}
|
||||
isVisible={isVisible}
|
||||
index={index}
|
||||
isModifiable={false}
|
||||
|
@ -3,6 +3,7 @@ import React, { Component } from 'react';
|
||||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||
import formatAge from 'Utilities/Number/formatAge';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import formatPreferredWordScore from 'Utilities/Number/formatPreferredWordScore';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import Icon from 'Components/Icon';
|
||||
import SpinnerIconButton from 'Components/Link/SpinnerIconButton';
|
||||
@ -193,8 +194,7 @@ class InteractiveSearchRow extends Component {
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.preferredWordScore}>
|
||||
{preferredWordScore > 0 && `+${preferredWordScore}`}
|
||||
{preferredWordScore < 0 && preferredWordScore}
|
||||
{formatPreferredWordScore(preferredWordScore)}
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.rejected}>
|
||||
|
@ -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',
|
||||
|
16
frontend/src/Utilities/Number/formatPreferredWordScore.js
Normal file
16
frontend/src/Utilities/Number/formatPreferredWordScore.js
Normal file
@ -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;
|
@ -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<Series>.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<Episode>.CreateNew()
|
||||
.Build();
|
||||
|
||||
_localEpisode = new LocalEpisode
|
||||
{
|
||||
Series = series,
|
||||
Episodes = new List<Episode> {episode},
|
||||
Path = Path.Combine(series.Path, "Series Title - S02E23 - Episode Title.mkv"),
|
||||
Quality = new QualityModel(Quality.Bluray720p),
|
||||
ReleaseGroup = "DRONE"
|
||||
};
|
||||
}
|
||||
|
||||
private void GivenExistingFileOnDisk()
|
||||
{
|
||||
Mocker.GetMock<IMediaFileService>()
|
||||
.Setup(s => s.GetFilesWithRelativePath(It.IsAny<int>(), It.IsAny<string>()))
|
||||
.Returns(new List<EpisodeFile>());
|
||||
}
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
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<ImportApprovedEpisodes>
|
||||
@ -169,112 +169,6 @@ public void should_not_move_existing_files()
|
||||
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<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(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<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(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<ImportDecision> { _approvedDecisions.First() }, true, _downloadClientItem);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(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<ImportDecision> { _approvedDecisions.First() }, true);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(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<ImportDecision> { _approvedDecisions.First() }, true);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(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<ImportDecision> { _approvedDecisions.First() }, true);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(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<ImportDecision> { _approvedDecisions.First() }, true);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(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<ImportDecision> { _approvedDecisions.First() }, true);
|
||||
|
||||
Mocker.GetMock<IMediaFileService>().Verify(v => v.Add(It.Is<EpisodeFile>(c => c.SceneName == null)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_import_larger_files_first()
|
||||
{
|
@ -287,14 +287,11 @@ public void should_return_false_if_it_is_not_a_preferred_word_upgrade()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotPrefer);
|
||||
|
||||
Mocker.GetMock<IPreferredWordService>()
|
||||
.Setup(s => s.Calculate(It.IsAny<Series>(), It.IsAny<string>(), 0))
|
||||
.Returns(5);
|
||||
|
||||
Mocker.GetMock<IEpisodeFilePreferredWordCalculator>()
|
||||
.Setup(s => s.Calculate(It.IsAny<Series>(), It.IsAny<EpisodeFile>()))
|
||||
.Returns(10);
|
||||
|
||||
_localEpisode.PreferredWordScore = 5;
|
||||
_localEpisode.Quality = new QualityModel(Quality.Bluray1080p);
|
||||
|
||||
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
@ -364,14 +361,11 @@ public void should_return_true_if_it_is_a_preferred_word_upgrade()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotPrefer);
|
||||
|
||||
Mocker.GetMock<IPreferredWordService>()
|
||||
.Setup(s => s.Calculate(It.IsAny<Series>(), It.IsAny<string>(), 0))
|
||||
.Returns(5);
|
||||
|
||||
Mocker.GetMock<IEpisodeFilePreferredWordCalculator>()
|
||||
.Setup(s => s.Calculate(It.IsAny<Series>(), It.IsAny<EpisodeFile>()))
|
||||
.Returns(1);
|
||||
|
||||
_localEpisode.PreferredWordScore = 5;
|
||||
_localEpisode.Quality = new QualityModel(Quality.Bluray1080p);
|
||||
|
||||
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
@ -397,14 +391,11 @@ public void should_return_true_if_it_has_an_equal_preferred_word_score()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotPrefer);
|
||||
|
||||
Mocker.GetMock<IPreferredWordService>()
|
||||
.Setup(s => s.Calculate(It.IsAny<Series>(), It.IsAny<string>(), 0))
|
||||
.Returns(5);
|
||||
|
||||
Mocker.GetMock<IEpisodeFilePreferredWordCalculator>()
|
||||
.Setup(s => s.Calculate(It.IsAny<Series>(), It.IsAny<EpisodeFile>()))
|
||||
.Returns(5);
|
||||
|
||||
_localEpisode.PreferredWordScore = 5;
|
||||
_localEpisode.Quality = new QualityModel(Quality.Bluray1080p);
|
||||
|
||||
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
|
@ -26,9 +26,7 @@ public EpisodeHistory()
|
||||
public EpisodeHistoryEventType EventType { get; set; }
|
||||
public Dictionary<string, string> Data { get; set; }
|
||||
public Language Language { get; set; }
|
||||
|
||||
public string DownloadId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public enum EpisodeHistoryEventType
|
||||
|
@ -39,11 +39,13 @@ public class HistoryService : IHistoryService,
|
||||
IHandle<DownloadIgnoredEvent>
|
||||
{
|
||||
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 @@ public void Handle(EpisodeGrabbedEvent message)
|
||||
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 @@ public void Handle(EpisodeGrabbedEvent message)
|
||||
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 @@ public void Handle(EpisodeImportedEvent message)
|
||||
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 @@ public void Handle(EpisodeFileDeletedEvent message)
|
||||
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 @@ public void Handle(EpisodeFileDeletedEvent message)
|
||||
};
|
||||
|
||||
history.Data.Add("Reason", message.Reason.ToString());
|
||||
history.Data.Add("PreferredWordScore", episodeFilePreferredWordScore.ToString());
|
||||
|
||||
_historyRepository.Insert(history);
|
||||
}
|
||||
|
@ -3,10 +3,12 @@
|
||||
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 @@ public LocalEpisode Augment(LocalEpisode localEpisode, DownloadClientItem downlo
|
||||
}
|
||||
|
||||
localEpisode.Size = _diskProvider.GetFileSize(localEpisode.Path);
|
||||
localEpisode.SceneName = localEpisode.SceneSource ? SceneNameCalculator.GetSceneName(localEpisode) : null;
|
||||
|
||||
if (isMediaFile && (!localEpisode.ExistingFile || _configService.EnableMediaInfo))
|
||||
{
|
||||
|
@ -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<int>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,11 +4,9 @@
|
||||
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 @@ public List<ImportResult> Import(List<ImportDecision> decisions, bool newDownloa
|
||||
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 @@ private string GetOriginalFilePath(DownloadClientItem downloadClientItem, LocalE
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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 @@ public UpgradeSpecification(IConfigService configService,
|
||||
Logger logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_preferredWordService = preferredWordService;
|
||||
_episodeFilePreferredWordCalculator = episodeFilePreferredWordCalculator;
|
||||
_logger = logger;
|
||||
}
|
||||
@ -34,7 +31,7 @@ public Decision IsSatisfiedBy(LocalEpisode localEpisode, DownloadClientItem down
|
||||
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 @@ public Decision IsSatisfiedBy(LocalEpisode localEpisode, DownloadClientItem down
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
private int GetPreferredWordScore(LocalEpisode localEpisode)
|
||||
{
|
||||
var series = localEpisode.Series;
|
||||
var scores = new List<int>();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ public LocalEpisode()
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user