Răsfoiți Sursa

Merge pull request #2906 from randrey/dlna-nullref-fix

Fix InvalidOperationException while browsing via DLNA client.
Joshua M. Boniface 5 ani în urmă
părinte
comite
ca4b6836c1
1 a modificat fișierele cu 72 adăugiri și 30 ștergeri
  1. 72 30
      Emby.Dlna/Didl/DidlBuilder.cs

+ 72 - 30
Emby.Dlna/Didl/DidlBuilder.cs

@@ -425,57 +425,99 @@ namespace Emby.Dlna.Didl
                 }
                 }
             }
             }
 
 
-            if (item is Episode episode && context is Season season)
+            return item is Episode episode
+                ? GetEpisodeDisplayName(episode, context)
+                : item.Name;
+        }
+
+        /// <summary>
+        /// Gets episode display name appropriate for the given context.
+        /// </summary>
+        /// <remarks>
+        /// If context is a season, this will return a string containing just episode number and name.
+        /// Otherwise the result will include series nams and season number.
+        /// </remarks>
+        /// <param name="episode">The episode.</param>
+        /// <param name="context">Current context.</param>
+        /// <returns>Formatted name of the episode.</returns>
+        private string GetEpisodeDisplayName(Episode episode, BaseItem context)
+        {
+            string[] components;
+
+            if (context is Season season)
             {
             {
                 // This is a special embedded within a season
                 // This is a special embedded within a season
-                if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0
+                if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value == 0
                     && season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
                     && season.IndexNumber.HasValue && season.IndexNumber.Value != 0)
                 {
                 {
                     return string.Format(
                     return string.Format(
                         CultureInfo.InvariantCulture,
                         CultureInfo.InvariantCulture,
                         _localization.GetLocalizedString("ValueSpecialEpisodeName"),
                         _localization.GetLocalizedString("ValueSpecialEpisodeName"),
-                        item.Name);
+                        episode.Name);
                 }
                 }
 
 
-                if (item.IndexNumber.HasValue)
-                {
-                    var number = item.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
+                // inside a season use simple format (ex. '12 - Episode Name')
+                var epNumberName = GetEpisodeIndexFullName(episode);
+                components = new[] { epNumberName, episode.Name };
+            }
+            else
+            {
+                // outside a season include series and season details (ex. 'TV Show - S05E11 - Episode Name')
+                var epNumberName = GetEpisodeNumberDisplayName(episode);
+                components = new[] { episode.SeriesName, epNumberName, episode.Name };
+            }
 
 
-                    if (episode.IndexNumberEnd.HasValue)
-                    {
-                        number += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture);
-                    }
+            return string.Join(" - ", components.Where(NotNullOrWhiteSpace));
+        }
 
 
-                    return number + " - " + item.Name;
-                }
-            }
-            else if (item is Episode ep)
+        /// <summary>
+        /// Gets complete episode number.
+        /// </summary>
+        /// <param name="episode">The episode.</param>
+        /// <returns>For single episodes returns just the number. For double episodes - current and ending numbers.</returns>
+        private string GetEpisodeIndexFullName(Episode episode)
+        {
+            var name = string.Empty;
+            if (episode.IndexNumber.HasValue)
             {
             {
-                var parent = ep.GetParent();
-                var name = parent.Name + " - ";
+                name += episode.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
 
 
-                if (ep.ParentIndexNumber.HasValue)
-                {
-                    name += "S" + ep.ParentIndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
-                }
-                else if (!item.IndexNumber.HasValue)
+                if (episode.IndexNumberEnd.HasValue)
                 {
                 {
-                    return name + " - " + item.Name;
+                    name += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture);
                 }
                 }
+            }
 
 
-                name += "E" + ep.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture);
-                if (ep.IndexNumberEnd.HasValue)
-                {
-                    name += "-" + ep.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture);
-                }
+            return name;
+        }
 
 
-                name += " - " + item.Name;
-                return name;
+        /// <summary>
+        /// Gets episode number formatted as 'S##E##'.
+        /// </summary>
+        /// <param name="episode">The episode.</param>
+        /// <returns>Formatted episode number.</returns>
+        private string GetEpisodeNumberDisplayName(Episode episode)
+        {
+            var name = string.Empty;
+            var seasonNumber = episode.Season?.IndexNumber;
+
+            if (seasonNumber.HasValue)
+            {
+                name = "S" + seasonNumber.Value.ToString("00", CultureInfo.InvariantCulture);
+            }
+
+            var indexName = GetEpisodeIndexFullName(episode);
+
+            if (!string.IsNullOrWhiteSpace(indexName))
+            {
+                name += "E" + indexName;
             }
             }
 
 
-            return item.Name;
+            return name;
         }
         }
 
 
+        private bool NotNullOrWhiteSpace(string s) => !string.IsNullOrWhiteSpace(s);
+
         private void AddAudioResource(XmlWriter writer, BaseItem audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
         private void AddAudioResource(XmlWriter writer, BaseItem audio, string deviceId, Filter filter, StreamInfo streamInfo = null)
         {
         {
             writer.WriteStartElement(string.Empty, "res", NS_DIDL);
             writer.WriteStartElement(string.Empty, "res", NS_DIDL);