handle invalid filename chars in episode expressions

This commit is contained in:
Luke Pulverenti 2017-03-26 19:36:36 -04:00
parent 8a68c23838
commit 85f4f8dbc9

View File

@ -677,20 +677,7 @@ namespace Emby.Server.Implementations.FileOrganization
var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options); var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options);
// MAX_PATH - trailing <NULL> charachter - drive component: 260 - 1 - 3 = 256 var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber.Value, episodeNumber.Value, endingEpisodeNumber, episodeName, options);
// Usually newPath would include the drive component, but use 256 to be sure
var maxFilenameLength = 256 - newPath.Length;
if (!newPath.EndsWith(@"\"))
{
// Remove 1 for missing backslash combining path and filename
maxFilenameLength--;
}
// Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt)
maxFilenameLength -= 4;
var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber.Value, episodeNumber.Value, endingEpisodeNumber, episodeName, options, maxFilenameLength);
if (string.IsNullOrEmpty(episodeFileName)) if (string.IsNullOrEmpty(episodeFileName))
{ {
@ -742,7 +729,7 @@ namespace Emby.Server.Implementations.FileOrganization
return Path.Combine(path, _fileSystem.GetValidFilename(seasonFolderName)); return Path.Combine(path, _fileSystem.GetValidFilename(seasonFolderName));
} }
private string GetEpisodeFileName(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, string episodeTitle, TvFileOrganizationOptions options, int? maxLength) private string GetEpisodeFileName(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, string episodeTitle, TvFileOrganizationOptions options)
{ {
seriesName = _fileSystem.GetValidFilename(seriesName).Trim(); seriesName = _fileSystem.GetValidFilename(seriesName).Trim();
@ -786,32 +773,15 @@ namespace Emby.Server.Implementations.FileOrganization
.Replace("%0e", episodeNumber.ToString("00", _usCulture)) .Replace("%0e", episodeNumber.ToString("00", _usCulture))
.Replace("%00e", episodeNumber.ToString("000", _usCulture)); .Replace("%00e", episodeNumber.ToString("000", _usCulture));
if (maxLength.HasValue && result.Contains("%#")) if (result.Contains("%#"))
{ {
// Substract 3 for the temp token length (%#1, %#2 or %#3) result = result.Replace("%#1", episodeTitle)
int maxRemainingTitleLength = maxLength.Value - result.Length + 3; .Replace("%#2", episodeTitle.Replace(" ", "."))
string shortenedEpisodeTitle = string.Empty; .Replace("%#3", episodeTitle.Replace(" ", "_"));
if (maxRemainingTitleLength > 5)
{
// A title with fewer than 5 letters wouldn't be of much value
shortenedEpisodeTitle = episodeTitle.Substring(0, Math.Min(maxRemainingTitleLength, episodeTitle.Length));
}
result = result.Replace("%#1", shortenedEpisodeTitle)
.Replace("%#2", shortenedEpisodeTitle.Replace(" ", "."))
.Replace("%#3", shortenedEpisodeTitle.Replace(" ", "_"));
} }
if (maxLength.HasValue && result.Length > maxLength.Value) // Finally, call GetValidFilename again in case user customized the episode expression with any invalid filename characters
{ return _fileSystem.GetValidFilename(result).Trim();
// There may be cases where reducing the title length may still not be sufficient to
// stay below maxLength
var msg = string.Format("Unable to generate an episode file name shorter than {0} characters to constrain to the max path limit", maxLength);
throw new Exception(msg);
}
return result;
} }
private bool IsSameEpisode(string sourcePath, string newPath) private bool IsSameEpisode(string sourcePath, string newPath)