mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-03 19:17:24 -05:00 
			
		
		
		
	Fully async'd xml parsing process as well as added resolver and provider priorities
This commit is contained in:
		
							parent
							
								
									19a4dd83c2
								
							
						
					
					
						commit
						8f024e8199
					
				@ -99,8 +99,13 @@ namespace MediaBrowser.Common.Kernel
 | 
			
		||||
            IEnumerable<Assembly> pluginAssemblies = Directory.GetFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.AllDirectories).Select(f => Assembly.Load(File.ReadAllBytes((f))));
 | 
			
		||||
 | 
			
		||||
            var catalog = new AggregateCatalog(pluginAssemblies.Select(a => new AssemblyCatalog(a)));
 | 
			
		||||
            
 | 
			
		||||
            // Include composable parts in the Common assembly 
 | 
			
		||||
            // Uncomment this if it's ever needed
 | 
			
		||||
            //catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
 | 
			
		||||
            //catalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly));
 | 
			
		||||
            
 | 
			
		||||
            // Include composable parts in the subclass assembly
 | 
			
		||||
            catalog.Catalogs.Add(new AssemblyCatalog(GetType().Assembly));
 | 
			
		||||
 | 
			
		||||
            var container = new CompositionContainer(catalog);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -86,42 +86,10 @@ namespace MediaBrowser.Controller
 | 
			
		||||
 | 
			
		||||
        protected override void OnComposablePartsLoaded()
 | 
			
		||||
        {
 | 
			
		||||
            AddCoreResolvers();
 | 
			
		||||
            AddCoreProviders();
 | 
			
		||||
 | 
			
		||||
            // The base class will start up all the plugins
 | 
			
		||||
            base.OnComposablePartsLoaded();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddCoreResolvers()
 | 
			
		||||
        {
 | 
			
		||||
            List<IBaseItemResolver> list = EntityResolvers.ToList();
 | 
			
		||||
 | 
			
		||||
            // Add the core resolvers
 | 
			
		||||
            list.AddRange(new IBaseItemResolver[]{
 | 
			
		||||
                new AudioResolver(),
 | 
			
		||||
                new VideoResolver(),
 | 
			
		||||
                new VirtualFolderResolver(),
 | 
			
		||||
                new FolderResolver()
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            EntityResolvers = list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddCoreProviders()
 | 
			
		||||
        {
 | 
			
		||||
            List<BaseMetadataProvider> list = MetadataProviders.ToList();
 | 
			
		||||
 | 
			
		||||
            // Add the core resolvers
 | 
			
		||||
            list.InsertRange(0, new BaseMetadataProvider[]{
 | 
			
		||||
                new ImageFromMediaLocationProvider(),
 | 
			
		||||
                new LocalTrailerProvider(),
 | 
			
		||||
                new AudioInfoProvider(),
 | 
			
		||||
                new FolderProviderFromXml()
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            MetadataProviders = list;
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
            // Initialize the metadata providers
 | 
			
		||||
            Parallel.ForEach(MetadataProviders, provider =>
 | 
			
		||||
            {
 | 
			
		||||
                provider.Init();
 | 
			
		||||
@ -264,19 +232,43 @@ namespace MediaBrowser.Controller
 | 
			
		||||
            // Get all supported providers
 | 
			
		||||
            var supportedProviders = Kernel.Instance.MetadataProviders.Where(i => i.Supports(item));
 | 
			
		||||
 | 
			
		||||
            // Start with non-internet providers. Run them sequentially
 | 
			
		||||
            foreach (BaseMetadataProvider provider in supportedProviders.Where(i => !i.RequiresInternet))
 | 
			
		||||
            // First priority providers
 | 
			
		||||
            var providers = supportedProviders.Where(i => !i.RequiresInternet && i.Priority == MetadataProviderPriority.First);
 | 
			
		||||
            
 | 
			
		||||
            if (providers.Any())
 | 
			
		||||
            {
 | 
			
		||||
                await provider.Fetch(item, args);
 | 
			
		||||
                await Task.WhenAll(
 | 
			
		||||
                    providers.Select(i => i.Fetch(item, args))
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var internetProviders = supportedProviders.Where(i => i.RequiresInternet);
 | 
			
		||||
            // Second priority providers
 | 
			
		||||
            providers = supportedProviders.Where(i => !i.RequiresInternet && i.Priority == MetadataProviderPriority.Second);
 | 
			
		||||
 | 
			
		||||
            if (internetProviders.Any())
 | 
			
		||||
            if (providers.Any())
 | 
			
		||||
            {
 | 
			
		||||
                // Now execute internet providers in parallel
 | 
			
		||||
                await Task.WhenAll(
 | 
			
		||||
                    internetProviders.Select(i => i.Fetch(item, args))
 | 
			
		||||
                    providers.Select(i => i.Fetch(item, args))
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Lowest priority providers
 | 
			
		||||
            providers = supportedProviders.Where(i => !i.RequiresInternet && i.Priority == MetadataProviderPriority.Last);
 | 
			
		||||
 | 
			
		||||
            if (providers.Any())
 | 
			
		||||
            {
 | 
			
		||||
                await Task.WhenAll(
 | 
			
		||||
                    providers.Select(i => i.Fetch(item, args))
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // Execute internet providers
 | 
			
		||||
            providers = supportedProviders.Where(i => i.RequiresInternet);
 | 
			
		||||
 | 
			
		||||
            if (providers.Any())
 | 
			
		||||
            {
 | 
			
		||||
                await Task.WhenAll(
 | 
			
		||||
                    providers.Select(i => i.Fetch(item, args))
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -59,8 +59,8 @@ namespace MediaBrowser.Controller.Library
 | 
			
		||||
 | 
			
		||||
        private async Task<BaseItem> ResolveItem(ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            // If that didn't pan out, try the slow ones
 | 
			
		||||
            foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers)
 | 
			
		||||
            // Try first priority resolvers
 | 
			
		||||
            foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.First))
 | 
			
		||||
            {
 | 
			
		||||
                var item = await resolver.ResolvePath(args);
 | 
			
		||||
 | 
			
		||||
@ -70,6 +70,39 @@ namespace MediaBrowser.Controller.Library
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Try second priority resolvers
 | 
			
		||||
            foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Second))
 | 
			
		||||
            {
 | 
			
		||||
                var item = await resolver.ResolvePath(args);
 | 
			
		||||
 | 
			
		||||
                if (item != null)
 | 
			
		||||
                {
 | 
			
		||||
                    return item;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Try third priority resolvers
 | 
			
		||||
            foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Third))
 | 
			
		||||
            {
 | 
			
		||||
                var item = await resolver.ResolvePath(args);
 | 
			
		||||
 | 
			
		||||
                if (item != null)
 | 
			
		||||
                {
 | 
			
		||||
                    return item;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Try last priority resolvers
 | 
			
		||||
            foreach (IBaseItemResolver resolver in Kernel.Instance.EntityResolvers.Where(p => p.Priority == ResolverPriority.Last))
 | 
			
		||||
            {
 | 
			
		||||
                var item = await resolver.ResolvePath(args);
 | 
			
		||||
 | 
			
		||||
                if (item != null)
 | 
			
		||||
                {
 | 
			
		||||
                    return item;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -153,7 +186,7 @@ namespace MediaBrowser.Controller.Library
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            BaseItem[] baseItemChildren = await Task<BaseItem>.WhenAll(tasks);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // Sort them
 | 
			
		||||
            folder.Children = baseItemChildren.Where(i => i != null).OrderBy(f =>
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,11 @@ namespace MediaBrowser.Controller.Providers
 | 
			
		||||
            return item is Audio;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            Audio audio = item as Audio;
 | 
			
		||||
 | 
			
		||||
@ -32,5 +32,22 @@ namespace MediaBrowser.Controller.Providers
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public abstract Task Fetch(BaseEntity item, ItemResolveEventArgs args);
 | 
			
		||||
 | 
			
		||||
        public abstract MetadataProviderPriority Priority { get; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Determines when a provider should execute, relative to others
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum MetadataProviderPriority
 | 
			
		||||
    {
 | 
			
		||||
        // Run this provider at the beginning
 | 
			
		||||
        First,
 | 
			
		||||
 | 
			
		||||
        // Run this provider after all first priority providers
 | 
			
		||||
        Second,
 | 
			
		||||
 | 
			
		||||
        // Run this provider last
 | 
			
		||||
        Last
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,11 @@ namespace MediaBrowser.Controller.Providers
 | 
			
		||||
            return item is Folder;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            var metadataFile = args.GetFileByName("folder.xml");
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,12 @@ namespace MediaBrowser.Controller.Providers
 | 
			
		||||
        {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.Run(() =>
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,11 @@ namespace MediaBrowser.Controller.Providers
 | 
			
		||||
            return item is BaseItem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            BaseItem baseItem = item as BaseItem;
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,11 @@ namespace MediaBrowser.Controller.Resolvers
 | 
			
		||||
    [Export(typeof(IBaseItemResolver))]
 | 
			
		||||
    public class AudioResolver : BaseItemResolver<Audio>
 | 
			
		||||
    {
 | 
			
		||||
        public override ResolverPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return ResolverPriority.Last; }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        protected override Audio Resolve(ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            // Return audio if the path is a file and has a matching extension
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,14 @@ namespace MediaBrowser.Controller.Resolvers
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual ResolverPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return ResolverPriority.First;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Sets initial values on the newly resolved item
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@ -89,5 +97,14 @@ namespace MediaBrowser.Controller.Resolvers
 | 
			
		||||
    public interface IBaseItemResolver
 | 
			
		||||
    {
 | 
			
		||||
        Task<BaseItem> ResolvePath(ItemResolveEventArgs args);
 | 
			
		||||
        ResolverPriority Priority { get; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum ResolverPriority
 | 
			
		||||
    {
 | 
			
		||||
        First,
 | 
			
		||||
        Second,
 | 
			
		||||
        Third,
 | 
			
		||||
        Last
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,11 @@ namespace MediaBrowser.Controller.Resolvers
 | 
			
		||||
    [Export(typeof(IBaseItemResolver))]
 | 
			
		||||
    public class FolderResolver : BaseFolderResolver<Folder>
 | 
			
		||||
    {
 | 
			
		||||
        public override ResolverPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return ResolverPriority.Last; }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        protected override Folder Resolve(ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            if (args.IsFolder)
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,10 @@ namespace MediaBrowser.Controller.Resolvers
 | 
			
		||||
    [Export(typeof(IBaseItemResolver))]
 | 
			
		||||
    public class VideoResolver : BaseVideoResolver<Video>
 | 
			
		||||
    {
 | 
			
		||||
        public override ResolverPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return ResolverPriority.Last; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,11 @@ namespace MediaBrowser.Controller.Resolvers
 | 
			
		||||
    [Export(typeof(IBaseItemResolver))]
 | 
			
		||||
    public class VirtualFolderResolver : BaseFolderResolver<VirtualFolder>
 | 
			
		||||
    {
 | 
			
		||||
        public override ResolverPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return ResolverPriority.Third; }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        protected override VirtualFolder Resolve(ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            if (args.IsFolder && args.Parent != null && args.Parent.IsRoot)
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                {
 | 
			
		||||
                    if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                    {
 | 
			
		||||
                        FetchDataFromXmlNode(reader, item);
 | 
			
		||||
                        await FetchDataFromXmlNode(reader, item);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -49,14 +49,14 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Fetches metadata from one Xml Element
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected virtual void FetchDataFromXmlNode(XmlReader reader, T item)
 | 
			
		||||
        protected async virtual Task FetchDataFromXmlNode(XmlReader reader, T item)
 | 
			
		||||
        {
 | 
			
		||||
            switch (reader.Name)
 | 
			
		||||
            {
 | 
			
		||||
                // DateCreated
 | 
			
		||||
                case "Added":
 | 
			
		||||
                    DateTime added;
 | 
			
		||||
                    if (DateTime.TryParse(reader.ReadString() ?? string.Empty, out added))
 | 
			
		||||
                    if (DateTime.TryParse(await reader.ReadElementContentAsStringAsync() ?? string.Empty, out added))
 | 
			
		||||
                    {
 | 
			
		||||
                        item.DateCreated = added;
 | 
			
		||||
                    }
 | 
			
		||||
@ -65,7 +65,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                // DisplayMediaType
 | 
			
		||||
                case "Type":
 | 
			
		||||
                    {
 | 
			
		||||
                        item.DisplayMediaType = reader.ReadString();
 | 
			
		||||
                        item.DisplayMediaType = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        switch (item.DisplayMediaType.ToLower())
 | 
			
		||||
                        {
 | 
			
		||||
@ -85,26 +85,26 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
 | 
			
		||||
                // TODO: Do we still need this?
 | 
			
		||||
                case "banner":
 | 
			
		||||
                    item.BannerImagePath = reader.ReadString();
 | 
			
		||||
                    item.BannerImagePath = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "LocalTitle":
 | 
			
		||||
                    item.Name = reader.ReadString();
 | 
			
		||||
                    item.Name = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "SortTitle":
 | 
			
		||||
                    item.SortName = reader.ReadString();
 | 
			
		||||
                    item.SortName = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Overview":
 | 
			
		||||
                case "Description":
 | 
			
		||||
                    item.Overview = reader.ReadString();
 | 
			
		||||
                    item.Overview = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "TagLine":
 | 
			
		||||
                    {
 | 
			
		||||
                        var list = (item.Taglines ?? new string[] { }).ToList();
 | 
			
		||||
                        var tagline = reader.ReadString();
 | 
			
		||||
                        var tagline = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!list.Contains(tagline))
 | 
			
		||||
                        {
 | 
			
		||||
@ -117,23 +117,23 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
 | 
			
		||||
                case "TagLines":
 | 
			
		||||
                    {
 | 
			
		||||
                        FetchFromTaglinesNode(reader.ReadSubtree(), item);
 | 
			
		||||
                        await FetchFromTaglinesNode(reader.ReadSubtree(), item);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                case "ContentRating":
 | 
			
		||||
                case "MPAARating":
 | 
			
		||||
                    item.OfficialRating = reader.ReadString();
 | 
			
		||||
                    item.OfficialRating = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "CustomRating":
 | 
			
		||||
                    item.CustomRating = reader.ReadString();
 | 
			
		||||
                    item.CustomRating = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Runtime":
 | 
			
		||||
                case "RunningTime":
 | 
			
		||||
                    {
 | 
			
		||||
                        string text = reader.ReadString();
 | 
			
		||||
                        string text = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(text))
 | 
			
		||||
                        {
 | 
			
		||||
@ -149,20 +149,20 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                case "Genre":
 | 
			
		||||
                    {
 | 
			
		||||
                        var genres = (item.Genres ?? new string[] { }).ToList();
 | 
			
		||||
                        genres.AddRange(GetSplitValues(reader.ReadString(), '|'));
 | 
			
		||||
                        genres.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|'));
 | 
			
		||||
 | 
			
		||||
                        item.Genres = genres;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                case "AspectRatio":
 | 
			
		||||
                    item.AspectRatio = reader.ReadString();
 | 
			
		||||
                    item.AspectRatio = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Network":
 | 
			
		||||
                    {
 | 
			
		||||
                        var studios = (item.Studios ?? new string[] { }).ToList();
 | 
			
		||||
                        studios.AddRange(GetSplitValues(reader.ReadString(), '|'));
 | 
			
		||||
                        studios.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|'));
 | 
			
		||||
 | 
			
		||||
                        item.Studios = studios;
 | 
			
		||||
                        break;
 | 
			
		||||
@ -171,7 +171,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                case "Director":
 | 
			
		||||
                    {
 | 
			
		||||
                        var list = (item.People ?? new PersonInfo[] { }).ToList();
 | 
			
		||||
                        list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Director" }));
 | 
			
		||||
                        list.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|').Select(v => new PersonInfo() { Name = v, Type = "Director" }));
 | 
			
		||||
 | 
			
		||||
                        item.People = list;
 | 
			
		||||
                        break;
 | 
			
		||||
@ -179,7 +179,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                case "Writer":
 | 
			
		||||
                    {
 | 
			
		||||
                        var list = (item.People ?? new PersonInfo[] { }).ToList();
 | 
			
		||||
                        list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Writer" }));
 | 
			
		||||
                        list.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|').Select(v => new PersonInfo() { Name = v, Type = "Writer" }));
 | 
			
		||||
 | 
			
		||||
                        item.People = list;
 | 
			
		||||
                        break;
 | 
			
		||||
@ -189,19 +189,19 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                case "GuestStars":
 | 
			
		||||
                    {
 | 
			
		||||
                        var list = (item.People ?? new PersonInfo[] { }).ToList();
 | 
			
		||||
                        list.AddRange(GetSplitValues(reader.ReadString(), '|').Select(v => new PersonInfo() { Name = v, Type = "Actor" }));
 | 
			
		||||
                        list.AddRange(GetSplitValues(await reader.ReadElementContentAsStringAsync(), '|').Select(v => new PersonInfo() { Name = v, Type = "Actor" }));
 | 
			
		||||
 | 
			
		||||
                        item.People = list;
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                case "Trailer":
 | 
			
		||||
                    item.TrailerUrl = reader.ReadString();
 | 
			
		||||
                    item.TrailerUrl = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "ProductionYear":
 | 
			
		||||
                    {
 | 
			
		||||
                        string val = reader.ReadString();
 | 
			
		||||
                        string val = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(val))
 | 
			
		||||
                        {
 | 
			
		||||
@ -218,7 +218,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                case "Rating":
 | 
			
		||||
                case "IMDBrating":
 | 
			
		||||
 | 
			
		||||
                    string rating = reader.ReadString();
 | 
			
		||||
                    string rating = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(rating))
 | 
			
		||||
                    {
 | 
			
		||||
@ -233,7 +233,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
 | 
			
		||||
                case "FirstAired":
 | 
			
		||||
                    {
 | 
			
		||||
                        string firstAired = reader.ReadString();
 | 
			
		||||
                        string firstAired = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(firstAired))
 | 
			
		||||
                        {
 | 
			
		||||
@ -250,7 +250,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                case "TMDbId":
 | 
			
		||||
                    string tmdb = reader.ReadString();
 | 
			
		||||
                    string tmdb = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(tmdb))
 | 
			
		||||
                    {
 | 
			
		||||
                        item.SetProviderId(MetadataProviders.Tmdb, tmdb);
 | 
			
		||||
@ -258,7 +258,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "TVcomId":
 | 
			
		||||
                    string TVcomId = reader.ReadString();
 | 
			
		||||
                    string TVcomId = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(TVcomId))
 | 
			
		||||
                    {
 | 
			
		||||
                        item.SetProviderId(MetadataProviders.Tvcom, TVcomId);
 | 
			
		||||
@ -268,7 +268,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                case "IMDB_ID":
 | 
			
		||||
                case "IMDB":
 | 
			
		||||
                case "IMDbId":
 | 
			
		||||
                    string IMDbId = reader.ReadString();
 | 
			
		||||
                    string IMDbId = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(IMDbId))
 | 
			
		||||
                    {
 | 
			
		||||
                        item.SetProviderId(MetadataProviders.Imdb, IMDbId);
 | 
			
		||||
@ -276,46 +276,43 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Genres":
 | 
			
		||||
                    FetchFromGenresNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    await FetchFromGenresNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Persons":
 | 
			
		||||
                    FetchDataFromPersonsNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    await FetchDataFromPersonsNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "ParentalRating":
 | 
			
		||||
                    FetchFromParentalRatingNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    await FetchFromParentalRatingNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Studios":
 | 
			
		||||
                    FetchFromStudiosNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    await FetchFromStudiosNode(reader.ReadSubtree(), item);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "MediaInfo":
 | 
			
		||||
                    FetchMediaInfo(reader.ReadSubtree(), item);
 | 
			
		||||
                    break;
 | 
			
		||||
                    {
 | 
			
		||||
                        var video = item as Video;
 | 
			
		||||
 | 
			
		||||
                        if (video != null)
 | 
			
		||||
                        {
 | 
			
		||||
                            await FetchMediaInfo(reader.ReadSubtree(), video);
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    reader.Skip();
 | 
			
		||||
                    await reader.SkipAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchMediaInfo(XmlReader reader, T item)
 | 
			
		||||
        private async Task FetchMediaInfo(XmlReader reader, Video item)
 | 
			
		||||
        {
 | 
			
		||||
            var video = item as Video;
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            if (video != null)
 | 
			
		||||
            {
 | 
			
		||||
                FetchMediaInfo(reader, video);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchMediaInfo(XmlReader reader, Video item)
 | 
			
		||||
        {
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
@ -323,7 +320,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Audio":
 | 
			
		||||
                            {
 | 
			
		||||
                                AudioStream stream = FetchMediaInfoAudio(reader.ReadSubtree());
 | 
			
		||||
                                AudioStream stream = await FetchMediaInfoAudio(reader.ReadSubtree());
 | 
			
		||||
 | 
			
		||||
                                List<AudioStream> streams = (item.AudioStreams ?? new AudioStream[] { }).ToList();
 | 
			
		||||
                                streams.Add(stream);
 | 
			
		||||
@ -333,56 +330,56 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        case "Video":
 | 
			
		||||
                            FetchMediaInfoVideo(reader.ReadSubtree(), item);
 | 
			
		||||
                            await FetchMediaInfoVideo(reader.ReadSubtree(), item);
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Subtitle":
 | 
			
		||||
                            FetchMediaInfoSubtitles(reader.ReadSubtree(), item);
 | 
			
		||||
                            await FetchMediaInfoSubtitles(reader.ReadSubtree(), item);
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private AudioStream FetchMediaInfoAudio(XmlReader reader)
 | 
			
		||||
        private async Task<AudioStream> FetchMediaInfoAudio(XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            AudioStream stream = new AudioStream();
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
                    switch (reader.Name)
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Default":
 | 
			
		||||
                            stream.IsDefault = reader.ReadString() == "True";
 | 
			
		||||
                            stream.IsDefault = await reader.ReadElementContentAsStringAsync() == "True";
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Forced":
 | 
			
		||||
                            stream.IsForced = reader.ReadString() == "True";
 | 
			
		||||
                            stream.IsForced = await reader.ReadElementContentAsStringAsync() == "True";
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "BitRate":
 | 
			
		||||
                            stream.BitRate = reader.ReadIntSafe();
 | 
			
		||||
                            stream.BitRate = await reader.ReadIntSafe();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Channels":
 | 
			
		||||
                            stream.Channels = reader.ReadIntSafe();
 | 
			
		||||
                            stream.Channels = await reader.ReadIntSafe();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Language":
 | 
			
		||||
                            stream.Language = reader.ReadString();
 | 
			
		||||
                            stream.Language = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Codec":
 | 
			
		||||
                            {
 | 
			
		||||
                                string codec = reader.ReadString();
 | 
			
		||||
                                string codec = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                                switch (codec.ToLower())
 | 
			
		||||
                                {
 | 
			
		||||
@ -430,7 +427,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -439,42 +436,42 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
            return stream;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchMediaInfoVideo(XmlReader reader, Video item)
 | 
			
		||||
        private async Task FetchMediaInfoVideo(XmlReader reader, Video item)
 | 
			
		||||
        {
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
                    switch (reader.Name)
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Width":
 | 
			
		||||
                            item.Width = reader.ReadIntSafe();
 | 
			
		||||
                            item.Width = await reader.ReadIntSafe();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Height":
 | 
			
		||||
                            item.Height = reader.ReadIntSafe();
 | 
			
		||||
                            item.Height = await reader.ReadIntSafe();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "BitRate":
 | 
			
		||||
                            item.BitRate = reader.ReadIntSafe();
 | 
			
		||||
                            item.BitRate = await reader.ReadIntSafe();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "FrameRate":
 | 
			
		||||
                            item.FrameRate = reader.ReadString();
 | 
			
		||||
                            item.FrameRate = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "ScanType":
 | 
			
		||||
                            item.ScanType = reader.ReadString();
 | 
			
		||||
                            item.ScanType = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Duration":
 | 
			
		||||
                            item.RunTimeTicks = TimeSpan.FromMinutes(reader.ReadIntSafe()).Ticks;
 | 
			
		||||
                            item.RunTimeTicks = TimeSpan.FromMinutes(await reader.ReadIntSafe()).Ticks;
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "DurationSeconds":
 | 
			
		||||
                            int seconds = reader.ReadIntSafe();
 | 
			
		||||
                            int seconds = await reader.ReadIntSafe();
 | 
			
		||||
                            if (seconds > 0)
 | 
			
		||||
                            {
 | 
			
		||||
                                item.RunTimeTicks = TimeSpan.FromSeconds(seconds).Ticks;
 | 
			
		||||
@ -483,7 +480,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
 | 
			
		||||
                        case "Codec":
 | 
			
		||||
                            {
 | 
			
		||||
                                string videoCodec = reader.ReadString();
 | 
			
		||||
                                string videoCodec = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                                switch (videoCodec.ToLower())
 | 
			
		||||
                                {
 | 
			
		||||
@ -505,20 +502,20 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchMediaInfoSubtitles(XmlReader reader, Video item)
 | 
			
		||||
        private async Task FetchMediaInfoSubtitles(XmlReader reader, Video item)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> list = (item.Subtitles ?? new string[] { }).ToList();
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
@ -526,7 +523,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Language":
 | 
			
		||||
                            {
 | 
			
		||||
                                string genre = reader.ReadString();
 | 
			
		||||
                                string genre = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                                if (!string.IsNullOrWhiteSpace(genre))
 | 
			
		||||
                                {
 | 
			
		||||
@ -536,7 +533,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -545,13 +542,13 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
            item.Subtitles = list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchFromTaglinesNode(XmlReader reader, T item)
 | 
			
		||||
        private async Task FetchFromTaglinesNode(XmlReader reader, T item)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> list = (item.Taglines ?? new string[] { }).ToList();
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
@ -559,7 +556,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Tagline":
 | 
			
		||||
                            {
 | 
			
		||||
                                string val = reader.ReadString();
 | 
			
		||||
                                string val = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                                if (!string.IsNullOrWhiteSpace(val))
 | 
			
		||||
                                {
 | 
			
		||||
@ -569,7 +566,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -578,13 +575,13 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
            item.Taglines = list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchFromGenresNode(XmlReader reader, T item)
 | 
			
		||||
        private async Task FetchFromGenresNode(XmlReader reader, T item)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> list = (item.Genres ?? new string[] { }).ToList();
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
@ -592,7 +589,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Genre":
 | 
			
		||||
                            {
 | 
			
		||||
                                string genre = reader.ReadString();
 | 
			
		||||
                                string genre = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                                if (!string.IsNullOrWhiteSpace(genre))
 | 
			
		||||
                                {
 | 
			
		||||
@ -602,7 +599,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -611,13 +608,13 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
            item.Genres = list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchDataFromPersonsNode(XmlReader reader, T item)
 | 
			
		||||
        private async Task FetchDataFromPersonsNode(XmlReader reader, T item)
 | 
			
		||||
        {
 | 
			
		||||
            List<PersonInfo> list = (item.People ?? new PersonInfo[] { }).ToList();
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
@ -625,12 +622,12 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Person":
 | 
			
		||||
                            {
 | 
			
		||||
                                list.Add(GetPersonFromXmlNode(reader.ReadSubtree()));
 | 
			
		||||
                                list.Add(await GetPersonFromXmlNode(reader.ReadSubtree()));
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -639,13 +636,13 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
            item.People = list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchFromStudiosNode(XmlReader reader, T item)
 | 
			
		||||
        private async Task FetchFromStudiosNode(XmlReader reader, T item)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> list = (item.Studios ?? new string[] { }).ToList();
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
@ -653,7 +650,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Studio":
 | 
			
		||||
                            {
 | 
			
		||||
                                string studio = reader.ReadString();
 | 
			
		||||
                                string studio = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                                if (!string.IsNullOrWhiteSpace(studio))
 | 
			
		||||
                                {
 | 
			
		||||
@ -663,7 +660,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -672,11 +669,11 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
            item.Studios = list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchFromParentalRatingNode(XmlReader reader, T item)
 | 
			
		||||
        private async Task FetchFromParentalRatingNode(XmlReader reader, T item)
 | 
			
		||||
        {
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
@ -684,7 +681,7 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Value":
 | 
			
		||||
                            {
 | 
			
		||||
                                string ratingString = reader.ReadString();
 | 
			
		||||
                                string ratingString = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                                int rating = 7;
 | 
			
		||||
 | 
			
		||||
@ -723,39 +720,39 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private PersonInfo GetPersonFromXmlNode(XmlReader reader)
 | 
			
		||||
        private async Task<PersonInfo> GetPersonFromXmlNode(XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            PersonInfo person = new PersonInfo();
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            await reader.MoveToContentAsync();
 | 
			
		||||
 | 
			
		||||
            while (reader.Read())
 | 
			
		||||
            while (await reader.ReadAsync())
 | 
			
		||||
            {
 | 
			
		||||
                if (reader.NodeType == XmlNodeType.Element)
 | 
			
		||||
                {
 | 
			
		||||
                    switch (reader.Name)
 | 
			
		||||
                    {
 | 
			
		||||
                        case "Name":
 | 
			
		||||
                            person.Name = reader.ReadString();
 | 
			
		||||
                            person.Name = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Type":
 | 
			
		||||
                            person.Type = reader.ReadString();
 | 
			
		||||
                            person.Type = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        case "Role":
 | 
			
		||||
                            person.Overview = reader.ReadString();
 | 
			
		||||
                            person.Overview = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            await reader.SkipAsync();
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.Controller.Xml
 | 
			
		||||
@ -10,9 +11,9 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Reads a float from the current element of an XmlReader
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static float ReadFloatSafe(this XmlReader reader)
 | 
			
		||||
        public static async Task<float> ReadFloatSafe(this XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            string valueString = reader.ReadElementContentAsString();
 | 
			
		||||
            string valueString = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
            float value = 0;
 | 
			
		||||
 | 
			
		||||
@ -28,9 +29,9 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Reads an int from the current element of an XmlReader
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static int ReadIntSafe(this XmlReader reader)
 | 
			
		||||
        public static async Task<int> ReadIntSafe(this XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            string valueString = reader.ReadElementContentAsString();
 | 
			
		||||
            string valueString = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
            int value = 0;
 | 
			
		||||
 | 
			
		||||
@ -42,13 +43,5 @@ namespace MediaBrowser.Controller.Xml
 | 
			
		||||
 | 
			
		||||
            return value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Reads an int from the current element of an XmlReader
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string ReadString(this XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            return reader.ReadElementContentAsString();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,11 @@ namespace MediaBrowser.Movies.Providers
 | 
			
		||||
            return item is Movie;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            var metadataFile = args.GetFileByName("movie.xml");
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using MediaBrowser.Controller.Xml;
 | 
			
		||||
using MediaBrowser.TV.Entities;
 | 
			
		||||
@ -7,13 +8,13 @@ namespace MediaBrowser.TV.Metadata
 | 
			
		||||
{
 | 
			
		||||
    public class EpisodeXmlParser : BaseItemXmlParser<Episode>
 | 
			
		||||
    {
 | 
			
		||||
        protected override void FetchDataFromXmlNode(XmlReader reader, Episode item)
 | 
			
		||||
        protected override async Task FetchDataFromXmlNode(XmlReader reader, Episode item)
 | 
			
		||||
        {
 | 
			
		||||
            switch (reader.Name)
 | 
			
		||||
            {
 | 
			
		||||
                case "filename":
 | 
			
		||||
                    {
 | 
			
		||||
                        string filename = reader.ReadString();
 | 
			
		||||
                        string filename = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(filename))
 | 
			
		||||
                        {
 | 
			
		||||
@ -24,7 +25,7 @@ namespace MediaBrowser.TV.Metadata
 | 
			
		||||
                    }
 | 
			
		||||
                case "SeasonNumber":
 | 
			
		||||
                    {
 | 
			
		||||
                        string number = reader.ReadString();
 | 
			
		||||
                        string number = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(number))
 | 
			
		||||
                        {
 | 
			
		||||
@ -35,7 +36,7 @@ namespace MediaBrowser.TV.Metadata
 | 
			
		||||
 | 
			
		||||
                case "EpisodeNumber":
 | 
			
		||||
                    {
 | 
			
		||||
                        string number = reader.ReadString();
 | 
			
		||||
                        string number = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(number))
 | 
			
		||||
                        {
 | 
			
		||||
@ -45,11 +46,11 @@ namespace MediaBrowser.TV.Metadata
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                case "EpisodeName":
 | 
			
		||||
                    item.Name = reader.ReadString();
 | 
			
		||||
                    item.Name = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    base.FetchDataFromXmlNode(reader, item);
 | 
			
		||||
                    await base.FetchDataFromXmlNode(reader, item);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using MediaBrowser.Controller.Xml;
 | 
			
		||||
using MediaBrowser.Model.Entities;
 | 
			
		||||
@ -8,12 +9,12 @@ namespace MediaBrowser.TV.Metadata
 | 
			
		||||
{
 | 
			
		||||
    public class SeriesXmlParser : BaseItemXmlParser<Series>
 | 
			
		||||
    {
 | 
			
		||||
        protected override void FetchDataFromXmlNode(XmlReader reader, Series item)
 | 
			
		||||
        protected async override Task FetchDataFromXmlNode(XmlReader reader, Series item)
 | 
			
		||||
        {
 | 
			
		||||
            switch (reader.Name)
 | 
			
		||||
            {
 | 
			
		||||
                case "id":
 | 
			
		||||
                    string id = reader.ReadString();
 | 
			
		||||
                    string id = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(id))
 | 
			
		||||
                    {
 | 
			
		||||
                        item.SetProviderId(MetadataProviders.Tvdb, id);
 | 
			
		||||
@ -22,7 +23,7 @@ namespace MediaBrowser.TV.Metadata
 | 
			
		||||
 | 
			
		||||
                case "Airs_DayOfWeek":
 | 
			
		||||
                    {
 | 
			
		||||
                        string day = reader.ReadString();
 | 
			
		||||
                        string day = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(day))
 | 
			
		||||
                        {
 | 
			
		||||
@ -50,19 +51,19 @@ namespace MediaBrowser.TV.Metadata
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                case "Airs_Time":
 | 
			
		||||
                    item.AirTime = reader.ReadString();
 | 
			
		||||
                    item.AirTime = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "SeriesName":
 | 
			
		||||
                    item.Name = reader.ReadString();
 | 
			
		||||
                    item.Name = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Status":
 | 
			
		||||
                    item.Status = reader.ReadString();
 | 
			
		||||
                    item.Status = await reader.ReadElementContentAsStringAsync();
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    base.FetchDataFromXmlNode(reader, item);
 | 
			
		||||
                    await base.FetchDataFromXmlNode(reader, item);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,11 @@ namespace MediaBrowser.TV.Providers
 | 
			
		||||
            return item is Episode;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            return Task.Run(() =>
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,11 @@ namespace MediaBrowser.TV.Providers
 | 
			
		||||
            return item is Episode;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            string metadataFolder = Path.Combine(args.Parent.Path, "metadata");
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,11 @@ namespace MediaBrowser.TV.Providers
 | 
			
		||||
            return item is Series;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override MetadataProviderPriority Priority
 | 
			
		||||
        {
 | 
			
		||||
            get { return MetadataProviderPriority.First; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async override Task Fetch(BaseEntity item, ItemResolveEventArgs args)
 | 
			
		||||
        {
 | 
			
		||||
            var metadataFile = args.GetFileByName("series.xml");
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user