mirror of https://github.com/Sonarr/Sonarr
New: Store and use original Series language
This commit is contained in:
parent
5400bce129
commit
be0fa73129
|
@ -11,7 +11,22 @@ function createMapStateToProps() {
|
|||
return createSelector(
|
||||
createLanguagesSelector(),
|
||||
(languages) => {
|
||||
return languages;
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items
|
||||
} = languages;
|
||||
|
||||
const filterItems = ['Any', 'Original'];
|
||||
const filteredLanguages = items.filter((lang) => !filterItems.includes(lang.name));
|
||||
|
||||
return {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
items: filteredLanguages
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,15 @@ function SeriesIndexSortMenu(props) {
|
|||
Network
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
name="originalLanguage"
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
onPress={onSortSelect}
|
||||
>
|
||||
Original Language
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
name="qualityProfileId"
|
||||
sortKey={sortKey}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
flex: 2 0 90px;
|
||||
}
|
||||
|
||||
.originalLanguage,
|
||||
.qualityProfileId {
|
||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
flex: 2 0 90px;
|
||||
}
|
||||
|
||||
.originalLanguage,
|
||||
.qualityProfileId {
|
||||
composes: cell;
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ class SeriesIndexRow extends Component {
|
|||
titleSlug,
|
||||
seriesType,
|
||||
network,
|
||||
originalLanguage,
|
||||
qualityProfile,
|
||||
nextAiring,
|
||||
previousAiring,
|
||||
|
@ -212,6 +213,17 @@ class SeriesIndexRow extends Component {
|
|||
);
|
||||
}
|
||||
|
||||
if (name === 'originalLanguage') {
|
||||
return (
|
||||
<VirtualTableRowCell
|
||||
key={name}
|
||||
className={styles[name]}
|
||||
>
|
||||
{originalLanguage.name}
|
||||
</VirtualTableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'qualityProfileId') {
|
||||
return (
|
||||
<VirtualTableRowCell
|
||||
|
@ -511,6 +523,7 @@ SeriesIndexRow.propTypes = {
|
|||
title: PropTypes.string.isRequired,
|
||||
titleSlug: PropTypes.string.isRequired,
|
||||
seriesType: PropTypes.string.isRequired,
|
||||
originalLanguage: PropTypes.object.isRequired,
|
||||
network: PropTypes.string,
|
||||
qualityProfile: PropTypes.object.isRequired,
|
||||
nextAiring: PropTypes.string,
|
||||
|
|
|
@ -131,6 +131,13 @@ export const filterPredicates = {
|
|||
return predicate(item.ratings.value * 10, filterValue);
|
||||
},
|
||||
|
||||
originalLanguage: function(item, filterValue, type) {
|
||||
const predicate = filterTypePredicates[type];
|
||||
const { originalLanguage } = item;
|
||||
|
||||
return predicate(originalLanguage ? originalLanguage.name : '', filterValue);
|
||||
},
|
||||
|
||||
releaseGroups: function(item, filterValue, type) {
|
||||
const { statistics = {} } = item;
|
||||
|
||||
|
@ -267,6 +274,25 @@ export const filterBuilderProps = [
|
|||
return tagList.sort(sortByName);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'originalLanguage',
|
||||
label: 'Original Language',
|
||||
type: filterBuilderTypes.EXACT,
|
||||
optionsSelector: function(items) {
|
||||
const languageList = items.reduce((acc, series) => {
|
||||
if (series.originalLanguage) {
|
||||
acc.push({
|
||||
id: series.originalLanguage.name,
|
||||
name: series.originalLanguage.name
|
||||
});
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
return languageList.sort(sortByName);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'releaseGroups',
|
||||
label: 'Release Groups',
|
||||
|
|
|
@ -95,6 +95,12 @@ export const defaultState = {
|
|||
isSortable: true,
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'originalLanguage',
|
||||
label: 'Original Language',
|
||||
isSortable: true,
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'added',
|
||||
label: 'Added',
|
||||
|
@ -249,6 +255,12 @@ export const defaultState = {
|
|||
return statistics.seasonCount;
|
||||
},
|
||||
|
||||
originalLanguage: function(item) {
|
||||
const { originalLanguage = {} } = item;
|
||||
|
||||
return originalLanguage.name;
|
||||
},
|
||||
|
||||
ratings: function(item) {
|
||||
const { ratings = {} } = item;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
|||
public class AggregateLanguageFixture : CoreTest<AggregateLanguage>
|
||||
{
|
||||
private LocalEpisode _localEpisode;
|
||||
private Series _series;
|
||||
private string _simpleReleaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
||||
|
||||
[SetUp]
|
||||
|
@ -26,11 +27,16 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
|||
var episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
.BuildList();
|
||||
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(m => m.OriginalLanguage = Language.English)
|
||||
.Build();
|
||||
|
||||
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||
.With(l => l.DownloadClientEpisodeInfo = null)
|
||||
.With(l => l.FolderEpisodeInfo = null)
|
||||
.With(l => l.FileEpisodeInfo = null)
|
||||
.With(l => l.Episodes = episodes)
|
||||
.With(l => l.Series = _series)
|
||||
.Build();
|
||||
}
|
||||
|
||||
|
@ -72,7 +78,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
|||
{
|
||||
var result = Subject.Aggregate(_localEpisode, null);
|
||||
|
||||
result.Languages.Should().Contain(Language.English);
|
||||
result.Languages.Should().Contain(_series.OriginalLanguage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -120,13 +126,13 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
|||
[Test]
|
||||
public void should_return_file_language_when_file_language_is_higher_than_others()
|
||||
{
|
||||
_localEpisode.DownloadClientEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.English }, _simpleReleaseTitle);
|
||||
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.English }, _simpleReleaseTitle);
|
||||
_localEpisode.DownloadClientEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Unknown }, _simpleReleaseTitle);
|
||||
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Unknown }, _simpleReleaseTitle);
|
||||
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.French }, _simpleReleaseTitle);
|
||||
|
||||
GivenAugmenters(new List<Language> { Language.French },
|
||||
new List<Language> { Language.English },
|
||||
new List<Language> { Language.English },
|
||||
new List<Language> { Language.Unknown },
|
||||
new List<Language> { Language.Unknown },
|
||||
null);
|
||||
|
||||
Subject.Aggregate(_localEpisode, null).Languages.Should().Contain(_localEpisode.FileEpisodeInfo.Languages);
|
||||
|
@ -135,9 +141,9 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
|||
[Test]
|
||||
public void should_return_multi_language()
|
||||
{
|
||||
GivenAugmenters(new List<Language> { Language.English },
|
||||
GivenAugmenters(new List<Language> { Language.Unknown },
|
||||
new List<Language> { Language.French, Language.German },
|
||||
new List<Language> { Language.English },
|
||||
new List<Language> { Language.Unknown },
|
||||
null);
|
||||
|
||||
Subject.Aggregate(_localEpisode, null).Languages.Should().Equal(new List<Language> { Language.French, Language.German });
|
||||
|
|
|
@ -260,46 +260,6 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
|
|||
Subject.IsSatisfiedBy(_localEpisode, null).Accepted.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_it_is_a_preferred_word_downgrade_and_equal_language_and_quality()
|
||||
{
|
||||
var lowFormat = new List<CustomFormat> { new CustomFormat("Bad Format", new ResolutionSpecification { Value = (int)Resolution.R1080p }) { Id = 2 } };
|
||||
|
||||
CustomFormatsFixture.GivenCustomFormats(lowFormat.First());
|
||||
|
||||
_series.QualityProfile.Value.FormatItems = CustomFormatsFixture.GetSampleFormatItems();
|
||||
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotPrefer);
|
||||
|
||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||
.Setup(s => s.ParseCustomFormat(It.IsAny<EpisodeFile>()))
|
||||
.Returns(new List<CustomFormat>());
|
||||
|
||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||
.Setup(s => s.ParseCustomFormat(It.IsAny<ParsedEpisodeInfo>()))
|
||||
.Returns(lowFormat);
|
||||
|
||||
_localEpisode.Quality = new QualityModel(Quality.Bluray1080p);
|
||||
|
||||
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(e => e.EpisodeFileId = 1)
|
||||
.With(e => e.EpisodeFile = new LazyLoaded<EpisodeFile>(
|
||||
new EpisodeFile
|
||||
{
|
||||
Quality = new QualityModel(Quality.Bluray1080p),
|
||||
Languages = new List<Language> { Language.Spanish }
|
||||
}))
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
_localEpisode.FileEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew().Build();
|
||||
|
||||
Subject.IsSatisfiedBy(_localEpisode, null).Accepted.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_if_it_is_a_preferred_word_downgrade_and_language_downgrade_and_a_quality_upgrade()
|
||||
{
|
||||
|
|
|
@ -11,21 +11,27 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
public class LanguageParserFixture : CoreTest
|
||||
{
|
||||
[TestCase("Title.the.Series.2009.S01E14.English.HDTV.XviD-LOL")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.English.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.english.sub")]
|
||||
public void should_parse_language_english(string postTitle)
|
||||
{
|
||||
var result = LanguageParser.ParseLanguages(postTitle);
|
||||
result.First().Should().Be(Language.English);
|
||||
}
|
||||
|
||||
[TestCase("Spanish Killroy was Here S02E02 Flodden 720p AMZN WEB-DL DDP5 1 H 264-NTb")]
|
||||
[TestCase("Title.the.Spanish.Series.S02E02.1080p.WEB.H264-CAKES")]
|
||||
[TestCase("Title.the.Spanish.Series.S02E06.Field.of.Cloth.of.Gold.1080p.AMZN.WEBRip.DDP5.1.x264-NTb")]
|
||||
[TestCase("Title.the.Series.2009.S01E14.Germany.HDTV.XviD-LOL")]
|
||||
[TestCase("Title.the.Series.2009.S01E14.HDTV.XviD-LOL")]
|
||||
[TestCase("Title.the.Italian.Series.S01E01.The.Family.720p.HDTV.x264-FTP")]
|
||||
[TestCase("Title.the.Italy.Series.S02E01.720p.HDTV.x264-TLA")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.en.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.eng.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.English.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.english.sub")]
|
||||
[TestCase("Spanish Killroy was Here S02E02 Flodden 720p AMZN WEB-DL DDP5 1 H 264-NTb")]
|
||||
[TestCase("Title.the.Spanish.Series.S02E02.1080p.WEB.H264-CAKES")]
|
||||
[TestCase("Title.the.Spanish.Series.S02E06.Field.of.Cloth.of.Gold.1080p.AMZN.WEBRip.DDP5.1.x264-NTb")]
|
||||
public void should_parse_language_english(string postTitle)
|
||||
public void should_parse_language_unknown(string postTitle)
|
||||
{
|
||||
var result = LanguageParser.ParseLanguages(postTitle);
|
||||
result.First().Should().Be(Language.English);
|
||||
result.First().Should().Be(Language.Unknown);
|
||||
}
|
||||
|
||||
[TestCase("Series Title - S01E01 - Pilot.sub")]
|
||||
|
@ -314,7 +320,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
public void should_not_parse_series_or_episode_title(string postTitle)
|
||||
{
|
||||
var result = LanguageParser.ParseLanguages(postTitle);
|
||||
result.First().Name.Should().Be(Language.English.Name);
|
||||
result.First().Name.Should().Be(Language.Unknown.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
@ -41,7 +42,8 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
SeriesTitle = _series.Title,
|
||||
SeasonNumber = 1,
|
||||
EpisodeNumbers = new[] { 1 },
|
||||
AbsoluteEpisodeNumbers = new int[0]
|
||||
AbsoluteEpisodeNumbers = new int[0],
|
||||
Languages = new List<Language> { Language.English }
|
||||
};
|
||||
|
||||
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
|
@ -7,6 +7,7 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
@ -41,7 +42,8 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
SeriesTitle = _series.Title,
|
||||
SeriesTitleInfo = new SeriesTitleInfo(),
|
||||
SeasonNumber = 1,
|
||||
EpisodeNumbers = new[] { 1 }
|
||||
EpisodeNumbers = new[] { 1 },
|
||||
Languages = new List<Language> { Language.English }
|
||||
};
|
||||
|
||||
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
||||
|
|
|
@ -84,7 +84,8 @@ namespace NzbDrone.Core.CustomFormats
|
|||
ExtraInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "Size", episodeFile.Size },
|
||||
{ "Filename", Path.GetFileName(episodeFile.RelativePath) }
|
||||
{ "Filename", Path.GetFileName(episodeFile.RelativePath) },
|
||||
{ "OriginalLanguage", episodeFile.Series.Value.OriginalLanguage }
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,11 @@ namespace NzbDrone.Core.CustomFormats
|
|||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedEpisodeInfo episodeInfo)
|
||||
{
|
||||
return episodeInfo?.Languages?.Contains((Language)Value) ?? false;
|
||||
var comparedLanguage = episodeInfo != null && Value == Language.Original.Id && episodeInfo.ExtraInfo.ContainsKey("OriginalLanguage")
|
||||
? (Language)episodeInfo.ExtraInfo["OriginalLanguage"]
|
||||
: (Language)Value;
|
||||
|
||||
return episodeInfo?.Languages?.Contains(comparedLanguage) ?? false;
|
||||
}
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Core.Languages;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(176)]
|
||||
public class original_language : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("Series")
|
||||
.AddColumn("OriginalLanguage").AsInt32().WithDefaultValue((int)Language.English);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,6 +102,7 @@ namespace NzbDrone.Core.Languages
|
|||
public static Language Malayalam => new Language(29, "Malayalam");
|
||||
public static Language Ukrainian => new Language(30, "Ukrainian");
|
||||
public static Language Slovak => new Language(31, "Slovak");
|
||||
public static Language Original => new Language(-2, "Original");
|
||||
|
||||
public static List<Language> All
|
||||
{
|
||||
|
@ -140,7 +141,8 @@ namespace NzbDrone.Core.Languages
|
|||
Bulgarian,
|
||||
Malayalam,
|
||||
Ukrainian,
|
||||
Slovak
|
||||
Slovak,
|
||||
Original
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
|||
|
||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
||||
{
|
||||
var languages = new List<Language> { Language.English };
|
||||
var languages = new List<Language> { localEpisode.Series?.OriginalLanguage ?? Language.Unknown };
|
||||
var languagesConfidence = Confidence.Default;
|
||||
|
||||
foreach (var augmentLanguage in _augmentLanguages)
|
||||
|
@ -37,7 +37,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
|||
|
||||
if (augmentedLanguage?.Languages != null &&
|
||||
augmentedLanguage.Languages.Count > 0 &&
|
||||
!(augmentedLanguage.Languages.Count == 1 && augmentedLanguage.Languages.Contains(Language.English)) &&
|
||||
!(augmentedLanguage.Languages.Count == 1 && augmentedLanguage.Languages.Contains(Language.Unknown)))
|
||||
{
|
||||
languages = augmentedLanguage.Languages;
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
|||
|
||||
foreach (var episode in localEpisode.Episodes)
|
||||
{
|
||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title, false);
|
||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title);
|
||||
|
||||
languages = languages.Except(episodeTitleLanguage).ToList();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
|||
|
||||
foreach (var episode in localEpisode.Episodes)
|
||||
{
|
||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title, false);
|
||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title);
|
||||
|
||||
languages = languages.Except(episodeTitleLanguage).ToList();
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
|||
|
||||
foreach (var episode in localEpisode.Episodes)
|
||||
{
|
||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title, false);
|
||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title);
|
||||
|
||||
languages = languages.Except(episodeTitleLanguage).ToList();
|
||||
}
|
||||
|
|
|
@ -139,6 +139,14 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
var rootFolder = Path.GetDirectoryName(path);
|
||||
var series = _seriesService.GetSeries(seriesId);
|
||||
|
||||
var languageParse = LanguageParser.ParseLanguages(path);
|
||||
|
||||
if (languageParse.Count <= 1 && languageParse.First() == Language.Unknown && series != null)
|
||||
{
|
||||
languageParse = new List<Language> { series.OriginalLanguage };
|
||||
_logger.Debug("Language couldn't be parsed from release, falling back to series original language: {0}", series.OriginalLanguage.Name);
|
||||
}
|
||||
|
||||
if (episodeIds.Any())
|
||||
{
|
||||
var downloadClientItem = GetTrackedDownload(downloadId)?.DownloadItem;
|
||||
|
@ -153,7 +161,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
|||
localEpisode.ExistingFile = series.Path.IsParentPath(path);
|
||||
localEpisode.Size = _diskProvider.GetFileSize(path);
|
||||
localEpisode.ReleaseGroup = releaseGroup.IsNullOrWhiteSpace() ? Parser.Parser.ParseReleaseGroup(path) : releaseGroup;
|
||||
localEpisode.Languages = (languages?.SingleOrDefault() ?? Language.Unknown) == Language.Unknown ? LanguageParser.ParseLanguages(path) : languages;
|
||||
localEpisode.Languages = (languages?.SingleOrDefault() ?? Language.Unknown) == Language.Unknown ? languageParse : languages;
|
||||
localEpisode.Quality = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality;
|
||||
|
||||
return MapItem(_importDecisionMaker.GetDecision(localEpisode, downloadClientItem), rootFolder, downloadId, null);
|
||||
|
|
|
@ -5,9 +5,7 @@ using NzbDrone.Core.Configuration;
|
|||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Profiles.Releases;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
|
||||
|
@ -43,7 +41,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
|
|||
}
|
||||
|
||||
var qualityCompare = qualityComparer.Compare(localEpisode.Quality.Quality, episodeFile.Quality.Quality);
|
||||
var customFormatScore = GetCustomFormatScore(localEpisode);
|
||||
|
||||
if (qualityCompare < 0)
|
||||
{
|
||||
|
@ -62,46 +59,9 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
|
|||
_logger.Debug("This file isn't a quality revision upgrade for all episodes. Skipping {0}", localEpisode.Path);
|
||||
return Decision.Reject("Not a quality revision upgrade for existing episode file(s)");
|
||||
}
|
||||
|
||||
var customFormats = _customFormatCalculationService.ParseCustomFormat(episodeFile);
|
||||
var episodeFileCustomFormatScore = localEpisode.Series.QualityProfile.Value.CalculateCustomFormatScore(customFormats);
|
||||
|
||||
if (qualityCompare == 0 && customFormatScore < episodeFileCustomFormatScore)
|
||||
{
|
||||
_logger.Debug("This file isn't a custom format upgrade for episode. Skipping {0}", localEpisode.Path);
|
||||
return Decision.Reject("Not a custom format upgrade for existing episode file(s)");
|
||||
}
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
private int GetCustomFormatScore(LocalEpisode localEpisode)
|
||||
{
|
||||
var series = localEpisode.Series;
|
||||
var scores = new List<int>();
|
||||
var fileFormats = new List<CustomFormat>();
|
||||
var folderFormats = new List<CustomFormat>();
|
||||
var clientFormats = new List<CustomFormat>();
|
||||
|
||||
if (localEpisode.FileEpisodeInfo != null)
|
||||
{
|
||||
fileFormats = _customFormatCalculationService.ParseCustomFormat(localEpisode.FileEpisodeInfo);
|
||||
}
|
||||
|
||||
if (localEpisode.FolderEpisodeInfo != null)
|
||||
{
|
||||
folderFormats = _customFormatCalculationService.ParseCustomFormat(localEpisode.FolderEpisodeInfo);
|
||||
}
|
||||
|
||||
if (localEpisode.DownloadClientEpisodeInfo != null)
|
||||
{
|
||||
clientFormats = _customFormatCalculationService.ParseCustomFormat(localEpisode.DownloadClientEpisodeInfo);
|
||||
}
|
||||
|
||||
var formats = fileFormats.Union(folderFormats.Union(clientFormats)).ToList();
|
||||
|
||||
return series.QualityProfile.Value.CalculateCustomFormatScore(formats);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||
{
|
||||
|
@ -29,6 +29,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|||
|
||||
public string Network { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public string OriginalLanguage { get; set; }
|
||||
|
||||
public List<ActorResource> Actors { get; set; }
|
||||
public List<string> Genres { get; set; }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
@ -9,8 +9,10 @@ using NzbDrone.Common.Extensions;
|
|||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.DataAugmentation.DailySeries;
|
||||
using NzbDrone.Core.Exceptions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||
|
@ -158,6 +160,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
series.CleanTitle = Parser.Parser.CleanSeriesTitle(show.Title);
|
||||
series.SortTitle = SeriesTitleNormalizer.Normalize(show.Title, show.TvdbId);
|
||||
|
||||
series.OriginalLanguage = IsoLanguages.Find(show.OriginalLanguage.ToLower())?.Language ?? Language.English;
|
||||
|
||||
if (show.FirstAired != null)
|
||||
{
|
||||
series.FirstAired = DateTime.ParseExact(show.FirstAired, "yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
private static readonly Regex SubtitleLanguageRegex = new Regex(".+?[-_. ](?<iso_code>[a-z]{2,3})([-_. ](?<tags>full|forced|foreign|default|cc|psdh|sdh))*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
public static List<Language> ParseLanguages(string title, bool defaultToEnglish = true)
|
||||
public static List<Language> ParseLanguages(string title)
|
||||
{
|
||||
foreach (var regex in CleanSeriesTitleRegex)
|
||||
{
|
||||
|
@ -175,7 +175,7 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
if (!languages.Any())
|
||||
{
|
||||
languages.Add(defaultToEnglish ? Language.English : Language.Unknown);
|
||||
languages.Add(Language.Unknown);
|
||||
}
|
||||
|
||||
return languages.DistinctBy(l => (int)l).ToList();
|
||||
|
|
|
@ -6,6 +6,8 @@ using NzbDrone.Common.Extensions;
|
|||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
|
@ -182,6 +184,29 @@ namespace NzbDrone.Core.Parser
|
|||
{
|
||||
remoteEpisode.Episodes = GetEpisodes(parsedEpisodeInfo, series, remoteEpisode.MappedSeasonNumber, sceneSource, searchCriteria);
|
||||
}
|
||||
|
||||
parsedEpisodeInfo.ExtraInfo["OriginalLanguage"] = series.OriginalLanguage;
|
||||
}
|
||||
|
||||
// Use series language as fallback if we could't parse a language (more accurate than just using English)
|
||||
if (parsedEpisodeInfo.Languages.Count <= 1 && parsedEpisodeInfo.Languages.First() == Language.Unknown && series != null)
|
||||
{
|
||||
parsedEpisodeInfo.Languages = new List<Language> { series.OriginalLanguage };
|
||||
_logger.Debug("Language couldn't be parsed from release, fallback to series original language: {0}", series.OriginalLanguage.Name);
|
||||
}
|
||||
|
||||
if (parsedEpisodeInfo.Languages.Contains(Language.Original))
|
||||
{
|
||||
parsedEpisodeInfo.Languages.Remove(Language.Original);
|
||||
|
||||
if (series != null && !parsedEpisodeInfo.Languages.Contains(series.OriginalLanguage))
|
||||
{
|
||||
parsedEpisodeInfo.Languages.Add(series.OriginalLanguage);
|
||||
}
|
||||
else
|
||||
{
|
||||
parsedEpisodeInfo.Languages.Add(Language.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
if (remoteEpisode.Episodes == null)
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace NzbDrone.Core.Tv
|
|||
series.ImdbId = seriesInfo.ImdbId;
|
||||
series.AirTime = seriesInfo.AirTime;
|
||||
series.Overview = seriesInfo.Overview;
|
||||
series.OriginalLanguage = seriesInfo.OriginalLanguage;
|
||||
series.Status = seriesInfo.Status;
|
||||
series.CleanTitle = seriesInfo.CleanTitle;
|
||||
series.SortTitle = seriesInfo.SortTitle;
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Profiles.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.Tv
|
||||
|
@ -15,6 +16,7 @@ namespace NzbDrone.Core.Tv
|
|||
Actors = new List<Actor>();
|
||||
Seasons = new List<Season>();
|
||||
Tags = new HashSet<int>();
|
||||
OriginalLanguage = Language.English;
|
||||
}
|
||||
|
||||
public int TvdbId { get; set; }
|
||||
|
@ -47,6 +49,7 @@ namespace NzbDrone.Core.Tv
|
|||
public DateTime Added { get; set; }
|
||||
public DateTime? FirstAired { get; set; }
|
||||
public LazyLoaded<QualityProfile> QualityProfile { get; set; }
|
||||
public Language OriginalLanguage { get; set; }
|
||||
|
||||
public List<Season> Seasons { get; set; }
|
||||
public HashSet<int> Tags { get; set; }
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaCover;
|
||||
using NzbDrone.Core.Tv;
|
||||
using Sonarr.Http.REST;
|
||||
|
@ -30,7 +31,7 @@ namespace Sonarr.Api.V3.Series
|
|||
public string Network { get; set; }
|
||||
public string AirTime { get; set; }
|
||||
public List<MediaCover> Images { get; set; }
|
||||
|
||||
public Language OriginalLanguage { get; set; }
|
||||
public string RemotePoster { get; set; }
|
||||
public List<SeasonResource> Seasons { get; set; }
|
||||
public int Year { get; set; }
|
||||
|
@ -100,6 +101,7 @@ namespace Sonarr.Api.V3.Series
|
|||
|
||||
Seasons = model.Seasons.ToResource(includeSeasonImages),
|
||||
Year = model.Year,
|
||||
OriginalLanguage = model.OriginalLanguage,
|
||||
|
||||
Path = model.Path,
|
||||
QualityProfileId = model.QualityProfileId,
|
||||
|
@ -161,6 +163,7 @@ namespace Sonarr.Api.V3.Series
|
|||
|
||||
Seasons = resource.Seasons?.ToModel() ?? new List<Season>(),
|
||||
Year = resource.Year,
|
||||
OriginalLanguage = resource.OriginalLanguage,
|
||||
|
||||
Path = resource.Path,
|
||||
QualityProfileId = resource.QualityProfileId,
|
||||
|
|
Loading…
Reference in New Issue