2
0
Эх сурвалжийг харах

support parsing itunes info

Luke Pulverenti 9 жил өмнө
parent
commit
5ca2ae6395

+ 211 - 0
MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs

@@ -7,7 +7,10 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Text;
+using System.Xml;
 using CommonIO;
+using MediaBrowser.Controller.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
 
@@ -170,7 +173,215 @@ namespace MediaBrowser.MediaEncoding.Probing
 
         private void FetchFromItunesInfo(string xml, MediaInfo info)
         {
+            // Make things simpler and strip out the dtd
+            xml = xml.Substring(xml.IndexOf("<plist", StringComparison.OrdinalIgnoreCase));
+            xml = "<?xml version=\"1.0\"?>" + xml;
+
             // <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>cast</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blender Foundation</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Janus Bager Kristensen</string>\n\t\t</dict>\n\t</array>\n\t<key>directors</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Sacha Goedegebure</string>\n\t\t</dict>\n\t</array>\n\t<key>studio</key>\n\t<string>Blender Foundation</string>\n</dict>\n</plist>\n
+            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
+            {
+                using (var streamReader = new StreamReader(stream))
+                {
+                    // Use XmlReader for best performance
+                    using (var reader = XmlReader.Create(streamReader))
+                    {
+                        reader.MoveToContent();
+
+                        // Loop through each element
+                        while (reader.Read())
+                        {
+                            if (reader.NodeType == XmlNodeType.Element)
+                            {
+                                switch (reader.Name)
+                                {
+                                    case "dict":
+                                        using (var subtree = reader.ReadSubtree())
+                                        {
+                                            ReadFromDictNode(subtree, info);
+                                        }
+                                        break;
+                                    default:
+                                        reader.Skip();
+                                        break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        private void ReadFromDictNode(XmlReader reader, MediaInfo info)
+        {
+            reader.MoveToContent();
+
+            string currentKey = null;
+            List<NameValuePair> pairs = new List<NameValuePair>();
+
+            // Loop through each element
+            while (reader.Read())
+            {
+                if (reader.NodeType == XmlNodeType.Element)
+                {
+                    switch (reader.Name)
+                    {
+                        case "key":
+                            if (!string.IsNullOrWhiteSpace(currentKey))
+                            {
+                                ProcessPairs(currentKey, pairs, info);
+                            }
+                            currentKey = reader.ReadElementContentAsString();
+                            pairs = new List<NameValuePair>();
+                            break;
+                        case "string":
+                            var value = reader.ReadElementContentAsString();
+                            if (!string.IsNullOrWhiteSpace(value))
+                            {
+                                pairs.Add(new NameValuePair
+                                {
+                                    Name = value,
+                                    Value = value
+                                });
+                            }
+                            break;
+                        case "array":
+                            if (!string.IsNullOrWhiteSpace(currentKey))
+                            {
+                                using (var subtree = reader.ReadSubtree())
+                                {
+                                    pairs.AddRange(ReadValueArray(subtree));
+                                }
+                            }
+                            break;
+                        default:
+                            reader.Skip();
+                            break;
+                    }
+                }
+            }
+        }
+
+        private List<NameValuePair> ReadValueArray(XmlReader reader)
+        {
+            reader.MoveToContent();
+
+            List<NameValuePair> pairs = new List<NameValuePair>();
+
+            // Loop through each element
+            while (reader.Read())
+            {
+                if (reader.NodeType == XmlNodeType.Element)
+                {
+                    switch (reader.Name)
+                    {
+                        case "dict":
+                            using (var subtree = reader.ReadSubtree())
+                            {
+                                var dict = GetNameValuePair(subtree);
+                                if (dict != null)
+                                {
+                                    pairs.Add(dict);
+                                }
+                            }
+                            break;
+                        default:
+                            reader.Skip();
+                            break;
+                    }
+                }
+            }
+
+            return pairs;
+        }
+
+        private void ProcessPairs(string key, List<NameValuePair> pairs, MediaInfo info)
+        {
+            if (string.Equals(key, "studio", StringComparison.OrdinalIgnoreCase))
+            {
+                foreach (var pair in pairs)
+                {
+                    info.Studios.Add(pair.Value);
+                }
+
+                info.Studios = info.Studios
+                    .Where(i => !string.IsNullOrWhiteSpace(i))
+                    .Distinct(StringComparer.OrdinalIgnoreCase)
+                    .ToList();
+
+            }
+            else if (string.Equals(key, "screenwriters", StringComparison.OrdinalIgnoreCase))
+            {
+                foreach (var pair in pairs)
+                {
+                    info.People.Add(new BaseItemPerson
+                    {
+                        Name = pair.Value,
+                        Type = PersonType.Writer
+                    });
+                }
+            }
+            else if (string.Equals(key, "producers", StringComparison.OrdinalIgnoreCase))
+            {
+                foreach (var pair in pairs)
+                {
+                    info.People.Add(new BaseItemPerson
+                    {
+                        Name = pair.Value,
+                        Type = PersonType.Producer
+                    });
+                }
+            }
+            else if (string.Equals(key, "directors", StringComparison.OrdinalIgnoreCase))
+            {
+                foreach (var pair in pairs)
+                {
+                    info.People.Add(new BaseItemPerson
+                    {
+                        Name = pair.Value,
+                        Type = PersonType.Director
+                    });
+                }
+            }
+        }
+
+        private NameValuePair GetNameValuePair(XmlReader reader)
+        {
+            reader.MoveToContent();
+
+            string name = null;
+            string value = null;
+
+            // Loop through each element
+            while (reader.Read())
+            {
+                if (reader.NodeType == XmlNodeType.Element)
+                {
+                    switch (reader.Name)
+                    {
+                        case "key":
+                            name = reader.ReadElementContentAsString();
+                            break;
+                        case "string":
+                            value = reader.ReadElementContentAsString();
+                            break;
+                        default:
+                            reader.Skip();
+                            break;
+                    }
+                }
+            }
+
+            if (string.IsNullOrWhiteSpace(name) ||
+                string.IsNullOrWhiteSpace(value))
+            {
+                return null;
+            }
+
+            return new NameValuePair
+            {
+                Name = name,
+                Value = value
+            };
         }
 
         /// <summary>