New: Store and use original Series language

This commit is contained in:
Qstick 2022-10-02 20:29:53 -05:00 committed by Mark McDowall
parent 5400bce129
commit be0fa73129
29 changed files with 193 additions and 113 deletions

View File

@ -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
};
}
);
}

View File

@ -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}

View File

@ -30,6 +30,7 @@
flex: 2 0 90px;
}
.originalLanguage,
.qualityProfileId {
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';

View File

@ -66,6 +66,7 @@
flex: 2 0 90px;
}
.originalLanguage,
.qualityProfileId {
composes: cell;

View File

@ -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,

View File

@ -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',

View File

@ -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;

View File

@ -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 });

View File

@ -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()
{

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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

View File

@ -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 }
}
};

View File

@ -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()

View File

@ -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);
}
}
}

View File

@ -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
};
}
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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; }

View File

@ -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);

View File

@ -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();

View File

@ -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)

View File

@ -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;

View File

@ -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; }

View File

@ -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,