mirror of
https://github.com/Sonarr/Sonarr
synced 2025-12-06 08:28:37 +01:00
Merge 79c4272726 into 1178c98341
This commit is contained in:
commit
a9704b4c73
7 changed files with 44 additions and 22 deletions
|
|
@ -200,6 +200,7 @@ const seriesIdTokens = [
|
|||
const seasonTokens = [
|
||||
{ token: '{season:0}', example: '1' },
|
||||
{ token: '{season:00}', example: '01' },
|
||||
{ token: '{Season Year}', example: '2010' },
|
||||
];
|
||||
|
||||
const episodeTokens = [
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public void Setup()
|
|||
.Returns(@"C:\Test\TV\Series\Season 01\File Name.avi".AsOsAgnostic());
|
||||
|
||||
Mocker.GetMock<IBuildFileNames>()
|
||||
.Setup(s => s.BuildSeasonPath(It.IsAny<Series>(), It.IsAny<int>()))
|
||||
.Setup(s => s.BuildSeasonPath(It.IsAny<Series>(), It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(@"C:\Test\TV\Series\Season 01".AsOsAgnostic());
|
||||
|
||||
var rootFolder = @"C:\Test\TV\".AsOsAgnostic();
|
||||
|
|
@ -112,6 +112,18 @@ public void should_notify_on_season_folder_creation()
|
|||
Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_first_episode_season_and_year()
|
||||
{
|
||||
Subject.MoveEpisodeFile(_episodeFile, _localEpisode);
|
||||
|
||||
Mocker.GetMock<IBuildFileNames>()
|
||||
.Verify(s => s.BuildSeasonPath(
|
||||
_series,
|
||||
_localEpisode.Episodes.First().SeasonNumber,
|
||||
_localEpisode.Episodes.First().AirDateUtc.Value.Year));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_notify_if_series_folder_already_exists()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public void should_replace_reserved_device_name_in_season_folder(string title, s
|
|||
_series.Title = title;
|
||||
_namingConfig.SeasonFolderFormat = "{Series.Title} - Season {Season:00}";
|
||||
|
||||
Subject.GetSeasonFolder(_series, 1).Should().Be($"{expected} - Season 01");
|
||||
Subject.GetSeasonFolder(_series, 1, 2025).Should().Be($"{expected} - Season 01");
|
||||
}
|
||||
|
||||
[TestCase("Con Game", "Con_Game")]
|
||||
|
|
|
|||
|
|
@ -20,16 +20,18 @@ public void Setup()
|
|||
.Setup(c => c.GetConfig()).Returns(_namingConfig);
|
||||
}
|
||||
|
||||
[TestCase("Venture Bros.", 1, "{Series.Title}.{season:00}", "Venture.Bros.01")]
|
||||
[TestCase("Venture Bros.", 1, "{Series Title} Season {season:00}", "Venture Bros. Season 01")]
|
||||
[TestCase("Series Title?", 1, "{Series Title} Season {season:00}", "Series Title! Season 01")]
|
||||
public void should_use_seriesFolderFormat_to_build_folder_name(string seriesTitle, int seasonNumber, string format, string expected)
|
||||
[TestCase("Venture Bros.", 1, null, "{Series.Title}.{season:00}", "Venture.Bros.01")]
|
||||
[TestCase("Venture Bros.", 1, null, "{Series Title} Season {season:00}", "Venture Bros. Season 01")]
|
||||
[TestCase("Series Title?", 1, null, "{Series Title} Season {season:00}", "Series Title! Season 01")]
|
||||
[TestCase("Series Title?", 1, null, "{Series Title} Season {season:00} {(Season Year)}", "Series Title! Season 01")]
|
||||
[TestCase("Series Title?", 1, 2025, "{Series Title} Season {season:00} {(Season Year)}", "Series Title! Season 01 (2025)")]
|
||||
public void should_use_seriesFolderFormat_to_build_folder_name(string seriesTitle, int seasonNumber, int? seasonYear, string format, string expected)
|
||||
{
|
||||
_namingConfig.SeasonFolderFormat = format;
|
||||
|
||||
var series = new Series { Title = seriesTitle };
|
||||
|
||||
Subject.GetSeasonFolder(series, seasonNumber, _namingConfig).Should().Be(expected);
|
||||
Subject.GetSeasonFolder(series, seasonNumber, seasonYear, _namingConfig).Should().Be(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ private EpisodeFile MoveEpisodeFile(EpisodeFile episodeFile, Series series, List
|
|||
{
|
||||
var filePath = _buildFileNames.BuildFilePath(episodes, series, episodeFile, Path.GetExtension(episodeFile.RelativePath));
|
||||
|
||||
EnsureEpisodeFolder(episodeFile, series, episodes.Select(v => v.SeasonNumber).First(), filePath);
|
||||
var firstEpisode = episodes.First();
|
||||
EnsureEpisodeFolder(episodeFile, series, firstEpisode.SeasonNumber, firstEpisode.AirDateUtc?.Year, filePath);
|
||||
|
||||
_logger.Debug("Renaming episode file: {0} to {1}", episodeFile, filePath);
|
||||
|
||||
|
|
@ -176,13 +177,13 @@ private EpisodeFile TransferFile(EpisodeFile episodeFile, Series series, List<Ep
|
|||
|
||||
private void EnsureEpisodeFolder(EpisodeFile episodeFile, LocalEpisode localEpisode, string filePath)
|
||||
{
|
||||
EnsureEpisodeFolder(episodeFile, localEpisode.Series, localEpisode.SeasonNumber, filePath);
|
||||
EnsureEpisodeFolder(episodeFile, localEpisode.Series, localEpisode.SeasonNumber, localEpisode.Episodes.First().AirDateUtc?.Year, filePath);
|
||||
}
|
||||
|
||||
private void EnsureEpisodeFolder(EpisodeFile episodeFile, Series series, int seasonNumber, string filePath)
|
||||
private void EnsureEpisodeFolder(EpisodeFile episodeFile, Series series, int seasonNumber, int? seasonYear, string filePath)
|
||||
{
|
||||
var episodeFolder = Path.GetDirectoryName(filePath);
|
||||
var seasonFolder = _buildFileNames.BuildSeasonPath(series, seasonNumber);
|
||||
var seasonFolder = _buildFileNames.BuildSeasonPath(series, seasonNumber, seasonYear);
|
||||
var seriesFolder = series.Path;
|
||||
var rootFolder = _rootFolderService.GetBestRootFolderPath(seriesFolder);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ public interface IBuildFileNames
|
|||
{
|
||||
string BuildFileName(List<Episode> episodes, Series series, EpisodeFile episodeFile, string extension = "", NamingConfig namingConfig = null, List<CustomFormat> customFormats = null);
|
||||
string BuildFilePath(List<Episode> episodes, Series series, EpisodeFile episodeFile, string extension, NamingConfig namingConfig = null, List<CustomFormat> customFormats = null);
|
||||
string BuildSeasonPath(Series series, int seasonNumber);
|
||||
string BuildSeasonPath(Series series, int seasonNumber, int? seasonYear);
|
||||
string GetSeriesFolder(Series series, NamingConfig namingConfig = null);
|
||||
string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null);
|
||||
string GetSeasonFolder(Series series, int seasonNumber, int? seasonYear, NamingConfig namingConfig = null);
|
||||
bool RequiresEpisodeTitle(Series series, List<Episode> episodes);
|
||||
bool RequiresAbsoluteEpisodeNumber();
|
||||
}
|
||||
|
|
@ -233,20 +233,21 @@ public string BuildFilePath(List<Episode> episodes, Series series, EpisodeFile e
|
|||
{
|
||||
Ensure.That(extension, () => extension).IsNotNullOrWhiteSpace();
|
||||
|
||||
var seasonPath = BuildSeasonPath(series, episodes.First().SeasonNumber);
|
||||
var firstEpisode = episodes.First();
|
||||
var seasonPath = BuildSeasonPath(series, firstEpisode.SeasonNumber, firstEpisode.AirDateUtc?.Year);
|
||||
var remainingPathLength = LongPathSupport.MaxFilePathLength - seasonPath.GetByteCount() - 1;
|
||||
var fileName = BuildFileName(episodes, series, episodeFile, extension, remainingPathLength, namingConfig, customFormats);
|
||||
|
||||
return Path.Combine(seasonPath, fileName);
|
||||
}
|
||||
|
||||
public string BuildSeasonPath(Series series, int seasonNumber)
|
||||
public string BuildSeasonPath(Series series, int seasonNumber, int? seasonYear)
|
||||
{
|
||||
var path = series.Path;
|
||||
|
||||
if (series.SeasonFolder)
|
||||
{
|
||||
var seasonFolder = GetSeasonFolder(series, seasonNumber);
|
||||
var seasonFolder = GetSeasonFolder(series, seasonNumber, seasonYear);
|
||||
|
||||
seasonFolder = CleanFileName(seasonFolder);
|
||||
|
||||
|
|
@ -277,7 +278,7 @@ public string GetSeriesFolder(Series series, NamingConfig namingConfig = null)
|
|||
return folderName;
|
||||
}
|
||||
|
||||
public string GetSeasonFolder(Series series, int seasonNumber, NamingConfig namingConfig = null)
|
||||
public string GetSeasonFolder(Series series, int seasonNumber, int? seasonYear, NamingConfig namingConfig = null)
|
||||
{
|
||||
if (namingConfig == null)
|
||||
{
|
||||
|
|
@ -288,7 +289,7 @@ public string GetSeasonFolder(Series series, int seasonNumber, NamingConfig nami
|
|||
|
||||
AddSeriesTokens(tokenHandlers, series);
|
||||
AddIdTokens(tokenHandlers, series);
|
||||
AddSeasonTokens(tokenHandlers, seasonNumber);
|
||||
AddSeasonTokens(tokenHandlers, seasonNumber, seasonYear);
|
||||
|
||||
var format = seasonNumber == 0 ? namingConfig.SpecialsFolderFormat : namingConfig.SeasonFolderFormat;
|
||||
var folderName = ReplaceTokens(format, tokenHandlers, namingConfig);
|
||||
|
|
@ -516,7 +517,9 @@ private string AddSeasonEpisodeNumberingTokens(string pattern, Dictionary<string
|
|||
tokenHandlers[token] = m => seasonEpisodePattern;
|
||||
}
|
||||
|
||||
AddSeasonTokens(tokenHandlers, episodes.First().SeasonNumber);
|
||||
var firstEpisode = episodes.First();
|
||||
|
||||
AddSeasonTokens(tokenHandlers, firstEpisode.SeasonNumber, firstEpisode.AirDateUtc?.Year);
|
||||
|
||||
if (episodes.Count > 1)
|
||||
{
|
||||
|
|
@ -593,9 +596,10 @@ private string AddAbsoluteNumberingTokens(string pattern, Dictionary<string, Fun
|
|||
return pattern;
|
||||
}
|
||||
|
||||
private void AddSeasonTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int seasonNumber)
|
||||
private void AddSeasonTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, int seasonNumber, int? seasonYear)
|
||||
{
|
||||
tokenHandlers["{Season}"] = m => seasonNumber.ToString(m.CustomFormat);
|
||||
tokenHandlers["{Season Year}"] = m => seasonYear?.ToString(m.CustomFormat) ?? string.Empty;
|
||||
}
|
||||
|
||||
private void AddEpisodeTokens(Dictionary<string, Func<TokenMatch, string>> tokenHandlers, List<Episode> episodes)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.CustomFormats;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
|
@ -80,6 +81,7 @@ public FileNameSampleService(IBuildFileNames buildFileNames)
|
|||
EpisodeNumber = 1,
|
||||
Title = "Episode Title (1)",
|
||||
AirDate = "2013-10-30",
|
||||
AirDateUtc = new(2013, 10, 30, 0, 0, 0, DateTimeKind.Utc),
|
||||
AbsoluteEpisodeNumber = 1,
|
||||
};
|
||||
|
||||
|
|
@ -260,12 +262,12 @@ public string GetSeriesFolderSample(NamingConfig nameSpec)
|
|||
|
||||
public string GetSeasonFolderSample(NamingConfig nameSpec)
|
||||
{
|
||||
return _buildFileNames.GetSeasonFolder(_standardSeries, _episode1.SeasonNumber, nameSpec);
|
||||
return _buildFileNames.GetSeasonFolder(_standardSeries, _episode1.SeasonNumber, _episode1.AirDateUtc?.Year, nameSpec);
|
||||
}
|
||||
|
||||
public string GetSpecialsFolderSample(NamingConfig nameSpec)
|
||||
{
|
||||
return _buildFileNames.GetSeasonFolder(_standardSeries, 0, nameSpec);
|
||||
return _buildFileNames.GetSeasonFolder(_standardSeries, 0, null, nameSpec);
|
||||
}
|
||||
|
||||
private string BuildSample(List<Episode> episodes, Series series, EpisodeFile episodeFile, NamingConfig nameSpec, List<CustomFormat> customFormats)
|
||||
|
|
|
|||
Loading…
Reference in a new issue