parent
c10677dfe7
commit
4bfcd0de1d
|
@ -0,0 +1,206 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Extras;
|
||||
using NzbDrone.Core.Extras.Files;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.Extras
|
||||
{
|
||||
[TestFixture]
|
||||
public class ExtraServiceFixture : CoreTest<ExtraService>
|
||||
{
|
||||
private Series _series;
|
||||
private EpisodeFile _episodeFile;
|
||||
private LocalEpisode _localEpisode;
|
||||
|
||||
private string _seriesFolder;
|
||||
private string _episodeFolder;
|
||||
|
||||
private Mock<IManageExtraFiles> _subtitleService;
|
||||
private Mock<IManageExtraFiles> _otherExtraService;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_seriesFolder = @"C:\Test\TV\Series Title".AsOsAgnostic();
|
||||
_episodeFolder = @"C:\Test\Unsorted TV\Series.Title.S01".AsOsAgnostic();
|
||||
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(s => s.Path = _seriesFolder)
|
||||
.Build();
|
||||
|
||||
var episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(e => e.SeasonNumber = 1)
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
|
||||
_episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Path = Path.Combine(_series.Path, "Season 1", "Series Title - S01E01.mkv").AsOsAgnostic())
|
||||
.With(f => f.RelativePath = @"Season 1\Series Title - S01E01.mkv".AsOsAgnostic())
|
||||
.Build();
|
||||
|
||||
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||
.With(l => l.Series = _series)
|
||||
.With(l => l.Episodes = episodes)
|
||||
.With(l => l.Path = Path.Combine(_episodeFolder, "Series.Title.S01E01.mkv").AsOsAgnostic())
|
||||
.Build();
|
||||
|
||||
_subtitleService = new Mock<IManageExtraFiles>();
|
||||
_subtitleService.SetupGet(s => s.Order).Returns(0);
|
||||
_subtitleService.Setup(s => s.CanImportFile(It.IsAny<LocalEpisode>(), It.IsAny<EpisodeFile>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Returns(false);
|
||||
_subtitleService.Setup(s => s.CanImportFile(It.IsAny<LocalEpisode>(), It.IsAny<EpisodeFile>(), It.IsAny<string>(), ".srt", It.IsAny<bool>()))
|
||||
.Returns(true);
|
||||
|
||||
_otherExtraService = new Mock<IManageExtraFiles>();
|
||||
_otherExtraService.SetupGet(s => s.Order).Returns(1);
|
||||
_otherExtraService.Setup(s => s.CanImportFile(It.IsAny<LocalEpisode>(), It.IsAny<EpisodeFile>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Returns(true);
|
||||
|
||||
Mocker.SetConstant<IEnumerable<IManageExtraFiles>>(new[] {
|
||||
_subtitleService.Object,
|
||||
_otherExtraService.Object
|
||||
});
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.FolderExists(It.IsAny<string>()))
|
||||
.Returns(false);
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetParentFolder(It.IsAny<string>()))
|
||||
.Returns((string path) => Directory.GetParent(path).FullName);
|
||||
|
||||
WithExistingFolder(_series.Path);
|
||||
WithExistingFile(_episodeFile.Path);
|
||||
WithExistingFile(_localEpisode.Path);
|
||||
|
||||
Mocker.GetMock<IConfigService>().Setup(v => v.ImportExtraFiles).Returns(true);
|
||||
Mocker.GetMock<IConfigService>().Setup(v => v.ExtraFileExtensions).Returns("nfo,srt");
|
||||
}
|
||||
|
||||
private void WithExistingFolder(string path, bool exists = true)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
|
||||
if (exists && dir.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
WithExistingFolder(dir);
|
||||
}
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(v => v.FolderExists(path)).Returns(exists);
|
||||
}
|
||||
|
||||
private void WithExistingFile(string path, bool exists = true, int size = 1000)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
|
||||
if (exists && dir.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
WithExistingFolder(dir);
|
||||
}
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(v => v.FileExists(path)).Returns(exists);
|
||||
Mocker.GetMock<IDiskProvider>().Setup(v => v.GetFileSize(path)).Returns(size);
|
||||
}
|
||||
|
||||
private void WithExistingFiles(List<string> files)
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
WithExistingFile(file);
|
||||
}
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetFiles(_episodeFolder, SearchOption.AllDirectories))
|
||||
.Returns(files.ToArray());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_pass_file_if_import_disabled()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().Setup(v => v.ImportExtraFiles).Returns(false);
|
||||
|
||||
var nfofile = Path.Combine(_episodeFolder, "Series.Title.S01E01.nfo").AsOsAgnostic();
|
||||
|
||||
var files = new List<string> {
|
||||
_localEpisode.Path,
|
||||
nfofile
|
||||
};
|
||||
|
||||
WithExistingFiles(files);
|
||||
|
||||
Subject.ImportEpisode(_localEpisode, _episodeFile, true);
|
||||
|
||||
_subtitleService.Verify(v => v.CanImportFile(_localEpisode, _episodeFile, It.IsAny<string>(), It.IsAny<string>(), true), Times.Never());
|
||||
_otherExtraService.Verify(v => v.CanImportFile(_localEpisode, _episodeFile, It.IsAny<string>(), It.IsAny<string>(), true), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("Series Title - S01E01.sub")]
|
||||
[TestCase("Series Title - S01E01.ass")]
|
||||
public void should_not_pass_unwanted_file(string filePath)
|
||||
{
|
||||
Mocker.GetMock<IConfigService>().Setup(v => v.ImportExtraFiles).Returns(false);
|
||||
|
||||
var nfofile = Path.Combine(_episodeFolder, filePath).AsOsAgnostic();
|
||||
|
||||
var files = new List<string> {
|
||||
_localEpisode.Path,
|
||||
nfofile
|
||||
};
|
||||
|
||||
WithExistingFiles(files);
|
||||
|
||||
Subject.ImportEpisode(_localEpisode, _episodeFile, true);
|
||||
|
||||
_subtitleService.Verify(v => v.CanImportFile(_localEpisode, _episodeFile, It.IsAny<string>(), It.IsAny<string>(), true), Times.Never());
|
||||
_otherExtraService.Verify(v => v.CanImportFile(_localEpisode, _episodeFile, It.IsAny<string>(), It.IsAny<string>(), true), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_pass_subtitle_file_to_subtitle_service()
|
||||
{
|
||||
var subtitleFile = Path.Combine(_episodeFolder, "Series.Title.S01E01.en.srt").AsOsAgnostic();
|
||||
|
||||
var files = new List<string> {
|
||||
_localEpisode.Path,
|
||||
subtitleFile
|
||||
};
|
||||
|
||||
WithExistingFiles(files);
|
||||
|
||||
Subject.ImportEpisode(_localEpisode, _episodeFile, true);
|
||||
|
||||
_subtitleService.Verify(v => v.ImportFiles(_localEpisode, _episodeFile, new List<string> { subtitleFile }, true), Times.Once());
|
||||
_otherExtraService.Verify(v => v.ImportFiles(_localEpisode, _episodeFile, new List<string> { subtitleFile }, true), Times.Never());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_pass_nfo_file_to_other_service()
|
||||
{
|
||||
var nfofile = Path.Combine(_episodeFolder, "Series.Title.S01E01.nfo").AsOsAgnostic();
|
||||
|
||||
var files = new List<string> {
|
||||
_localEpisode.Path,
|
||||
nfofile
|
||||
};
|
||||
|
||||
WithExistingFiles(files);
|
||||
|
||||
Subject.ImportEpisode(_localEpisode, _episodeFile, true);
|
||||
|
||||
_subtitleService.Verify(v => v.ImportFiles(_localEpisode, _episodeFile, new List<string> { nfofile }, true), Times.Never());
|
||||
_otherExtraService.Verify(v => v.ImportFiles(_localEpisode, _episodeFile, new List<string> { nfofile }, true), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using FizzWare.NBuilder;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Extras.Others;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.Extras.Others
|
||||
{
|
||||
[TestFixture]
|
||||
public class OtherExtraServiceFixture : CoreTest<OtherExtraService>
|
||||
{
|
||||
private Series _series;
|
||||
private EpisodeFile _episodeFile;
|
||||
private LocalEpisode _localEpisode;
|
||||
|
||||
private string _seriesFolder;
|
||||
private string _episodeFolder;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_seriesFolder = @"C:\Test\TV\Series Title".AsOsAgnostic();
|
||||
_episodeFolder = @"C:\Test\Unsorted TV\Series.Title.S01".AsOsAgnostic();
|
||||
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(s => s.Path = _seriesFolder)
|
||||
.Build();
|
||||
|
||||
var episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(e => e.SeasonNumber = 1)
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
|
||||
_episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Path = Path.Combine(_series.Path, "Season 1", "Series Title - S01E01.mkv").AsOsAgnostic())
|
||||
.With(f => f.RelativePath = @"Season 1\Series Title - S01E01.mkv")
|
||||
.Build();
|
||||
|
||||
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||
.With(l => l.Series = _series)
|
||||
.With(l => l.Episodes = episodes)
|
||||
.With(l => l.Path = Path.Combine(_episodeFolder, "Series.Title.S01E01.mkv").AsOsAgnostic())
|
||||
.With(l => l.FileEpisodeInfo = new ParsedEpisodeInfo
|
||||
{
|
||||
SeasonNumber = 1,
|
||||
EpisodeNumbers = new[] { 1 }
|
||||
})
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("Series Title - S01E01.nfo", "Series Title - S01E01.nfo")]
|
||||
[TestCase("Series.Title.S01E01.nfo", "Series Title - S01E01.nfo")]
|
||||
[TestCase("Series-Title-S01E01.nfo", "Series Title - S01E01.nfo")]
|
||||
[TestCase("Series Title S01E01.nfo", "Series Title - S01E01.nfo")]
|
||||
[TestCase("Series_Title_S01E01.nfo", "Series Title - S01E01.nfo")]
|
||||
[TestCase("S01E01.thumb.jpg", "Series Title - S01E01.jpg")]
|
||||
[TestCase(@"Series.Title.S01E01\thumb.jpg", "Series Title - S01E01.jpg")]
|
||||
public void should_import_matching_file(string filePath, string expectedOutputPath)
|
||||
{
|
||||
var files = new List<string> { Path.Combine(_episodeFolder, filePath).AsOsAgnostic() };
|
||||
|
||||
var results = Subject.ImportFiles(_localEpisode, _episodeFile, files, true).ToList();
|
||||
|
||||
results.Count().Should().Be(1);
|
||||
|
||||
results[0].RelativePath.AsOsAgnostic().PathEquals(Path.Combine("Season 1", expectedOutputPath).AsOsAgnostic()).Should().Be(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_import_multiple_nfo_files()
|
||||
{
|
||||
var files = new List<string>
|
||||
{
|
||||
Path.Combine(_episodeFolder, "Series.Title.S01E01.nfo").AsOsAgnostic(),
|
||||
Path.Combine(_episodeFolder, "Series_Title_S01E01.nfo").AsOsAgnostic(),
|
||||
};
|
||||
|
||||
var results = Subject.ImportFiles(_localEpisode, _episodeFile, files, true).ToList();
|
||||
|
||||
results.Count().Should().Be(1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using FizzWare.NBuilder;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Extras.Subtitles;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
using Moq;
|
||||
using NzbDrone.Common.Disk;
|
||||
|
||||
namespace NzbDrone.Core.Test.Extras.Subtitles
|
||||
{
|
||||
[TestFixture]
|
||||
public class SubtitleServiceFixture : CoreTest<SubtitleService>
|
||||
{
|
||||
private Series _series;
|
||||
private EpisodeFile _episodeFile;
|
||||
private LocalEpisode _localEpisode;
|
||||
|
||||
private string _seriesFolder;
|
||||
private string _episodeFolder;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_seriesFolder = @"C:\Test\TV\Series Title".AsOsAgnostic();
|
||||
_episodeFolder = @"C:\Test\Unsorted TV\Series.Title.S01".AsOsAgnostic();
|
||||
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.With(s => s.Path = _seriesFolder)
|
||||
.Build();
|
||||
|
||||
var episodes = Builder<Episode>.CreateListOfSize(1)
|
||||
.All()
|
||||
.With(e => e.SeasonNumber = 1)
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
|
||||
_episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Path = Path.Combine(_series.Path, "Season 1", "Series Title - S01E01.mkv").AsOsAgnostic())
|
||||
.With(f => f.RelativePath = @"Season 1\Series Title - S01E01.mkv".AsOsAgnostic())
|
||||
.Build();
|
||||
|
||||
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||
.With(l => l.Series = _series)
|
||||
.With(l => l.Episodes = episodes)
|
||||
.With(l => l.Path = Path.Combine(_episodeFolder, "Series.Title.S01E01.mkv").AsOsAgnostic())
|
||||
.With(l => l.FileEpisodeInfo = new ParsedEpisodeInfo
|
||||
{
|
||||
SeasonNumber = 1,
|
||||
EpisodeNumbers = new[] { 1 }
|
||||
})
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetParentFolder(It.IsAny<string>()))
|
||||
.Returns((string path) => Directory.GetParent(path).FullName);
|
||||
|
||||
Mocker.GetMock<IDetectSample>().Setup(s => s.IsSample(It.IsAny<Series>(), It.IsAny<string>(), It.IsAny<bool>()))
|
||||
.Returns(DetectSampleResult.NotSample);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("Series.Title.S01E01.en.nfo")]
|
||||
public void should_not_import_non_subtitle_file(string filePath)
|
||||
{
|
||||
var files = new List<string> { Path.Combine(_episodeFolder, filePath).AsOsAgnostic() };
|
||||
|
||||
var results = Subject.ImportFiles(_localEpisode, _episodeFile, files, true).ToList();
|
||||
|
||||
results.Count().Should().Be(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("Series Title - S01E01.srt", "Series Title - S01E01.srt")]
|
||||
[TestCase("Series.Title.S01E01.en.srt", "Series Title - S01E01.en.srt")]
|
||||
[TestCase("Series.Title.S01E01.english.srt", "Series Title - S01E01.en.srt")]
|
||||
[TestCase("Series-Title-S01E01-fr-cc.srt", "Series Title - S01E01.fr.srt")]
|
||||
[TestCase("Series Title S01E01_en_sdh_forced.srt", "Series Title - S01E01.en.srt")]
|
||||
[TestCase("Series_Title_S01E01 en.srt", "Series Title - S01E01.en.srt")]
|
||||
[TestCase(@"Subs\S01E01.en.srt", "Series Title - S01E01.en.srt")]
|
||||
[TestCase(@"Subs\Series.Title.S01E01\2_en.srt", "Series Title - S01E01.en.srt")]
|
||||
public void should_import_matching_subtitle_file(string filePath, string expectedOutputPath)
|
||||
{
|
||||
var files = new List<string> { Path.Combine(_episodeFolder, filePath).AsOsAgnostic() };
|
||||
|
||||
var results = Subject.ImportFiles(_localEpisode, _episodeFile, files, true).ToList();
|
||||
|
||||
results.Count().Should().Be(1);
|
||||
|
||||
results[0].RelativePath.AsOsAgnostic().PathEquals(Path.Combine("Season 1", expectedOutputPath).AsOsAgnostic()).Should().Be(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_import_multiple_subtitle_files_per_language()
|
||||
{
|
||||
var files = new List<string>
|
||||
{
|
||||
Path.Combine(_episodeFolder, "Series.Title.S01E01.en.srt").AsOsAgnostic(),
|
||||
Path.Combine(_episodeFolder, "Series.Title.S01E01.english.srt").AsOsAgnostic(),
|
||||
Path.Combine(_episodeFolder, "Subs", "Series_Title_S01E01_en_forced.srt").AsOsAgnostic(),
|
||||
Path.Combine(_episodeFolder, "Subs", "Series.Title.S01E01", "2_fr.srt").AsOsAgnostic()
|
||||
};
|
||||
|
||||
var expectedOutputs = new string[]
|
||||
{
|
||||
"Series Title - S01E01.1.en.srt",
|
||||
"Series Title - S01E01.2.en.srt",
|
||||
"Series Title - S01E01.3.en.srt",
|
||||
"Series Title - S01E01.fr.srt",
|
||||
};
|
||||
|
||||
var results = Subject.ImportFiles(_localEpisode, _episodeFile, files, true).ToList();
|
||||
|
||||
results.Count().Should().Be(expectedOutputs.Length);
|
||||
|
||||
for (int i = 0; i < expectedOutputs.Length; i++)
|
||||
{
|
||||
results[i].RelativePath.AsOsAgnostic().PathEquals(Path.Combine("Season 1", expectedOutputs[i]).AsOsAgnostic()).Should().Be(true);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("sub.srt", "Series Title - S01E01.srt")]
|
||||
[TestCase(@"Subs\2_en.srt", "Series Title - S01E01.en.srt")]
|
||||
public void should_import_unmatching_subtitle_file_if_only_episode(string filePath, string expectedOutputPath)
|
||||
{
|
||||
var subtitleFile = Path.Combine(_episodeFolder, filePath).AsOsAgnostic();
|
||||
|
||||
var sampleFile = Path.Combine(_series.Path, "Season 1", "Series Title - S01E01.sample.mkv").AsOsAgnostic();
|
||||
|
||||
var videoFiles = new string[]
|
||||
{
|
||||
_localEpisode.Path,
|
||||
sampleFile
|
||||
};
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetFiles(It.IsAny<string>(), SearchOption.AllDirectories))
|
||||
.Returns(videoFiles);
|
||||
|
||||
Mocker.GetMock<IDetectSample>().Setup(s => s.IsSample(It.IsAny<Series>(), sampleFile, It.IsAny<bool>()))
|
||||
.Returns(DetectSampleResult.Sample);
|
||||
|
||||
var results = Subject.ImportFiles(_localEpisode, _episodeFile, new List<string> { subtitleFile }, true).ToList();
|
||||
|
||||
results.Count().Should().Be(1);
|
||||
|
||||
results[0].RelativePath.AsOsAgnostic().PathEquals(Path.Combine("Season 1", expectedOutputPath).AsOsAgnostic()).Should().Be(true);
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("sub.srt")]
|
||||
[TestCase(@"Subs\2_en.srt")]
|
||||
public void should_not_import_unmatching_subtitle_file_if_multiple_episodes(string filePath)
|
||||
{
|
||||
var subtitleFile = Path.Combine(_episodeFolder, filePath).AsOsAgnostic();
|
||||
|
||||
var videoFiles = new string[]
|
||||
{
|
||||
_localEpisode.Path,
|
||||
Path.Combine(_series.Path, "Season 1", "Series Title - S01E01.sample.mkv").AsOsAgnostic()
|
||||
};
|
||||
|
||||
Mocker.GetMock<IDiskProvider>().Setup(s => s.GetFiles(It.IsAny<string>(), SearchOption.AllDirectories))
|
||||
.Returns(videoFiles);
|
||||
|
||||
var results = Subject.ImportFiles(_localEpisode, _episodeFile, new List<string> { subtitleFile }, true).ToList();
|
||||
|
||||
results.Count().Should().Be(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,6 +35,22 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
result.Should().Be(Language.Unknown);
|
||||
}
|
||||
|
||||
[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")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.english.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.en.cc.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.en.sdh.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.en.forced.sub")]
|
||||
[TestCase("Series Title - S01E01 - Pilot.en.sdh.forced.sub")]
|
||||
public void should_parse_subtitle_language_english(string fileName)
|
||||
{
|
||||
var result = LanguageParser.ParseSubtitleLanguage(fileName);
|
||||
result.Should().Be(Language.English);
|
||||
}
|
||||
|
||||
[TestCase("Title.the.Series.2009.S01E14.French.HDTV.XviD-LOL")]
|
||||
[TestCase("Title.the.Series.The.1x13.Tueurs.De.Flics.FR.DVDRip.XviD")]
|
||||
public void should_parse_language_french(string postTitle)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -32,13 +32,12 @@ namespace NzbDrone.Core.Extras
|
|||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly List<IManageExtraFiles> _extraFileManagers;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public ExtraService(IMediaFileService mediaFileService,
|
||||
IEpisodeService episodeService,
|
||||
IDiskProvider diskProvider,
|
||||
IConfigService configService,
|
||||
List<IManageExtraFiles> extraFileManagers,
|
||||
IEnumerable<IManageExtraFiles> extraFileManagers,
|
||||
Logger logger)
|
||||
{
|
||||
_mediaFileService = mediaFileService;
|
||||
|
@ -46,13 +45,12 @@ namespace NzbDrone.Core.Extras
|
|||
_diskProvider = diskProvider;
|
||||
_configService = configService;
|
||||
_extraFileManagers = extraFileManagers.OrderBy(e => e.Order).ToList();
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void ImportEpisode(LocalEpisode localEpisode, EpisodeFile episodeFile, bool isReadOnly)
|
||||
{
|
||||
ImportExtraFiles(localEpisode, episodeFile, isReadOnly);
|
||||
|
||||
|
||||
CreateAfterEpisodeImport(localEpisode.Series, episodeFile);
|
||||
}
|
||||
|
||||
|
@ -63,62 +61,38 @@ namespace NzbDrone.Core.Extras
|
|||
return;
|
||||
}
|
||||
|
||||
var sourcePath = localEpisode.Path;
|
||||
var sourceFolder = _diskProvider.GetParentFolder(sourcePath);
|
||||
var sourceFileName = Path.GetFileNameWithoutExtension(sourcePath);
|
||||
var files = _diskProvider.GetFiles(sourceFolder, SearchOption.TopDirectoryOnly);
|
||||
|
||||
var wantedExtensions = _configService.ExtraFileExtensions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(e => e.Trim(' ', '.'))
|
||||
.Select(e => e.Trim(' ', '.')
|
||||
.Insert(0, "."))
|
||||
.ToList();
|
||||
|
||||
var matchingFilenames = files.Where(f => Path.GetFileNameWithoutExtension(f).StartsWith(sourceFileName, StringComparison.InvariantCultureIgnoreCase)).ToList();
|
||||
var filteredFilenames = new List<string>();
|
||||
var hasNfo = false;
|
||||
var sourceFolder = _diskProvider.GetParentFolder(localEpisode.Path);
|
||||
var files = _diskProvider.GetFiles(sourceFolder, SearchOption.AllDirectories);
|
||||
var managedFiles = _extraFileManagers.Select((i) => new List<string>()).ToArray();
|
||||
|
||||
foreach (var matchingFilename in matchingFilenames)
|
||||
foreach (var file in files)
|
||||
{
|
||||
// Filter out duplicate NFO files
|
||||
|
||||
if (matchingFilename.EndsWith(".nfo", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (hasNfo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasNfo = true;
|
||||
}
|
||||
|
||||
filteredFilenames.Add(matchingFilename);
|
||||
}
|
||||
|
||||
foreach (var matchingFilename in filteredFilenames)
|
||||
{
|
||||
var matchingExtension = wantedExtensions.FirstOrDefault(e => matchingFilename.EndsWith(e));
|
||||
var extension = Path.GetExtension(file);
|
||||
var matchingExtension = wantedExtensions.FirstOrDefault(e => e.Equals(extension));
|
||||
|
||||
if (matchingExtension == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
for (int i = 0; i < _extraFileManagers.Count; i++)
|
||||
{
|
||||
foreach (var extraFileManager in _extraFileManagers)
|
||||
if (_extraFileManagers[i].CanImportFile(localEpisode, episodeFile, file, extension, isReadOnly))
|
||||
{
|
||||
var extension = Path.GetExtension(matchingFilename);
|
||||
var extraFile = extraFileManager.Import(localEpisode.Series, episodeFile, matchingFilename, extension, isReadOnly);
|
||||
|
||||
if (extraFile != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
managedFiles[i].Add(file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Failed to import extra file: {0}", matchingFilename);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _extraFileManagers.Count; i++)
|
||||
{
|
||||
_extraFileManagers[i].ImportFiles(localEpisode, episodeFile, managedFiles[i], isReadOnly);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ using NzbDrone.Common.Disk;
|
|||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Extras.Files
|
||||
|
@ -19,7 +20,8 @@ namespace NzbDrone.Core.Extras.Files
|
|||
IEnumerable<ExtraFile> CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile);
|
||||
IEnumerable<ExtraFile> CreateAfterEpisodeFolder(Series series, string seriesFolder, string seasonFolder);
|
||||
IEnumerable<ExtraFile> MoveFilesAfterRename(Series series, List<EpisodeFile> episodeFiles);
|
||||
ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly);
|
||||
bool CanImportFile(LocalEpisode localEpisode, EpisodeFile episodeFile, string path, string extension, bool readOnly);
|
||||
IEnumerable<ExtraFile> ImportFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, List<string> files, bool isReadOnly);
|
||||
}
|
||||
|
||||
public abstract class ExtraFileManager<TExtraFile> : IManageExtraFiles
|
||||
|
@ -48,7 +50,8 @@ namespace NzbDrone.Core.Extras.Files
|
|||
public abstract IEnumerable<ExtraFile> CreateAfterEpisodeImport(Series series, EpisodeFile episodeFile);
|
||||
public abstract IEnumerable<ExtraFile> CreateAfterEpisodeFolder(Series series, string seriesFolder, string seasonFolder);
|
||||
public abstract IEnumerable<ExtraFile> MoveFilesAfterRename(Series series, List<EpisodeFile> episodeFiles);
|
||||
public abstract ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly);
|
||||
public abstract bool CanImportFile(LocalEpisode localEpisode, EpisodeFile episodeFile, string path, string extension, bool readOnly);
|
||||
public abstract IEnumerable<ExtraFile> ImportFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, List<string> files, bool isReadOnly);
|
||||
|
||||
protected TExtraFile ImportFile(Series series, EpisodeFile episodeFile, string path, bool readOnly, string extension, string fileNameSuffix = null)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@ using NzbDrone.Core.Extras.Files;
|
|||
using NzbDrone.Core.Extras.Metadata.Files;
|
||||
using NzbDrone.Core.Extras.Others;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Extras.Metadata
|
||||
|
@ -202,9 +203,14 @@ namespace NzbDrone.Core.Extras.Metadata
|
|||
return movedFiles;
|
||||
}
|
||||
|
||||
public override ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly)
|
||||
public override bool CanImportFile(LocalEpisode localEpisode, EpisodeFile episodeFile, string path, string extension, bool readOnly)
|
||||
{
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> ImportFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, List<string> files, bool isReadOnly)
|
||||
{
|
||||
return Enumerable.Empty<ExtraFile>();
|
||||
}
|
||||
|
||||
private List<MetadataFile> GetMetadataFilesForConsumer(IMetadata consumer, List<MetadataFile> seriesMetadata)
|
||||
|
|
|
@ -8,14 +8,17 @@ using NzbDrone.Common.Extensions;
|
|||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Extras.Files;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Extras.Others
|
||||
{
|
||||
public class OtherExtraService : ExtraFileManager<OtherExtraFile>
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IOtherExtraFileService _otherExtraFileService;
|
||||
private readonly IMediaFileAttributeService _mediaFileAttributeService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public OtherExtraService(IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
|
@ -25,8 +28,10 @@ namespace NzbDrone.Core.Extras.Others
|
|||
Logger logger)
|
||||
: base(configService, diskProvider, diskTransferService, logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_otherExtraFileService = otherExtraFileService;
|
||||
_mediaFileAttributeService = mediaFileAttributeService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override int Order => 2;
|
||||
|
@ -71,14 +76,79 @@ namespace NzbDrone.Core.Extras.Others
|
|||
return movedFiles;
|
||||
}
|
||||
|
||||
public override ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly)
|
||||
public override bool CanImportFile(LocalEpisode localEpisode, EpisodeFile episodeFile, string path, string extension, bool readOnly)
|
||||
{
|
||||
var extraFile = ImportFile(series, episodeFile, path, readOnly, extension, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
_mediaFileAttributeService.SetFilePermissions(path);
|
||||
_otherExtraFileService.Upsert(extraFile);
|
||||
public override IEnumerable<ExtraFile> ImportFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, List<string> files, bool isReadOnly)
|
||||
{
|
||||
var importedFiles = new List<ExtraFile>();
|
||||
var filteredFiles = files.Where(f => CanImportFile(localEpisode, episodeFile, f, Path.GetExtension(f), isReadOnly)).ToList();
|
||||
var sourcePath = localEpisode.Path;
|
||||
var sourceFolder = _diskProvider.GetParentFolder(sourcePath);
|
||||
var sourceFileName = Path.GetFileNameWithoutExtension(sourcePath);
|
||||
var matchingFiles = new List<string>();
|
||||
var hasNfo = false;
|
||||
|
||||
return extraFile;
|
||||
foreach (var file in filteredFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Filter out duplicate NFO files
|
||||
if (file.EndsWith(".nfo", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (hasNfo)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hasNfo = true;
|
||||
}
|
||||
|
||||
// Filename match
|
||||
if (Path.GetFileNameWithoutExtension(file).StartsWith(sourceFileName, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
matchingFiles.Add(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Season and episode match
|
||||
var fileEpisodeInfo = Parser.Parser.ParsePath(file) ?? new ParsedEpisodeInfo();
|
||||
|
||||
if (fileEpisodeInfo.EpisodeNumbers.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileEpisodeInfo.SeasonNumber == localEpisode.FileEpisodeInfo.SeasonNumber &&
|
||||
fileEpisodeInfo.EpisodeNumbers.SequenceEqual(localEpisode.FileEpisodeInfo.EpisodeNumbers))
|
||||
{
|
||||
matchingFiles.Add(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Failed to import extra file: {0}", file);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string file in matchingFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
var extraFile = ImportFile(localEpisode.Series, episodeFile, file, isReadOnly, Path.GetExtension(file), null);
|
||||
_mediaFileAttributeService.SetFilePermissions(file);
|
||||
_otherExtraFileService.Upsert(extraFile);
|
||||
importedFiles.Add(extraFile);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Failed to import extra file: {0}", file);
|
||||
}
|
||||
}
|
||||
|
||||
return importedFiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
@ -9,13 +10,17 @@ using NzbDrone.Core.Configuration;
|
|||
using NzbDrone.Core.Extras.Files;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Extras.Subtitles
|
||||
{
|
||||
public class SubtitleService : ExtraFileManager<SubtitleFile>
|
||||
{
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IDetectSample _detectSample;
|
||||
private readonly ISubtitleFileService _subtitleFileService;
|
||||
private readonly IMediaFileAttributeService _mediaFileAttributeService;
|
||||
private readonly Logger _logger;
|
||||
|
@ -23,11 +28,14 @@ namespace NzbDrone.Core.Extras.Subtitles
|
|||
public SubtitleService(IConfigService configService,
|
||||
IDiskProvider diskProvider,
|
||||
IDiskTransferService diskTransferService,
|
||||
IDetectSample detectSample,
|
||||
ISubtitleFileService subtitleFileService,
|
||||
IMediaFileAttributeService mediaFileAttributeService,
|
||||
Logger logger)
|
||||
: base(configService, diskProvider, diskTransferService, logger)
|
||||
{
|
||||
_diskProvider = diskProvider;
|
||||
_detectSample = detectSample;
|
||||
_subtitleFileService = subtitleFileService;
|
||||
_mediaFileAttributeService = mediaFileAttributeService;
|
||||
_logger = logger;
|
||||
|
@ -71,11 +79,6 @@ namespace NzbDrone.Core.Extras.Subtitles
|
|||
var groupCount = group.Count();
|
||||
var copy = 1;
|
||||
|
||||
if (groupCount > 1)
|
||||
{
|
||||
_logger.Warn("Multiple subtitle files found with the same language and extension for {0}", Path.Combine(series.Path, episodeFile.RelativePath));
|
||||
}
|
||||
|
||||
foreach (var subtitleFile in group)
|
||||
{
|
||||
var suffix = GetSuffix(subtitleFile.Language, copy, groupCount > 1);
|
||||
|
@ -91,23 +94,129 @@ namespace NzbDrone.Core.Extras.Subtitles
|
|||
return movedFiles;
|
||||
}
|
||||
|
||||
public override ExtraFile Import(Series series, EpisodeFile episodeFile, string path, string extension, bool readOnly)
|
||||
public override bool CanImportFile(LocalEpisode localEpisode, EpisodeFile episodeFile, string path, string extension, bool readOnly)
|
||||
{
|
||||
if (SubtitleFileExtensions.Extensions.Contains(Path.GetExtension(path)))
|
||||
return SubtitleFileExtensions.Extensions.Contains(extension.ToLowerInvariant());
|
||||
}
|
||||
|
||||
public override IEnumerable<ExtraFile> ImportFiles(LocalEpisode localEpisode, EpisodeFile episodeFile, List<string> files, bool isReadOnly)
|
||||
{
|
||||
var importedFiles = new List<SubtitleFile>();
|
||||
|
||||
var filteredFiles = files.Where(f => CanImportFile(localEpisode, episodeFile, f, Path.GetExtension(f), isReadOnly)).ToList();
|
||||
|
||||
var sourcePath = localEpisode.Path;
|
||||
var sourceFolder = _diskProvider.GetParentFolder(sourcePath);
|
||||
var sourceFileName = Path.GetFileNameWithoutExtension(sourcePath);
|
||||
|
||||
var matchingFiles = new List<string>();
|
||||
|
||||
foreach (var file in filteredFiles)
|
||||
{
|
||||
var language = LanguageParser.ParseSubtitleLanguage(path);
|
||||
var suffix = GetSuffix(language, 1, false);
|
||||
var subtitleFile = ImportFile(series, episodeFile, path, readOnly, extension, suffix);
|
||||
subtitleFile.Language = language;
|
||||
try
|
||||
{
|
||||
// Filename match
|
||||
if (Path.GetFileNameWithoutExtension(file).StartsWith(sourceFileName, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
matchingFiles.Add(file);
|
||||
continue;
|
||||
}
|
||||
|
||||
_mediaFileAttributeService.SetFilePermissions(path);
|
||||
_subtitleFileService.Upsert(subtitleFile);
|
||||
// Season and episode match
|
||||
var fileEpisodeInfo = Parser.Parser.ParsePath(file) ?? new ParsedEpisodeInfo();
|
||||
|
||||
if (fileEpisodeInfo.EpisodeNumbers.Length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return subtitleFile;
|
||||
if (fileEpisodeInfo.SeasonNumber == localEpisode.FileEpisodeInfo.SeasonNumber &&
|
||||
fileEpisodeInfo.EpisodeNumbers.SequenceEqual(localEpisode.FileEpisodeInfo.EpisodeNumbers))
|
||||
{
|
||||
matchingFiles.Add(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Failed to import subtitle file: {0}", file);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
// Use any sub if only episode in folder
|
||||
if (matchingFiles.Count == 0 && filteredFiles.Count > 0)
|
||||
{
|
||||
var videoFiles = _diskProvider.GetFiles(sourceFolder, SearchOption.AllDirectories)
|
||||
.Where(file => MediaFileExtensions.Extensions.Contains(Path.GetExtension(file)))
|
||||
.ToList();
|
||||
|
||||
if (videoFiles.Count() > 2)
|
||||
{
|
||||
return importedFiles;
|
||||
}
|
||||
|
||||
// Filter out samples
|
||||
videoFiles = videoFiles.Where(file =>
|
||||
{
|
||||
var sample = _detectSample.IsSample(localEpisode.Series, file, false);
|
||||
|
||||
if (sample == DetectSampleResult.Sample)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}).ToList();
|
||||
|
||||
if (videoFiles.Count == 1)
|
||||
{
|
||||
matchingFiles.AddRange(filteredFiles);
|
||||
|
||||
_logger.Warn("Imported any available subtitle file for episode: {0}", localEpisode);
|
||||
}
|
||||
}
|
||||
|
||||
var subtitleFiles = new List<Tuple<string, Language, string>>();
|
||||
|
||||
foreach (string file in matchingFiles)
|
||||
{
|
||||
var language = LanguageParser.ParseSubtitleLanguage(file);
|
||||
var extension = Path.GetExtension(file);
|
||||
subtitleFiles.Add(new Tuple<string, Language, string>(file, language, extension));
|
||||
}
|
||||
|
||||
var groupedSubtitleFiles = subtitleFiles.GroupBy(s => s.Item2 + s.Item3).ToList();
|
||||
|
||||
foreach (var group in groupedSubtitleFiles)
|
||||
{
|
||||
var groupCount = group.Count();
|
||||
var copy = 1;
|
||||
|
||||
foreach (var file in group)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = file.Item1;
|
||||
var language = file.Item2;
|
||||
var extension = file.Item3;
|
||||
var suffix = GetSuffix(language, copy, groupCount > 1);
|
||||
var subtitleFile = ImportFile(localEpisode.Series, episodeFile, path, isReadOnly, extension, suffix);
|
||||
subtitleFile.Language = language;
|
||||
|
||||
_mediaFileAttributeService.SetFilePermissions(path);
|
||||
_subtitleFileService.Upsert(subtitleFile);
|
||||
|
||||
importedFiles.Add(subtitleFile);
|
||||
|
||||
copy++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Failed to import subtitle file: {0}", file.Item1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return importedFiles;
|
||||
}
|
||||
|
||||
private string GetSuffix(Language language, int copy, bool multipleCopies = false)
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace NzbDrone.Core.Parser
|
|||
RegexOptions.Compiled);
|
||||
|
||||
|
||||
private static readonly Regex SubtitleLanguageRegex = new Regex(".+?[-_. ](?<iso_code>[a-z]{2,3})$", 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 Language ParseLanguage(string title, bool defaultToEnglish = true)
|
||||
{
|
||||
|
@ -124,12 +124,12 @@ namespace NzbDrone.Core.Parser
|
|||
if (languageMatch.Success)
|
||||
{
|
||||
var isoCode = languageMatch.Groups["iso_code"].Value;
|
||||
var isoLanguage = IsoLanguages.Find(isoCode);
|
||||
var isoLanguage = IsoLanguages.Find(isoCode.ToLower());
|
||||
|
||||
return isoLanguage?.Language ?? Language.Unknown;
|
||||
}
|
||||
|
||||
foreach (Language language in Enum.GetValues(typeof(Language)))
|
||||
foreach (Language language in Language.All)
|
||||
{
|
||||
if (simpleFilename.EndsWith(language.ToString(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue