Browse Source

Merge branch 'dev' of https://github.com/MediaBrowser/Emby into dev

Luke Pulverenti 9 years ago
parent
commit
cb1c958fa0

+ 51 - 15
MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs

@@ -435,21 +435,29 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
 
             var newPath = GetSeasonFolderPath(series, seasonNumber, options);
 
-            var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episode.Name, options);
+            // MAX_PATH - trailing <NULL> charachter - drive component: 260 - 1 - 3 = 256
+            // Usually newPath would include the drive component, but use 256 to be sure
+            var maxFilenameLength = 256 - newPath.Length;
 
-            newPath = Path.Combine(newPath, episodeFileName);
-
-            // Try to account for windows limitations by removing the episode title
-            if (newPath.Length > 255)
+            if (!newPath.EndsWith(@"\"))
             {
-                var extension = Path.GetExtension(episodeFileName);
-                var fileName = Path.GetFileNameWithoutExtension(episodeFileName);
-                fileName = fileName.Replace(episode.Name, string.Empty, StringComparison.OrdinalIgnoreCase);
-                episodeFileName = Path.ChangeExtension(fileName, extension);
+                // Remove 1 for missing backslash combining path and filename
+                maxFilenameLength--;
+            }
 
-                newPath = Path.Combine(newPath, episodeFileName);
+            // Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt)
+            maxFilenameLength -= 4;
+
+            var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber, episodeNumber, endingEpisodeNumber, episode.Name, options, maxFilenameLength);
+
+            if (string.IsNullOrEmpty(episodeFileName))
+            {
+                // cause failure
+                return string.Empty;
             }
 
+            newPath = Path.Combine(newPath, episodeFileName);
+
             return newPath;
         }
 
@@ -492,7 +500,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
             return Path.Combine(path, _fileSystem.GetValidFilename(seasonFolderName));
         }
 
-        private string GetEpisodeFileName(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, string episodeTitle, TvFileOrganizationOptions options)
+        private string GetEpisodeFileName(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, string episodeTitle, TvFileOrganizationOptions options, int? maxLength)
         {
             seriesName = _fileSystem.GetValidFilename(seriesName).Trim();
             episodeTitle = _fileSystem.GetValidFilename(episodeTitle).Trim();
@@ -508,9 +516,9 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
                 .Replace("%0s", seasonNumber.ToString("00", _usCulture))
                 .Replace("%00s", seasonNumber.ToString("000", _usCulture))
                 .Replace("%ext", sourceExtension)
-                .Replace("%en", episodeTitle)
-                .Replace("%e.n", episodeTitle.Replace(" ", "."))
-                .Replace("%e_n", episodeTitle.Replace(" ", "_"));
+                .Replace("%en", "%#1")
+                .Replace("%e.n", "%#2")
+                .Replace("%e_n", "%#3");
 
             if (endingEpisodeNumber.HasValue)
             {
@@ -519,9 +527,37 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
                 .Replace("%00ed", endingEpisodeNumber.Value.ToString("000", _usCulture));
             }
 
-            return result.Replace("%e", episodeNumber.ToString(_usCulture))
+            result = result.Replace("%e", episodeNumber.ToString(_usCulture))
                 .Replace("%0e", episodeNumber.ToString("00", _usCulture))
                 .Replace("%00e", episodeNumber.ToString("000", _usCulture));
+
+            if (maxLength.HasValue && result.Contains("%#"))
+            {
+                // Substract 3 for the temp token length (%#1, %#2 or %#3)  
+                int maxRemainingTitleLength = maxLength.Value - result.Length + 3;
+                string shortenedEpisodeTitle = string.Empty;
+
+                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)
+            {
+                // 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);
+                _logger.Warn(msg);
+                return string.Empty;
+            }
+
+            return result;
         }
 
         private bool IsSameEpisode(string sourcePath, string newPath)