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(
|
return createSelector(
|
||||||
createLanguagesSelector(),
|
createLanguagesSelector(),
|
||||||
(languages) => {
|
(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
|
Network
|
||||||
</SortMenuItem>
|
</SortMenuItem>
|
||||||
|
|
||||||
|
<SortMenuItem
|
||||||
|
name="originalLanguage"
|
||||||
|
sortKey={sortKey}
|
||||||
|
sortDirection={sortDirection}
|
||||||
|
onPress={onSortSelect}
|
||||||
|
>
|
||||||
|
Original Language
|
||||||
|
</SortMenuItem>
|
||||||
|
|
||||||
<SortMenuItem
|
<SortMenuItem
|
||||||
name="qualityProfileId"
|
name="qualityProfileId"
|
||||||
sortKey={sortKey}
|
sortKey={sortKey}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
flex: 2 0 90px;
|
flex: 2 0 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.originalLanguage,
|
||||||
.qualityProfileId {
|
.qualityProfileId {
|
||||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
flex: 2 0 90px;
|
flex: 2 0 90px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.originalLanguage,
|
||||||
.qualityProfileId {
|
.qualityProfileId {
|
||||||
composes: cell;
|
composes: cell;
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ class SeriesIndexRow extends Component {
|
||||||
titleSlug,
|
titleSlug,
|
||||||
seriesType,
|
seriesType,
|
||||||
network,
|
network,
|
||||||
|
originalLanguage,
|
||||||
qualityProfile,
|
qualityProfile,
|
||||||
nextAiring,
|
nextAiring,
|
||||||
previousAiring,
|
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') {
|
if (name === 'qualityProfileId') {
|
||||||
return (
|
return (
|
||||||
<VirtualTableRowCell
|
<VirtualTableRowCell
|
||||||
|
@ -511,6 +523,7 @@ SeriesIndexRow.propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
titleSlug: PropTypes.string.isRequired,
|
titleSlug: PropTypes.string.isRequired,
|
||||||
seriesType: PropTypes.string.isRequired,
|
seriesType: PropTypes.string.isRequired,
|
||||||
|
originalLanguage: PropTypes.object.isRequired,
|
||||||
network: PropTypes.string,
|
network: PropTypes.string,
|
||||||
qualityProfile: PropTypes.object.isRequired,
|
qualityProfile: PropTypes.object.isRequired,
|
||||||
nextAiring: PropTypes.string,
|
nextAiring: PropTypes.string,
|
||||||
|
|
|
@ -131,6 +131,13 @@ export const filterPredicates = {
|
||||||
return predicate(item.ratings.value * 10, filterValue);
|
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) {
|
releaseGroups: function(item, filterValue, type) {
|
||||||
const { statistics = {} } = item;
|
const { statistics = {} } = item;
|
||||||
|
|
||||||
|
@ -267,6 +274,25 @@ export const filterBuilderProps = [
|
||||||
return tagList.sort(sortByName);
|
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',
|
name: 'releaseGroups',
|
||||||
label: 'Release Groups',
|
label: 'Release Groups',
|
||||||
|
|
|
@ -95,6 +95,12 @@ export const defaultState = {
|
||||||
isSortable: true,
|
isSortable: true,
|
||||||
isVisible: false
|
isVisible: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'originalLanguage',
|
||||||
|
label: 'Original Language',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'added',
|
name: 'added',
|
||||||
label: 'Added',
|
label: 'Added',
|
||||||
|
@ -249,6 +255,12 @@ export const defaultState = {
|
||||||
return statistics.seasonCount;
|
return statistics.seasonCount;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
originalLanguage: function(item) {
|
||||||
|
const { originalLanguage = {} } = item;
|
||||||
|
|
||||||
|
return originalLanguage.name;
|
||||||
|
},
|
||||||
|
|
||||||
ratings: function(item) {
|
ratings: function(item) {
|
||||||
const { ratings = {} } = item;
|
const { ratings = {} } = item;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
public class AggregateLanguageFixture : CoreTest<AggregateLanguage>
|
public class AggregateLanguageFixture : CoreTest<AggregateLanguage>
|
||||||
{
|
{
|
||||||
private LocalEpisode _localEpisode;
|
private LocalEpisode _localEpisode;
|
||||||
|
private Series _series;
|
||||||
private string _simpleReleaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
private string _simpleReleaseTitle = "Series.Title.S01E01.xyz-RlsGroup";
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
|
@ -26,11 +27,16 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
var episodes = Builder<Episode>.CreateListOfSize(1)
|
var episodes = Builder<Episode>.CreateListOfSize(1)
|
||||||
.BuildList();
|
.BuildList();
|
||||||
|
|
||||||
|
_series = Builder<Series>.CreateNew()
|
||||||
|
.With(m => m.OriginalLanguage = Language.English)
|
||||||
|
.Build();
|
||||||
|
|
||||||
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||||
.With(l => l.DownloadClientEpisodeInfo = null)
|
.With(l => l.DownloadClientEpisodeInfo = null)
|
||||||
.With(l => l.FolderEpisodeInfo = null)
|
.With(l => l.FolderEpisodeInfo = null)
|
||||||
.With(l => l.FileEpisodeInfo = null)
|
.With(l => l.FileEpisodeInfo = null)
|
||||||
.With(l => l.Episodes = episodes)
|
.With(l => l.Episodes = episodes)
|
||||||
|
.With(l => l.Series = _series)
|
||||||
.Build();
|
.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +78,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
var result = Subject.Aggregate(_localEpisode, null);
|
var result = Subject.Aggregate(_localEpisode, null);
|
||||||
|
|
||||||
result.Languages.Should().Contain(Language.English);
|
result.Languages.Should().Contain(_series.OriginalLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -120,13 +126,13 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_file_language_when_file_language_is_higher_than_others()
|
public void should_return_file_language_when_file_language_is_higher_than_others()
|
||||||
{
|
{
|
||||||
_localEpisode.DownloadClientEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.English }, _simpleReleaseTitle);
|
_localEpisode.DownloadClientEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Unknown }, _simpleReleaseTitle);
|
||||||
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.English }, _simpleReleaseTitle);
|
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.Unknown }, _simpleReleaseTitle);
|
||||||
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.French }, _simpleReleaseTitle);
|
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.French }, _simpleReleaseTitle);
|
||||||
|
|
||||||
GivenAugmenters(new List<Language> { Language.French },
|
GivenAugmenters(new List<Language> { Language.French },
|
||||||
new List<Language> { Language.English },
|
new List<Language> { Language.Unknown },
|
||||||
new List<Language> { Language.English },
|
new List<Language> { Language.Unknown },
|
||||||
null);
|
null);
|
||||||
|
|
||||||
Subject.Aggregate(_localEpisode, null).Languages.Should().Contain(_localEpisode.FileEpisodeInfo.Languages);
|
Subject.Aggregate(_localEpisode, null).Languages.Should().Contain(_localEpisode.FileEpisodeInfo.Languages);
|
||||||
|
@ -135,9 +141,9 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
[Test]
|
[Test]
|
||||||
public void should_return_multi_language()
|
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.French, Language.German },
|
||||||
new List<Language> { Language.English },
|
new List<Language> { Language.Unknown },
|
||||||
null);
|
null);
|
||||||
|
|
||||||
Subject.Aggregate(_localEpisode, null).Languages.Should().Equal(new List<Language> { Language.French, Language.German });
|
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();
|
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]
|
[Test]
|
||||||
public void should_return_true_if_it_is_a_preferred_word_downgrade_and_language_downgrade_and_a_quality_upgrade()
|
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
|
public class LanguageParserFixture : CoreTest
|
||||||
{
|
{
|
||||||
[TestCase("Title.the.Series.2009.S01E14.English.HDTV.XviD-LOL")]
|
[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.Germany.HDTV.XviD-LOL")]
|
||||||
[TestCase("Title.the.Series.2009.S01E14.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.Italian.Series.S01E01.The.Family.720p.HDTV.x264-FTP")]
|
||||||
[TestCase("Title.the.Italy.Series.S02E01.720p.HDTV.x264-TLA")]
|
[TestCase("Title.the.Italy.Series.S02E01.720p.HDTV.x264-TLA")]
|
||||||
[TestCase("Series Title - S01E01 - Pilot.en.sub")]
|
[TestCase("Series Title - S01E01 - Pilot.en.sub")]
|
||||||
[TestCase("Series Title - S01E01 - Pilot.eng.sub")]
|
[TestCase("Series Title - S01E01 - Pilot.eng.sub")]
|
||||||
[TestCase("Series Title - S01E01 - Pilot.English.sub")]
|
public void should_parse_language_unknown(string postTitle)
|
||||||
[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)
|
|
||||||
{
|
{
|
||||||
var result = LanguageParser.ParseLanguages(postTitle);
|
var result = LanguageParser.ParseLanguages(postTitle);
|
||||||
result.First().Should().Be(Language.English);
|
result.First().Should().Be(Language.Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Series Title - S01E01 - Pilot.sub")]
|
[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)
|
public void should_not_parse_series_or_episode_title(string postTitle)
|
||||||
{
|
{
|
||||||
var result = LanguageParser.ParseLanguages(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 NUnit.Framework;
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -41,7 +42,8 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
SeriesTitle = _series.Title,
|
SeriesTitle = _series.Title,
|
||||||
SeasonNumber = 1,
|
SeasonNumber = 1,
|
||||||
EpisodeNumbers = new[] { 1 },
|
EpisodeNumbers = new[] { 1 },
|
||||||
AbsoluteEpisodeNumbers = new int[0]
|
AbsoluteEpisodeNumbers = new int[0],
|
||||||
|
Languages = new List<Language> { Language.English }
|
||||||
};
|
};
|
||||||
|
|
||||||
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
|
@ -7,6 +7,7 @@ using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -41,7 +42,8 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
SeriesTitle = _series.Title,
|
SeriesTitle = _series.Title,
|
||||||
SeriesTitleInfo = new SeriesTitleInfo(),
|
SeriesTitleInfo = new SeriesTitleInfo(),
|
||||||
SeasonNumber = 1,
|
SeasonNumber = 1,
|
||||||
EpisodeNumbers = new[] { 1 }
|
EpisodeNumbers = new[] { 1 },
|
||||||
|
Languages = new List<Language> { Language.English }
|
||||||
};
|
};
|
||||||
|
|
||||||
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
_singleEpisodeSearchCriteria = new SingleEpisodeSearchCriteria
|
||||||
|
|
|
@ -84,7 +84,8 @@ namespace NzbDrone.Core.CustomFormats
|
||||||
ExtraInfo = new Dictionary<string, object>
|
ExtraInfo = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "Size", episodeFile.Size },
|
{ "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)
|
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()
|
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 Malayalam => new Language(29, "Malayalam");
|
||||||
public static Language Ukrainian => new Language(30, "Ukrainian");
|
public static Language Ukrainian => new Language(30, "Ukrainian");
|
||||||
public static Language Slovak => new Language(31, "Slovak");
|
public static Language Slovak => new Language(31, "Slovak");
|
||||||
|
public static Language Original => new Language(-2, "Original");
|
||||||
|
|
||||||
public static List<Language> All
|
public static List<Language> All
|
||||||
{
|
{
|
||||||
|
@ -140,7 +141,8 @@ namespace NzbDrone.Core.Languages
|
||||||
Bulgarian,
|
Bulgarian,
|
||||||
Malayalam,
|
Malayalam,
|
||||||
Ukrainian,
|
Ukrainian,
|
||||||
Slovak
|
Slovak,
|
||||||
|
Original
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
|
|
||||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
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;
|
var languagesConfidence = Confidence.Default;
|
||||||
|
|
||||||
foreach (var augmentLanguage in _augmentLanguages)
|
foreach (var augmentLanguage in _augmentLanguages)
|
||||||
|
@ -37,7 +37,6 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
|
|
||||||
if (augmentedLanguage?.Languages != null &&
|
if (augmentedLanguage?.Languages != null &&
|
||||||
augmentedLanguage.Languages.Count > 0 &&
|
augmentedLanguage.Languages.Count > 0 &&
|
||||||
!(augmentedLanguage.Languages.Count == 1 && augmentedLanguage.Languages.Contains(Language.English)) &&
|
|
||||||
!(augmentedLanguage.Languages.Count == 1 && augmentedLanguage.Languages.Contains(Language.Unknown)))
|
!(augmentedLanguage.Languages.Count == 1 && augmentedLanguage.Languages.Contains(Language.Unknown)))
|
||||||
{
|
{
|
||||||
languages = augmentedLanguage.Languages;
|
languages = augmentedLanguage.Languages;
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
||||||
|
|
||||||
foreach (var episode in localEpisode.Episodes)
|
foreach (var episode in localEpisode.Episodes)
|
||||||
{
|
{
|
||||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title, false);
|
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title);
|
||||||
|
|
||||||
languages = languages.Except(episodeTitleLanguage).ToList();
|
languages = languages.Except(episodeTitleLanguage).ToList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
||||||
|
|
||||||
foreach (var episode in localEpisode.Episodes)
|
foreach (var episode in localEpisode.Episodes)
|
||||||
{
|
{
|
||||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title, false);
|
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title);
|
||||||
|
|
||||||
languages = languages.Except(episodeTitleLanguage).ToList();
|
languages = languages.Except(episodeTitleLanguage).ToList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
||||||
|
|
||||||
foreach (var episode in localEpisode.Episodes)
|
foreach (var episode in localEpisode.Episodes)
|
||||||
{
|
{
|
||||||
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title, false);
|
var episodeTitleLanguage = LanguageParser.ParseLanguages(episode.Title);
|
||||||
|
|
||||||
languages = languages.Except(episodeTitleLanguage).ToList();
|
languages = languages.Except(episodeTitleLanguage).ToList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,14 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
var rootFolder = Path.GetDirectoryName(path);
|
var rootFolder = Path.GetDirectoryName(path);
|
||||||
var series = _seriesService.GetSeries(seriesId);
|
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())
|
if (episodeIds.Any())
|
||||||
{
|
{
|
||||||
var downloadClientItem = GetTrackedDownload(downloadId)?.DownloadItem;
|
var downloadClientItem = GetTrackedDownload(downloadId)?.DownloadItem;
|
||||||
|
@ -153,7 +161,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
localEpisode.ExistingFile = series.Path.IsParentPath(path);
|
localEpisode.ExistingFile = series.Path.IsParentPath(path);
|
||||||
localEpisode.Size = _diskProvider.GetFileSize(path);
|
localEpisode.Size = _diskProvider.GetFileSize(path);
|
||||||
localEpisode.ReleaseGroup = releaseGroup.IsNullOrWhiteSpace() ? Parser.Parser.ParseReleaseGroup(path) : releaseGroup;
|
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;
|
localEpisode.Quality = quality.Quality == Quality.Unknown ? QualityParser.ParseQuality(path) : quality;
|
||||||
|
|
||||||
return MapItem(_importDecisionMaker.GetDecision(localEpisode, downloadClientItem), rootFolder, downloadId, null);
|
return MapItem(_importDecisionMaker.GetDecision(localEpisode, downloadClientItem), rootFolder, downloadId, null);
|
||||||
|
|
|
@ -5,9 +5,7 @@ using NzbDrone.Core.Configuration;
|
||||||
using NzbDrone.Core.CustomFormats;
|
using NzbDrone.Core.CustomFormats;
|
||||||
using NzbDrone.Core.DecisionEngine;
|
using NzbDrone.Core.DecisionEngine;
|
||||||
using NzbDrone.Core.Download;
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Languages;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Profiles.Releases;
|
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
|
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 qualityCompare = qualityComparer.Compare(localEpisode.Quality.Quality, episodeFile.Quality.Quality);
|
||||||
var customFormatScore = GetCustomFormatScore(localEpisode);
|
|
||||||
|
|
||||||
if (qualityCompare < 0)
|
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);
|
_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)");
|
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();
|
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
|
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||||
|
|
||||||
public string Network { get; set; }
|
public string Network { get; set; }
|
||||||
public string ImdbId { get; set; }
|
public string ImdbId { get; set; }
|
||||||
|
public string OriginalLanguage { get; set; }
|
||||||
|
|
||||||
public List<ActorResource> Actors { get; set; }
|
public List<ActorResource> Actors { get; set; }
|
||||||
public List<string> Genres { get; set; }
|
public List<string> Genres { get; set; }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -9,8 +9,10 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Http;
|
using NzbDrone.Common.Http;
|
||||||
using NzbDrone.Core.DataAugmentation.DailySeries;
|
using NzbDrone.Core.DataAugmentation.DailySeries;
|
||||||
using NzbDrone.Core.Exceptions;
|
using NzbDrone.Core.Exceptions;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MetadataSource.SkyHook
|
namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
|
@ -158,6 +160,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
series.CleanTitle = Parser.Parser.CleanSeriesTitle(show.Title);
|
series.CleanTitle = Parser.Parser.CleanSeriesTitle(show.Title);
|
||||||
series.SortTitle = SeriesTitleNormalizer.Normalize(show.Title, show.TvdbId);
|
series.SortTitle = SeriesTitleNormalizer.Normalize(show.Title, show.TvdbId);
|
||||||
|
|
||||||
|
series.OriginalLanguage = IsoLanguages.Find(show.OriginalLanguage.ToLower())?.Language ?? Language.English;
|
||||||
|
|
||||||
if (show.FirstAired != null)
|
if (show.FirstAired != null)
|
||||||
{
|
{
|
||||||
series.FirstAired = DateTime.ParseExact(show.FirstAired, "yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
|
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);
|
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)
|
foreach (var regex in CleanSeriesTitleRegex)
|
||||||
{
|
{
|
||||||
|
@ -175,7 +175,7 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
if (!languages.Any())
|
if (!languages.Any())
|
||||||
{
|
{
|
||||||
languages.Add(defaultToEnglish ? Language.English : Language.Unknown);
|
languages.Add(Language.Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
return languages.DistinctBy(l => (int)l).ToList();
|
return languages.DistinctBy(l => (int)l).ToList();
|
||||||
|
|
|
@ -6,6 +6,8 @@ using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Instrumentation.Extensions;
|
using NzbDrone.Common.Instrumentation.Extensions;
|
||||||
using NzbDrone.Core.DataAugmentation.Scene;
|
using NzbDrone.Core.DataAugmentation.Scene;
|
||||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.MediaFiles;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
@ -182,6 +184,29 @@ namespace NzbDrone.Core.Parser
|
||||||
{
|
{
|
||||||
remoteEpisode.Episodes = GetEpisodes(parsedEpisodeInfo, series, remoteEpisode.MappedSeasonNumber, sceneSource, searchCriteria);
|
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)
|
if (remoteEpisode.Episodes == null)
|
||||||
|
|
|
@ -91,6 +91,7 @@ namespace NzbDrone.Core.Tv
|
||||||
series.ImdbId = seriesInfo.ImdbId;
|
series.ImdbId = seriesInfo.ImdbId;
|
||||||
series.AirTime = seriesInfo.AirTime;
|
series.AirTime = seriesInfo.AirTime;
|
||||||
series.Overview = seriesInfo.Overview;
|
series.Overview = seriesInfo.Overview;
|
||||||
|
series.OriginalLanguage = seriesInfo.OriginalLanguage;
|
||||||
series.Status = seriesInfo.Status;
|
series.Status = seriesInfo.Status;
|
||||||
series.CleanTitle = seriesInfo.CleanTitle;
|
series.CleanTitle = seriesInfo.CleanTitle;
|
||||||
series.SortTitle = seriesInfo.SortTitle;
|
series.SortTitle = seriesInfo.SortTitle;
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.Profiles.Qualities;
|
using NzbDrone.Core.Profiles.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Tv
|
namespace NzbDrone.Core.Tv
|
||||||
|
@ -15,6 +16,7 @@ namespace NzbDrone.Core.Tv
|
||||||
Actors = new List<Actor>();
|
Actors = new List<Actor>();
|
||||||
Seasons = new List<Season>();
|
Seasons = new List<Season>();
|
||||||
Tags = new HashSet<int>();
|
Tags = new HashSet<int>();
|
||||||
|
OriginalLanguage = Language.English;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int TvdbId { get; set; }
|
public int TvdbId { get; set; }
|
||||||
|
@ -47,6 +49,7 @@ namespace NzbDrone.Core.Tv
|
||||||
public DateTime Added { get; set; }
|
public DateTime Added { get; set; }
|
||||||
public DateTime? FirstAired { get; set; }
|
public DateTime? FirstAired { get; set; }
|
||||||
public LazyLoaded<QualityProfile> QualityProfile { get; set; }
|
public LazyLoaded<QualityProfile> QualityProfile { get; set; }
|
||||||
|
public Language OriginalLanguage { get; set; }
|
||||||
|
|
||||||
public List<Season> Seasons { get; set; }
|
public List<Season> Seasons { get; set; }
|
||||||
public HashSet<int> Tags { get; set; }
|
public HashSet<int> Tags { get; set; }
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.MediaCover;
|
using NzbDrone.Core.MediaCover;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
using Sonarr.Http.REST;
|
using Sonarr.Http.REST;
|
||||||
|
@ -30,7 +31,7 @@ namespace Sonarr.Api.V3.Series
|
||||||
public string Network { get; set; }
|
public string Network { get; set; }
|
||||||
public string AirTime { get; set; }
|
public string AirTime { get; set; }
|
||||||
public List<MediaCover> Images { get; set; }
|
public List<MediaCover> Images { get; set; }
|
||||||
|
public Language OriginalLanguage { get; set; }
|
||||||
public string RemotePoster { get; set; }
|
public string RemotePoster { get; set; }
|
||||||
public List<SeasonResource> Seasons { get; set; }
|
public List<SeasonResource> Seasons { get; set; }
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
|
@ -100,6 +101,7 @@ namespace Sonarr.Api.V3.Series
|
||||||
|
|
||||||
Seasons = model.Seasons.ToResource(includeSeasonImages),
|
Seasons = model.Seasons.ToResource(includeSeasonImages),
|
||||||
Year = model.Year,
|
Year = model.Year,
|
||||||
|
OriginalLanguage = model.OriginalLanguage,
|
||||||
|
|
||||||
Path = model.Path,
|
Path = model.Path,
|
||||||
QualityProfileId = model.QualityProfileId,
|
QualityProfileId = model.QualityProfileId,
|
||||||
|
@ -161,6 +163,7 @@ namespace Sonarr.Api.V3.Series
|
||||||
|
|
||||||
Seasons = resource.Seasons?.ToModel() ?? new List<Season>(),
|
Seasons = resource.Seasons?.ToModel() ?? new List<Season>(),
|
||||||
Year = resource.Year,
|
Year = resource.Year,
|
||||||
|
OriginalLanguage = resource.OriginalLanguage,
|
||||||
|
|
||||||
Path = resource.Path,
|
Path = resource.Path,
|
||||||
QualityProfileId = resource.QualityProfileId,
|
QualityProfileId = resource.QualityProfileId,
|
||||||
|
|
Loading…
Reference in New Issue