various improvements
This commit is contained in:
parent
718c642ab7
commit
96623d077e
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Dapper;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class parse_title_from_existing_subtitle_filesFixture : MigrationTest<parse_title_from_existing_subtitle_files>
|
||||
{
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.default.eng.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].eng.default.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.eng.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020).mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.forced.eng.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].eng.forced.testtitle.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].forced.eng.testtitle.ass", "Name (2020)/Season 1/Name (2020).mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.default.fra.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].fra.default.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.fra.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020).mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.forced.fra.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].fra.forced.testtitle.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].forced.fra.testtitle.ass", "Name (2020)/Season 1/Name (2020).mkv", "testtitle")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", null)]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", null)]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", null)]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", null)]
|
||||
public void should_process_file_with_missing_title(string subtitlePath, string episodePath, string title)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var db = WithDapperMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("SubtitleFiles").Row(new
|
||||
{
|
||||
SeriesId = 1,
|
||||
SeasonNumber = 1,
|
||||
EpisodeFileId = 1,
|
||||
RelativePath = subtitlePath,
|
||||
Added = now,
|
||||
LastUpdated = now,
|
||||
Extension = Path.GetExtension(subtitlePath),
|
||||
Language = 1
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("EpisodeFiles").Row(new
|
||||
{
|
||||
Id = 1,
|
||||
SeriesId = 1,
|
||||
RelativePath = episodePath,
|
||||
Quality = new { }.ToJson(),
|
||||
Size = 0,
|
||||
DateAdded = now,
|
||||
SeasonNumber = 1,
|
||||
Languages = new List<int> { 1 }.ToJson()
|
||||
});
|
||||
});
|
||||
|
||||
var files = db.Query<SubtitleFile197>("SELECT * FROM \"SubtitleFiles\"").ToList();
|
||||
|
||||
files.Should().HaveCount(1);
|
||||
|
||||
files.First().Title.Should().Be(title);
|
||||
files.First().Copy.Should().Be(0);
|
||||
}
|
||||
}
|
||||
|
||||
public class SubtitleFile197
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public int? EpisodeFileId { get; set; }
|
||||
public int? SeasonNumber { get; set; }
|
||||
public string RelativePath { get; set; }
|
||||
public DateTime Added { get; set; }
|
||||
public DateTime LastUpdated { get; set; }
|
||||
public string Extension { get; set; }
|
||||
public int Language { get; set; }
|
||||
public int Copy { get; set; }
|
||||
public string Title { get; set; }
|
||||
public List<string> LanguageTags { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
@ -433,13 +432,19 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
result.Languages.Should().Contain(Language.English);
|
||||
}
|
||||
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.default.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020).mkv")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.default.eng.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].eng.default.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.eng.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020).mkv")]
|
||||
public void should_parse_title_and_tags(string postTitle, string episodeFilePath)
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.default.eng.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "default", "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].eng.default.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "default", "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.eng.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020).mkv", new[] { "default", "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.forced.eng.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].eng.forced.testtitle.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].forced.eng.testtitle.ass", "Name (2020)/Season 1/Name (2020).mkv", new[] { "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.default.fra.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "default", "forced" }, "testtitle", "French")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].fra.default.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "default", "forced" }, "testtitle", "French")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.fra.testtitle.forced.ass", "Name (2020)/Season 1/Name (2020).mkv", new[] { "default", "forced" }, "testtitle", "French")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.forced.fra.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "forced" }, "testtitle", "French")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].fra.forced.testtitle.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv", new[] { "forced" }, "testtitle", "French")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].forced.fra.testtitle.ass", "Name (2020)/Season 1/Name (2020).mkv", new[] { "forced" }, "testtitle", "French")]
|
||||
public void should_parse_title_and_tags(string postTitle, string episodeFilePath, string[] expectedTags, string expectedTitle, string expectedLanguage)
|
||||
{
|
||||
var episode = new Episode
|
||||
{
|
||||
|
@ -448,12 +453,11 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
RelativePath = episodeFilePath
|
||||
})
|
||||
};
|
||||
var (languageTags, title) = LanguageParser.ParseLanguageTagsAndTitle(postTitle, episode);
|
||||
languageTags.Should().BeEquivalentTo(new[] { "default", "forced" });
|
||||
title.Should().BeEquivalentTo("testtitle");
|
||||
|
||||
var result = LanguageParser.ParseLanguages(postTitle);
|
||||
result.Should().Contain(Language.English);
|
||||
var (languageTags, title, language) = LanguageParser.ParseLanguageTagsAndTitle(postTitle, episode);
|
||||
languageTags.Should().BeEquivalentTo(expectedTags);
|
||||
title.Should().BeEquivalentTo(expectedTitle);
|
||||
language.Should().BeEquivalentTo((Language)expectedLanguage);
|
||||
}
|
||||
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.forced.ass", "Name (2020)/Season 1/Name (2020) - S01E20 - [AAC 2.0].mkv")]
|
||||
|
@ -469,7 +473,7 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
RelativePath = episodeFilePath
|
||||
})
|
||||
};
|
||||
Assert.Throws<ArgumentException>(() => LanguageParser.ParseLanguageTagsAndTitle(postTitle, episode));
|
||||
Assert.Throws<LanguageParsingException>(() => LanguageParser.ParseLanguageTagsAndTitle(postTitle, episode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,16 +41,20 @@ namespace NzbDrone.Core.Datastore.Migration
|
|||
EpisodeFile = new LazyLoaded<EpisodeFile>(episodeFile)
|
||||
};
|
||||
|
||||
var title = LanguageParser.ParseLanguageTagsAndTitle(relativePath, episode).title;
|
||||
|
||||
var copy = LanguageParser.CopyFromTitle(title);
|
||||
|
||||
updatedTitles.Add(new
|
||||
try
|
||||
{
|
||||
Id = id,
|
||||
Title = title,
|
||||
Copy = copy
|
||||
});
|
||||
var (copy, title) = LanguageParser.CopyFromTitle(LanguageParser.ParseLanguageTagsAndTitle(relativePath, episode).title);
|
||||
|
||||
updatedTitles.Add(new
|
||||
{
|
||||
Id = id,
|
||||
Title = title,
|
||||
Copy = copy
|
||||
});
|
||||
}
|
||||
catch (LanguageParsingException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Extras.Files;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
@ -76,27 +76,32 @@ namespace NzbDrone.Core.Extras.Subtitles
|
|||
|
||||
List<string> languageTags = null;
|
||||
string title = null;
|
||||
Language language = null;
|
||||
|
||||
try
|
||||
{
|
||||
(languageTags, title) = LanguageParser.ParseLanguageTagsAndTitle(possibleSubtitleFile, firstEpisode);
|
||||
(languageTags, title, language) = LanguageParser.ParseLanguageTagsAndTitle(possibleSubtitleFile, firstEpisode);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
catch (LanguageParsingException)
|
||||
{
|
||||
language = LanguageParser.ParseSubtitleLanguage(possibleSubtitleFile);
|
||||
languageTags = LanguageParser.ParseLanguageTags(possibleSubtitleFile);
|
||||
_logger.Debug("Failed parsing language tags with title from subtitle file: {0}", possibleSubtitleFile);
|
||||
}
|
||||
|
||||
var (copy, newTitle) = LanguageParser.CopyFromTitle(title);
|
||||
|
||||
var subtitleFile = new SubtitleFile
|
||||
{
|
||||
SeriesId = series.Id,
|
||||
SeasonNumber = localEpisode.SeasonNumber,
|
||||
EpisodeFileId = firstEpisode.EpisodeFileId,
|
||||
RelativePath = series.Path.GetRelativePath(possibleSubtitleFile),
|
||||
Language = LanguageParser.ParseSubtitleLanguage(possibleSubtitleFile),
|
||||
LanguageTags = languageTags ?? LanguageParser.ParseLanguageTags(possibleSubtitleFile),
|
||||
Title = title,
|
||||
Language = language,
|
||||
LanguageTags = languageTags,
|
||||
Title = newTitle,
|
||||
Extension = extension,
|
||||
Copy = LanguageParser.CopyFromTitle(title)
|
||||
Copy = copy
|
||||
};
|
||||
|
||||
subtitleFiles.Add(subtitleFile);
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
private static readonly Regex SubtitleLanguageTitleRegex = new Regex(".+?(\\.((?<tags1>full|forced|foreign|default|cc|psdh|sdh)|(?<iso_code>[a-z]{2,3})))*\\.(?<title>[^.]*)(\\.((?<tags2>full|forced|foreign|default|cc|psdh|sdh)|(?<iso_code>[a-z]{2,3})))*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
private static readonly Regex SubtitleTitleRegex = new Regex("(.+ - )?(?<copy>\\d+)", RegexOptions.Compiled);
|
||||
private static readonly Regex SubtitleTitleRegex = new Regex("((?<title>.+) - )?(?<copy>\\d+)", RegexOptions.Compiled);
|
||||
|
||||
public static List<Language> ParseLanguages(string title)
|
||||
{
|
||||
|
@ -254,22 +254,27 @@ namespace NzbDrone.Core.Parser
|
|||
return Language.Unknown;
|
||||
}
|
||||
|
||||
public static (List<string> languageTags, string title) ParseLanguageTagsAndTitle(string fileName, Episode episode)
|
||||
public static (List<string> languageTags, string title, Language language) ParseLanguageTagsAndTitle(string fileName, Episode episode)
|
||||
{
|
||||
var simpleFilename = Path.GetFileNameWithoutExtension(fileName);
|
||||
var matchTitle = SubtitleLanguageTitleRegex.Match(simpleFilename);
|
||||
|
||||
if (matchTitle.Groups["iso_code"].Captures.Count != 1)
|
||||
{
|
||||
throw new ArgumentException("Subtitle file title probably parsed incorrectly, not using.");
|
||||
throw new LanguageParsingException("Subtitle file title probably parsed incorrectly, no language code found, not using.");
|
||||
}
|
||||
|
||||
var isoCode = matchTitle.Groups["iso_code"].Value;
|
||||
var isoLanguage = IsoLanguages.Find(isoCode.ToLower());
|
||||
|
||||
var language = isoLanguage?.Language ?? Language.Unknown;
|
||||
|
||||
var languageTags = matchTitle.Groups["tags1"].Captures
|
||||
.Union(matchTitle.Groups["tags2"].Captures)
|
||||
.Cast<Capture>()
|
||||
.Where(tag => !tag.Value.Empty())
|
||||
.Select(tag => tag.Value.ToLower());
|
||||
var title = matchTitle.Groups["title"].Captures.Cast<Capture>().First().ToString();
|
||||
var title = matchTitle.Groups["title"].Captures.Cast<Capture>().First().Value;
|
||||
|
||||
if (matchTitle.Groups["tags1"].Captures.Empty())
|
||||
{
|
||||
|
@ -279,18 +284,18 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
if (episodeFileTitle.Contains(title, StringComparison.OrdinalIgnoreCase) || originalEpisodeFileTitle.Contains(title, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new ArgumentException("Subtitle file title probably parsed incorrectly, not using.");
|
||||
throw new LanguageParsingException("Subtitle file title probably parsed incorrectly, title contained in episode file, not using.");
|
||||
}
|
||||
}
|
||||
|
||||
return (languageTags.ToList(), title);
|
||||
return (languageTags.ToList(), title, language);
|
||||
}
|
||||
|
||||
public static int CopyFromTitle(string title)
|
||||
public static (int copy, string title) CopyFromTitle(string title)
|
||||
{
|
||||
if (title is null)
|
||||
{
|
||||
return 0;
|
||||
return (0, title);
|
||||
}
|
||||
|
||||
var match = SubtitleTitleRegex.Match(title);
|
||||
|
@ -298,10 +303,12 @@ namespace NzbDrone.Core.Parser
|
|||
if (match.Success)
|
||||
{
|
||||
var copy = match.Groups["copy"].ToString();
|
||||
return int.Parse(copy);
|
||||
var newTitle = match.Groups["title"].Success ? match.Groups["title"].ToString() : null;
|
||||
|
||||
return (int.Parse(copy), newTitle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (0, title);
|
||||
}
|
||||
|
||||
public static List<string> ParseLanguageTags(string fileName)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace NzbDrone.Core.Parser
|
||||
{
|
||||
public class LanguageParsingException : Exception
|
||||
{
|
||||
public LanguageParsingException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue