mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
Merge pull request #141 from Sonarr/multi-episode-range
Various naming fixes
This commit is contained in:
commit
f214e5cb25
@ -82,6 +82,7 @@ private JsonResponse<NamingSampleResource> GetExamples(NamingConfigResource conf
|
||||
var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec);
|
||||
var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec);
|
||||
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
|
||||
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
|
||||
|
||||
sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null
|
||||
? "Invalid format"
|
||||
@ -99,6 +100,10 @@ private JsonResponse<NamingSampleResource> GetExamples(NamingConfigResource conf
|
||||
? "Invalid format"
|
||||
: animeEpisodeSampleResult.FileName;
|
||||
|
||||
sampleResource.AnimeMultiEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult) != null
|
||||
? "Invalid format"
|
||||
: animeMultiEpisodeSampleResult.FileName;
|
||||
|
||||
sampleResource.SeriesFolderExample = nameSpec.SeriesFolderFormat.IsNullOrWhiteSpace()
|
||||
? "Invalid format"
|
||||
: _filenameSampleService.GetSeriesFolderSample(nameSpec);
|
||||
@ -115,26 +120,22 @@ private void ValidateFormatResult(NamingConfig nameSpec)
|
||||
var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec);
|
||||
var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec);
|
||||
var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec);
|
||||
var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec);
|
||||
var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec);
|
||||
|
||||
var singleEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult);
|
||||
var multiEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult);
|
||||
var dailyEpisodeValidationResult = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult);
|
||||
var animeEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult);
|
||||
var animeMultiEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult);
|
||||
|
||||
var validationFailures = new List<ValidationFailure>();
|
||||
|
||||
if (singleEpisodeValidationResult != null)
|
||||
{
|
||||
validationFailures.Add(singleEpisodeValidationResult);
|
||||
}
|
||||
|
||||
if (multiEpisodeValidationResult != null)
|
||||
{
|
||||
validationFailures.Add(multiEpisodeValidationResult);
|
||||
}
|
||||
|
||||
if (dailyEpisodeValidationResult != null)
|
||||
{
|
||||
validationFailures.Add(dailyEpisodeValidationResult);
|
||||
}
|
||||
validationFailures.AddIfNotNull(singleEpisodeValidationResult);
|
||||
validationFailures.AddIfNotNull(multiEpisodeValidationResult);
|
||||
validationFailures.AddIfNotNull(dailyEpisodeValidationResult);
|
||||
validationFailures.AddIfNotNull(animeEpisodeValidationResult);
|
||||
validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult);
|
||||
|
||||
if (validationFailures.Any())
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ public class NamingSampleResource
|
||||
public string MultiEpisodeExample { get; set; }
|
||||
public string DailyEpisodeExample { get; set; }
|
||||
public string AnimeEpisodeExample { get; set; }
|
||||
public string AnimeMultiEpisodeExample { get; set; }
|
||||
public string SeriesFolderExample { get; set; }
|
||||
public string SeasonFolderExample { get; set; }
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ public class FileNameBuilderFixture : CoreTest<FileNameBuilder>
|
||||
private Series _series;
|
||||
private Episode _episode1;
|
||||
private Episode _episode2;
|
||||
private Episode _episode3;
|
||||
private EpisodeFile _episodeFile;
|
||||
private NamingConfig _namingConfig;
|
||||
|
||||
@ -53,6 +54,13 @@ public void Setup()
|
||||
.With(e => e.AbsoluteEpisodeNumber = 101)
|
||||
.Build();
|
||||
|
||||
_episode3 = Builder<Episode>.CreateNew()
|
||||
.With(e => e.Title = "City Sushi")
|
||||
.With(e => e.SeasonNumber = 15)
|
||||
.With(e => e.EpisodeNumber = 8)
|
||||
.With(e => e.AbsoluteEpisodeNumber = 102)
|
||||
.Build();
|
||||
|
||||
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "DRONE" };
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>()
|
||||
@ -549,8 +557,8 @@ public void should_duplicate_absolute_pattern_when_multi_episode_style_is_duplic
|
||||
_namingConfig.MultiEpisodeStyle = (int)MultiEpisodeStyle.Duplicate;
|
||||
_namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}";
|
||||
|
||||
Subject.BuildFileName(new List<Episode> { _episode1, _episode2 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - 100 - 101 - City Sushi");
|
||||
Subject.BuildFileName(new List<Episode> { _episode1, _episode2, _episode3 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - 100 - 101 - 102 - City Sushi");
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -682,5 +690,59 @@ public void should_default_to_dash_when_serparator_is_not_set_for_absolute_numbe
|
||||
Subject.BuildFileName(new List<Episode> { _episode1, _episode2 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - 15x06 - 15x07 - [100-101] - City Sushi - HDTV-720p");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_range_multi_episode_properly()
|
||||
{
|
||||
_namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}";
|
||||
_namingConfig.MultiEpisodeStyle = 4;
|
||||
|
||||
Subject.BuildFileName(new List<Episode> { _episode1, _episode2, _episode3 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - S15E06-08 - City Sushi");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_range_multi_episode_anime_properly()
|
||||
{
|
||||
_series.SeriesType = SeriesTypes.Anime;
|
||||
_namingConfig.MultiEpisodeStyle = 4;
|
||||
_namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}";
|
||||
|
||||
Subject.BuildFileName(new List<Episode> { _episode1, _episode2, _episode3 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - 100-102 - City Sushi");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_repeat_multi_episode_anime_properly()
|
||||
{
|
||||
_series.SeriesType = SeriesTypes.Anime;
|
||||
_namingConfig.MultiEpisodeStyle = 2;
|
||||
_namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}";
|
||||
|
||||
Subject.BuildFileName(new List<Episode> { _episode1, _episode2, _episode3 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - 100-101-102 - City Sushi");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_single_episode_with_range_multi_episode_properly()
|
||||
{
|
||||
_namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}";
|
||||
_namingConfig.MultiEpisodeStyle = 4;
|
||||
|
||||
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - S15E06 - City Sushi");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_format_single_anime_episode_with_range_multi_episode_properly()
|
||||
{
|
||||
_series.SeriesType = SeriesTypes.Anime;
|
||||
_namingConfig.MultiEpisodeStyle = 4;
|
||||
_namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}";
|
||||
|
||||
Subject.BuildFileName(new List<Episode> { _episode1 }, _series, _episodeFile)
|
||||
.Should().Be("South Park - 100 - City Sushi");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -97,6 +97,7 @@ public void should_parse_absolute_specials(String postTitle, String title, Int32
|
||||
|
||||
[TestCase("[ANBU-AonE]_Naruto_26-27_[F224EF26].avi", "Naruto", new[] { 26, 27 })]
|
||||
[TestCase("[Doutei] Recently, My Sister is Unusual - 01-12 [BD][720p-AAC]", "Recently, My Sister is Unusual", new [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 })]
|
||||
[TestCase("Series Title (2010) - 01-02-03 - Episode Title (1) HDTV-720p", "Series Title (2010)", new [] { 1, 2, 3 })]
|
||||
public void should_parse_multi_episode_absolute_numbers(string postTitle, string title, int[] absoluteEpisodeNumbers)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
|
@ -280,32 +280,41 @@ private String AddSeasonEpisodeNumberingTokens(String pattern, Dictionary<String
|
||||
foreach (var episodeFormat in episodeFormats)
|
||||
{
|
||||
var seasonEpisodePattern = episodeFormat.SeasonEpisodePattern;
|
||||
string formatPattern;
|
||||
|
||||
foreach (var episode in episodes.Skip(1))
|
||||
switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle)
|
||||
{
|
||||
switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle)
|
||||
{
|
||||
case MultiEpisodeStyle.Duplicate:
|
||||
seasonEpisodePattern += episodeFormat.Separator + episodeFormat.SeasonEpisodePattern;
|
||||
break;
|
||||
case MultiEpisodeStyle.Duplicate:
|
||||
formatPattern = episodeFormat.Separator + episodeFormat.SeasonEpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Repeat:
|
||||
seasonEpisodePattern += episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern;
|
||||
break;
|
||||
case MultiEpisodeStyle.Repeat:
|
||||
formatPattern = episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Scene:
|
||||
seasonEpisodePattern += "-" + episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern;
|
||||
break;
|
||||
case MultiEpisodeStyle.Scene:
|
||||
formatPattern = "-" + episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
//MultiEpisodeStyle.Extend
|
||||
default:
|
||||
seasonEpisodePattern += "-" + episodeFormat.EpisodePattern;
|
||||
break;
|
||||
}
|
||||
case MultiEpisodeStyle.Range:
|
||||
formatPattern = "-" + episodeFormat.EpisodePattern;
|
||||
var eps = new List<Episode> { episodes.First() };
|
||||
|
||||
if (episodes.Count > 1) eps.Add(episodes.Last());
|
||||
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, eps);
|
||||
break;
|
||||
|
||||
//MultiEpisodeStyle.Extend
|
||||
default:
|
||||
formatPattern = "-" + episodeFormat.EpisodePattern;
|
||||
seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
}
|
||||
|
||||
seasonEpisodePattern = ReplaceNumberTokens(seasonEpisodePattern, episodes);
|
||||
|
||||
var token = String.Format("{{Season Episode{0}}}", index++);
|
||||
pattern = pattern.Replace(episodeFormat.SeasonEpisodePattern, token);
|
||||
tokenHandlers[token] = m => seasonEpisodePattern;
|
||||
@ -339,34 +348,44 @@ private String AddAbsoluteNumberingTokens(String pattern, Dictionary<String, Fun
|
||||
}
|
||||
|
||||
var absoluteEpisodePattern = absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
string formatPattern;
|
||||
|
||||
foreach (var episode in episodes.Skip(1))
|
||||
switch ((MultiEpisodeStyle) namingConfig.MultiEpisodeStyle)
|
||||
{
|
||||
switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle)
|
||||
{
|
||||
case MultiEpisodeStyle.Duplicate:
|
||||
absoluteEpisodePattern += absoluteEpisodeFormat.Separator +
|
||||
absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Repeat:
|
||||
absoluteEpisodePattern += absoluteEpisodeFormat.Separator +
|
||||
absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
break;
|
||||
case MultiEpisodeStyle.Duplicate:
|
||||
formatPattern = absoluteEpisodeFormat.Separator + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Scene:
|
||||
absoluteEpisodePattern += "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
break;
|
||||
case MultiEpisodeStyle.Repeat:
|
||||
var repeatSeparator = absoluteEpisodeFormat.Separator.Trim().IsNullOrWhiteSpace() ? " " : absoluteEpisodeFormat.Separator.Trim();
|
||||
|
||||
formatPattern = repeatSeparator + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Scene:
|
||||
formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
|
||||
case MultiEpisodeStyle.Range:
|
||||
formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
var eps = new List<Episode> {episodes.First()};
|
||||
|
||||
if (episodes.Count > 1) eps.Add(episodes.Last());
|
||||
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, eps);
|
||||
break;
|
||||
|
||||
//MultiEpisodeStyle.Extend
|
||||
default:
|
||||
absoluteEpisodePattern += "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern;
|
||||
absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes);
|
||||
break;
|
||||
}
|
||||
|
||||
absoluteEpisodePattern = ReplaceAbsoluteNumberTokens(absoluteEpisodePattern, episodes);
|
||||
|
||||
var token = String.Format("{{Absolute Pattern{0}}}", index++);
|
||||
pattern = pattern.Replace(absoluteEpisodeFormat.AbsoluteEpisodePattern, token);
|
||||
tokenHandlers[token] = m => absoluteEpisodePattern;
|
||||
@ -554,31 +573,30 @@ private string ReplaceToken(Match match, Dictionary<String, Func<TokenMatch, Str
|
||||
return replacementText;
|
||||
}
|
||||
|
||||
private string ReplaceNumberTokens(string pattern, List<Episode> episodes)
|
||||
private string FormatNumberTokens(string basePattern, string formatPattern, List<Episode> episodes)
|
||||
{
|
||||
var episodeIndex = 0;
|
||||
pattern = EpisodeRegex.Replace(pattern, match =>
|
||||
{
|
||||
var episode = episodes[episodeIndex];
|
||||
episodeIndex++;
|
||||
var pattern = String.Empty;
|
||||
|
||||
return ReplaceNumberToken(match.Groups["episode"].Value, episode.EpisodeNumber);
|
||||
});
|
||||
for (int i = 0; i < episodes.Count; i++)
|
||||
{
|
||||
var patternToReplace = i == 0 ? basePattern : formatPattern;
|
||||
|
||||
pattern += EpisodeRegex.Replace(patternToReplace, match => ReplaceNumberToken(match.Groups["episode"].Value, episodes[i].EpisodeNumber));
|
||||
}
|
||||
|
||||
return ReplaceSeasonTokens(pattern, episodes.First().SeasonNumber);
|
||||
}
|
||||
|
||||
private string ReplaceAbsoluteNumberTokens(string pattern, List<Episode> episodes)
|
||||
private string FormatAbsoluteNumberTokens(string basePattern, string formatPattern, List<Episode> episodes)
|
||||
{
|
||||
var episodeIndex = 0;
|
||||
pattern = AbsoluteEpisodeRegex.Replace(pattern, match =>
|
||||
{
|
||||
var episode = episodes[episodeIndex];
|
||||
episodeIndex++;
|
||||
var pattern = String.Empty;
|
||||
|
||||
//TODO: We need to handle this null check somewhere, I think earlier is better...
|
||||
return ReplaceNumberToken(match.Groups["absolute"].Value, episode.AbsoluteEpisodeNumber.Value);
|
||||
});
|
||||
for (int i = 0; i < episodes.Count; i++)
|
||||
{
|
||||
var patternToReplace = i == 0 ? basePattern : formatPattern;
|
||||
|
||||
pattern += AbsoluteEpisodeRegex.Replace(patternToReplace, match => ReplaceNumberToken(match.Groups["absolute"].Value, episodes[i].AbsoluteEpisodeNumber.Value));
|
||||
}
|
||||
|
||||
return ReplaceSeasonTokens(pattern, episodes.First().SeasonNumber);
|
||||
}
|
||||
@ -684,6 +702,7 @@ public enum MultiEpisodeStyle
|
||||
Extend = 0,
|
||||
Duplicate = 1,
|
||||
Repeat = 2,
|
||||
Scene = 3
|
||||
Scene = 3,
|
||||
Range = 4
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ public interface IFilenameSampleService
|
||||
SampleResult GetMultiEpisodeSample(NamingConfig nameSpec);
|
||||
SampleResult GetDailySample(NamingConfig nameSpec);
|
||||
SampleResult GetAnimeSample(NamingConfig nameSpec);
|
||||
SampleResult GetAnimeMultiEpisodeSample(NamingConfig nameSpec);
|
||||
String GetSeriesFolderSample(NamingConfig nameSpec);
|
||||
String GetSeasonFolderSample(NamingConfig nameSpec);
|
||||
}
|
||||
@ -25,12 +26,14 @@ public class FileNameSampleService : IFilenameSampleService
|
||||
private static Series _animeSeries;
|
||||
private static Episode _episode1;
|
||||
private static Episode _episode2;
|
||||
private static Episode _episode3;
|
||||
private static List<Episode> _singleEpisode;
|
||||
private static List<Episode> _multiEpisodes;
|
||||
private static EpisodeFile _singleEpisodeFile;
|
||||
private static EpisodeFile _multiEpisodeFile;
|
||||
private static EpisodeFile _dailyEpisodeFile;
|
||||
private static EpisodeFile _animeEpisodeFile;
|
||||
private static EpisodeFile _animeMultiEpisodeFile;
|
||||
|
||||
public FileNameSampleService(IBuildFileNames buildFileNames)
|
||||
{
|
||||
@ -71,8 +74,16 @@ public FileNameSampleService(IBuildFileNames buildFileNames)
|
||||
AbsoluteEpisodeNumber = 2
|
||||
};
|
||||
|
||||
_episode3 = new Episode
|
||||
{
|
||||
SeasonNumber = 1,
|
||||
EpisodeNumber = 3,
|
||||
Title = "Episode Title (3)",
|
||||
AbsoluteEpisodeNumber = 3
|
||||
};
|
||||
|
||||
_singleEpisode = new List<Episode> { _episode1 };
|
||||
_multiEpisodes = new List<Episode> { _episode1, _episode2 };
|
||||
_multiEpisodes = new List<Episode> { _episode1, _episode2, _episode3 };
|
||||
|
||||
var mediaInfo = new MediaInfoModel()
|
||||
{
|
||||
@ -102,8 +113,8 @@ public FileNameSampleService(IBuildFileNames buildFileNames)
|
||||
_multiEpisodeFile = new EpisodeFile
|
||||
{
|
||||
Quality = new QualityModel(Quality.HDTV720p),
|
||||
RelativePath = "Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv",
|
||||
SceneName = "Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE",
|
||||
RelativePath = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE.mkv",
|
||||
SceneName = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE",
|
||||
ReleaseGroup = "RlsGrp",
|
||||
MediaInfo = mediaInfo,
|
||||
};
|
||||
@ -120,8 +131,17 @@ public FileNameSampleService(IBuildFileNames buildFileNames)
|
||||
_animeEpisodeFile = new EpisodeFile
|
||||
{
|
||||
Quality = new QualityModel(Quality.HDTV720p),
|
||||
RelativePath = "Series.Title.001.HDTV.x264-EVOLVE.mkv",
|
||||
SceneName = "Series.Title.001.HDTV.x264-EVOLVE",
|
||||
RelativePath = "[RlsGroup] Series Title - 001 [720p].mkv",
|
||||
SceneName = "[RlsGroup] Series Title - 001 [720p]",
|
||||
ReleaseGroup = "RlsGrp",
|
||||
MediaInfo = mediaInfoAnime
|
||||
};
|
||||
|
||||
_animeMultiEpisodeFile = new EpisodeFile
|
||||
{
|
||||
Quality = new QualityModel(Quality.HDTV720p),
|
||||
RelativePath = "[RlsGroup] Series Title - 001 - 103 [720p].mkv",
|
||||
SceneName = "[RlsGroup] Series Title - 001 - 103 [720p]",
|
||||
ReleaseGroup = "RlsGrp",
|
||||
MediaInfo = mediaInfoAnime
|
||||
};
|
||||
@ -179,6 +199,19 @@ public SampleResult GetAnimeSample(NamingConfig nameSpec)
|
||||
return result;
|
||||
}
|
||||
|
||||
public SampleResult GetAnimeMultiEpisodeSample(NamingConfig nameSpec)
|
||||
{
|
||||
var result = new SampleResult
|
||||
{
|
||||
FileName = BuildSample(_multiEpisodes, _animeSeries, _animeMultiEpisodeFile, nameSpec),
|
||||
Series = _animeSeries,
|
||||
Episodes = _multiEpisodes,
|
||||
EpisodeFile = _animeMultiEpisodeFile
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetSeriesFolderSample(NamingConfig nameSpec)
|
||||
{
|
||||
return _buildFileNames.GetSeriesFolder(_standardSeries, nameSpec);
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentValidation.Results;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
@ -87,7 +87,7 @@ public static class Parser
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Episodes with airdate
|
||||
new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])",
|
||||
new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])(?!\W+[0-3][0-9])",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||
|
||||
//Supports 1103/1113 naming
|
||||
|
@ -13,16 +13,17 @@ define(
|
||||
template: 'Settings/MediaManagement/Naming/NamingViewTemplate',
|
||||
|
||||
ui: {
|
||||
namingOptions : '.x-naming-options',
|
||||
renameEpisodesCheckbox: '.x-rename-episodes',
|
||||
singleEpisodeExample : '.x-single-episode-example',
|
||||
multiEpisodeExample : '.x-multi-episode-example',
|
||||
dailyEpisodeExample : '.x-daily-episode-example',
|
||||
animeEpisodeExample : '.x-anime-episode-example',
|
||||
namingTokenHelper : '.x-naming-token-helper',
|
||||
multiEpisodeStyle : '.x-multi-episode-style',
|
||||
seriesFolderExample : '.x-series-folder-example',
|
||||
seasonFolderExample : '.x-season-folder-example'
|
||||
namingOptions : '.x-naming-options',
|
||||
renameEpisodesCheckbox : '.x-rename-episodes',
|
||||
singleEpisodeExample : '.x-single-episode-example',
|
||||
multiEpisodeExample : '.x-multi-episode-example',
|
||||
dailyEpisodeExample : '.x-daily-episode-example',
|
||||
animeEpisodeExample : '.x-anime-episode-example',
|
||||
animeMultiEpisodeExample : '.x-anime-multi-episode-example',
|
||||
namingTokenHelper : '.x-naming-token-helper',
|
||||
multiEpisodeStyle : '.x-multi-episode-style',
|
||||
seriesFolderExample : '.x-series-folder-example',
|
||||
seasonFolderExample : '.x-season-folder-example'
|
||||
},
|
||||
|
||||
events: {
|
||||
@ -70,6 +71,7 @@ define(
|
||||
this.ui.multiEpisodeExample.html(this.namingSampleModel.get('multiEpisodeExample'));
|
||||
this.ui.dailyEpisodeExample.html(this.namingSampleModel.get('dailyEpisodeExample'));
|
||||
this.ui.animeEpisodeExample.html(this.namingSampleModel.get('animeEpisodeExample'));
|
||||
this.ui.animeMultiEpisodeExample.html(this.namingSampleModel.get('animeMultiEpisodeExample'));
|
||||
this.ui.seriesFolderExample.html(this.namingSampleModel.get('seriesFolderExample'));
|
||||
this.ui.seasonFolderExample.html(this.namingSampleModel.get('seasonFolderExample'));
|
||||
},
|
||||
|
@ -175,6 +175,7 @@
|
||||
<option value="1">Duplicate</option>
|
||||
<option value="2">Repeat</option>
|
||||
<option value="3">Scene</option>
|
||||
<option value="4">Range</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@ -212,6 +213,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Anime Multi-Episode Example</label>
|
||||
|
||||
<div class="col-sm-8">
|
||||
<p class="form-control-static x-anime-multi-episode-example naming-example"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Series Folder Example</label>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user