mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-04 03:27:21 -05:00 
			
		
		
		
	Remove warnings from MediaBrowser.LocalMetadata
This commit is contained in:
		
							parent
							
								
									403cd3205f
								
							
						
					
					
						commit
						14f32b4927
					
				@ -7,12 +7,43 @@ using MediaBrowser.Model.IO;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// The BaseXmlProvider.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <typeparam name="T">Type of provider.</typeparam>
 | 
			
		||||
    public abstract class BaseXmlProvider<T> : ILocalMetadataProvider<T>, IHasItemChangeMonitor, IHasOrder
 | 
			
		||||
        where T : BaseItem, new()
 | 
			
		||||
    {
 | 
			
		||||
        protected IFileSystem FileSystem;
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="BaseXmlProvider{T}"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        protected BaseXmlProvider(IFileSystem fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
            this.FileSystem = fileSystem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<MetadataResult<T>> GetMetadata(ItemInfo info,
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public string Name => XmlProviderUtils.Name;
 | 
			
		||||
 | 
			
		||||
        /// After Nfo
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public virtual int Order => 1;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the IFileSystem.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected IFileSystem FileSystem { get; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets metadata for item.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="info">The item info.</param>
 | 
			
		||||
        /// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
 | 
			
		||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
			
		||||
        /// <returns>The metadata for item.</returns>
 | 
			
		||||
        public Task<MetadataResult<T>> GetMetadata(
 | 
			
		||||
            ItemInfo info,
 | 
			
		||||
            IDirectoryService directoryService,
 | 
			
		||||
            CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
@ -46,15 +77,23 @@ namespace MediaBrowser.LocalMetadata
 | 
			
		||||
            return Task.FromResult(result);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get metadata from path.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="result">Resulting metadata.</param>
 | 
			
		||||
        /// <param name="path">The path.</param>
 | 
			
		||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
			
		||||
        protected abstract void Fetch(MetadataResult<T> result, string path, CancellationToken cancellationToken);
 | 
			
		||||
 | 
			
		||||
        protected BaseXmlProvider(IFileSystem fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
            FileSystem = fileSystem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get metadata from xml file.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="info">Item inf.</param>
 | 
			
		||||
        /// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
 | 
			
		||||
        /// <returns>The file system metadata.</returns>
 | 
			
		||||
        protected abstract FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService);
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public bool HasChanged(BaseItem item, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            var file = GetXmlFile(new ItemInfo(item), directoryService);
 | 
			
		||||
@ -66,15 +105,5 @@ namespace MediaBrowser.LocalMetadata
 | 
			
		||||
 | 
			
		||||
            return file.Exists && FileSystem.GetLastWriteTimeUtc(file) > item.DateLastSaved;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Name => XmlProviderUtils.Name;
 | 
			
		||||
 | 
			
		||||
        //After Nfo
 | 
			
		||||
        public virtual int Order => 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static class XmlProviderUtils
 | 
			
		||||
    {
 | 
			
		||||
        public static string Name => "Emby Xml";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,30 +5,41 @@ using MediaBrowser.Model.IO;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Collection folder local image provider.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class CollectionFolderLocalImageProvider : ILocalImageProvider, IHasOrder
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IFileSystem _fileSystem;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="CollectionFolderLocalImageProvider"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        public CollectionFolderLocalImageProvider(IFileSystem fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
            _fileSystem = fileSystem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public string Name => "Collection Folder Images";
 | 
			
		||||
 | 
			
		||||
        /// Run after LocalImageProvider
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public int Order => 1;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public bool Supports(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            return item is CollectionFolder && item.SupportsLocalMetadata;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Run after LocalImageProvider
 | 
			
		||||
        public int Order => 1;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            var collectionFolder = (CollectionFolder)item;
 | 
			
		||||
 | 
			
		||||
            return new LocalImageProvider(_fileSystem).GetImages(item, collectionFolder.PhysicalLocations, true, directoryService);
 | 
			
		||||
            return new LocalImageProvider(_fileSystem).GetImages(item, collectionFolder.PhysicalLocations, directoryService);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -10,24 +10,35 @@ using MediaBrowser.Model.IO;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
{
 | 
			
		||||
    public class EpisodeLocalLocalImageProvider : ILocalImageProvider, IHasOrder
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Episode local local local image provider.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class EpisodeLocalImageProvider : ILocalImageProvider, IHasOrder
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IFileSystem _fileSystem;
 | 
			
		||||
 | 
			
		||||
        public EpisodeLocalLocalImageProvider(IFileSystem fileSystem)
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="EpisodeLocalImageProvider"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        public EpisodeLocalImageProvider(IFileSystem fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
            _fileSystem = fileSystem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public string Name => "Local Images";
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public int Order => 0;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public bool Supports(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            return item is Episode && item.SupportsLocalMetadata;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            var parentPath = Path.GetDirectoryName(item.Path);
 | 
			
		||||
@ -58,23 +69,15 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
 | 
			
		||||
                    if (string.Equals(filenameWithoutExtension, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
                    {
 | 
			
		||||
                        list.Add(new LocalImageInfo
 | 
			
		||||
                        {
 | 
			
		||||
                            FileInfo = i,
 | 
			
		||||
                            Type = ImageType.Primary
 | 
			
		||||
                        });
 | 
			
		||||
                        list.Add(new LocalImageInfo { FileInfo = i, Type = ImageType.Primary });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    else if (string.Equals(thumbName, currentNameWithoutExtension, StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
                    {
 | 
			
		||||
                        list.Add(new LocalImageInfo
 | 
			
		||||
                        {
 | 
			
		||||
                            FileInfo = i,
 | 
			
		||||
                            Type = ImageType.Primary
 | 
			
		||||
                        });
 | 
			
		||||
                        list.Add(new LocalImageInfo { FileInfo = i, Type = ImageType.Primary });
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return list;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -9,12 +9,21 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Internal metadata folder image provider.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class InternalMetadataFolderImageProvider : ILocalImageProvider, IHasOrder
 | 
			
		||||
    {
 | 
			
		||||
        private readonly IServerConfigurationManager _config;
 | 
			
		||||
        private readonly IFileSystem _fileSystem;
 | 
			
		||||
        private readonly ILogger<InternalMetadataFolderImageProvider> _logger;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="InternalMetadataFolderImageProvider"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="config">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{InternalMetadataFolderImageProvider}"/> interface.</param>
 | 
			
		||||
        public InternalMetadataFolderImageProvider(
 | 
			
		||||
            IServerConfigurationManager config,
 | 
			
		||||
            IFileSystem fileSystem,
 | 
			
		||||
@ -25,8 +34,14 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// Make sure this is last so that all other locations are scanned first
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public int Order => 1000;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public string Name => "Internal Images";
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public bool Supports(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            if (item is Photo)
 | 
			
		||||
@ -52,9 +67,8 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        // Make sure this is last so that all other locations are scanned first
 | 
			
		||||
        public int Order => 1000;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            var path = item.GetInternalMetadataPath();
 | 
			
		||||
@ -66,7 +80,7 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                return new LocalImageProvider(_fileSystem).GetImages(item, path, false, directoryService);
 | 
			
		||||
                return new LocalImageProvider(_fileSystem).GetImages(item, path, directoryService);
 | 
			
		||||
            }
 | 
			
		||||
            catch (IOException ex)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
@ -13,19 +13,71 @@ using MediaBrowser.Model.IO;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Local image provider.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class LocalImageProvider : ILocalImageProvider, IHasOrder
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly string[] _commonImageFileNames =
 | 
			
		||||
        {
 | 
			
		||||
            "poster",
 | 
			
		||||
            "folder",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] _musicImageFileNames =
 | 
			
		||||
        {
 | 
			
		||||
            "folder",
 | 
			
		||||
            "poster",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] _personImageFileNames =
 | 
			
		||||
        {
 | 
			
		||||
            "folder",
 | 
			
		||||
            "poster"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] _seriesImageFileNames =
 | 
			
		||||
        {
 | 
			
		||||
            "poster",
 | 
			
		||||
            "folder",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default",
 | 
			
		||||
            "show"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] _videoImageFileNames =
 | 
			
		||||
        {
 | 
			
		||||
            "poster",
 | 
			
		||||
            "folder",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default",
 | 
			
		||||
            "movie"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private readonly IFileSystem _fileSystem;
 | 
			
		||||
 | 
			
		||||
        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="LocalImageProvider"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        public LocalImageProvider(IFileSystem fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
            _fileSystem = fileSystem;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public string Name => "Local Images";
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public int Order => 0;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public bool Supports(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            if (item.SupportsLocalMetadata)
 | 
			
		||||
@ -42,17 +94,12 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            if (item.LocationType == LocationType.Virtual)
 | 
			
		||||
            {
 | 
			
		||||
                var season = item as Season;
 | 
			
		||||
 | 
			
		||||
                if (season != null)
 | 
			
		||||
                {
 | 
			
		||||
                    var series = season.Series;
 | 
			
		||||
 | 
			
		||||
                var series = season?.Series;
 | 
			
		||||
                if (series != null && series.IsFileProtocol)
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@ -85,6 +132,7 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
                .OrderBy(i => Array.IndexOf(BaseItem.SupportedImageExtensions, i.Extension ?? string.Empty));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            var files = GetFiles(item, true, directoryService).ToList();
 | 
			
		||||
@ -96,12 +144,26 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            return list;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, string path, bool isPathInMediaFolder, IDirectoryService directoryService)
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get images for item.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="path">The images path.</param>
 | 
			
		||||
        /// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
 | 
			
		||||
        /// <returns>The local image info.</returns>
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, string path, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            return GetImages(item, new[] { path }, isPathInMediaFolder, directoryService);
 | 
			
		||||
            return GetImages(item, new[] { path }, directoryService);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, IEnumerable<string> paths, bool arePathsInMediaFolders, IDirectoryService directoryService)
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get images for item from multiple paths.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="paths">The image paths.</param>
 | 
			
		||||
        /// <param name="directoryService">Instance of the <see cref="IDirectoryService"/> interface.</param>
 | 
			
		||||
        /// <returns>The local image info.</returns>
 | 
			
		||||
        public List<LocalImageInfo> GetImages(BaseItem item, IEnumerable<string> paths, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            IEnumerable<FileSystemMetadata> files = paths.SelectMany(i => _fileSystem.GetFiles(i, BaseItem.SupportedImageExtensions, true, false));
 | 
			
		||||
 | 
			
		||||
@ -196,7 +258,7 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
 | 
			
		||||
            if (!isEpisode && !isSong && !isPerson)
 | 
			
		||||
            {
 | 
			
		||||
                PopulateBackdrops(item, images, files, imagePrefix, isInMixedFolder, directoryService);
 | 
			
		||||
                PopulateBackdrops(item, images, files, imagePrefix, isInMixedFolder);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (item is IHasScreenshots)
 | 
			
		||||
@ -205,46 +267,6 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] CommonImageFileNames = new[]
 | 
			
		||||
        {
 | 
			
		||||
            "poster",
 | 
			
		||||
            "folder",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] MusicImageFileNames = new[]
 | 
			
		||||
        {
 | 
			
		||||
            "folder",
 | 
			
		||||
            "poster",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] PersonImageFileNames = new[]
 | 
			
		||||
        {
 | 
			
		||||
            "folder",
 | 
			
		||||
            "poster"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] SeriesImageFileNames = new[]
 | 
			
		||||
        {
 | 
			
		||||
            "poster",
 | 
			
		||||
            "folder",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default",
 | 
			
		||||
            "show"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly string[] VideoImageFileNames = new[]
 | 
			
		||||
        {
 | 
			
		||||
            "poster",
 | 
			
		||||
            "folder",
 | 
			
		||||
            "cover",
 | 
			
		||||
            "default",
 | 
			
		||||
            "movie"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private void PopulatePrimaryImages(BaseItem item, List<LocalImageInfo> images, List<FileSystemMetadata> files, string imagePrefix, bool isInMixedFolder)
 | 
			
		||||
        {
 | 
			
		||||
            string[] imageFileNames;
 | 
			
		||||
@ -252,24 +274,24 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            if (item is MusicAlbum || item is MusicArtist || item is PhotoAlbum)
 | 
			
		||||
            {
 | 
			
		||||
                // these prefer folder
 | 
			
		||||
                imageFileNames = MusicImageFileNames;
 | 
			
		||||
                imageFileNames = _musicImageFileNames;
 | 
			
		||||
            }
 | 
			
		||||
            else if (item is Person)
 | 
			
		||||
            {
 | 
			
		||||
                // these prefer folder
 | 
			
		||||
                imageFileNames = PersonImageFileNames;
 | 
			
		||||
                imageFileNames = _personImageFileNames;
 | 
			
		||||
            }
 | 
			
		||||
            else if (item is Series)
 | 
			
		||||
            {
 | 
			
		||||
                imageFileNames = SeriesImageFileNames;
 | 
			
		||||
                imageFileNames = _seriesImageFileNames;
 | 
			
		||||
            }
 | 
			
		||||
            else if (item is Video && !(item is Episode))
 | 
			
		||||
            {
 | 
			
		||||
                imageFileNames = VideoImageFileNames;
 | 
			
		||||
                imageFileNames = _videoImageFileNames;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                imageFileNames = CommonImageFileNames;
 | 
			
		||||
                imageFileNames = _commonImageFileNames;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var fileNameWithoutExtension = item.FileNameWithoutExtension;
 | 
			
		||||
@ -301,7 +323,7 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void PopulateBackdrops(BaseItem item, List<LocalImageInfo> images, List<FileSystemMetadata> files, string imagePrefix, bool isInMixedFolder, IDirectoryService directoryService)
 | 
			
		||||
        private void PopulateBackdrops(BaseItem item, List<LocalImageInfo> images, List<FileSystemMetadata> files, string imagePrefix, bool isInMixedFolder)
 | 
			
		||||
        {
 | 
			
		||||
            if (!string.IsNullOrEmpty(item.Path))
 | 
			
		||||
            {
 | 
			
		||||
@ -328,13 +350,13 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
 | 
			
		||||
            if (extraFanartFolder != null)
 | 
			
		||||
            {
 | 
			
		||||
                PopulateBackdropsFromExtraFanart(extraFanartFolder.FullName, images, directoryService);
 | 
			
		||||
                PopulateBackdropsFromExtraFanart(extraFanartFolder.FullName, images);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", isInMixedFolder, ImageType.Backdrop);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images, IDirectoryService directoryService)
 | 
			
		||||
        private void PopulateBackdropsFromExtraFanart(string path, List<LocalImageInfo> images)
 | 
			
		||||
        {
 | 
			
		||||
            var imageFiles = _fileSystem.GetFiles(path, BaseItem.SupportedImageExtensions, false, false);
 | 
			
		||||
 | 
			
		||||
@ -395,8 +417,6 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 | 
			
		||||
 | 
			
		||||
        private void PopulateSeasonImagesFromSeriesFolder(Season season, List<LocalImageInfo> images, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            var seasonNumber = season.IndexNumber;
 | 
			
		||||
@ -410,7 +430,7 @@ namespace MediaBrowser.LocalMetadata.Images
 | 
			
		||||
            var seriesFiles = GetFiles(series, false, directoryService).ToList();
 | 
			
		||||
 | 
			
		||||
            // Try using the season name
 | 
			
		||||
            var prefix = season.Name.ToLowerInvariant().Replace(" ", string.Empty);
 | 
			
		||||
            var prefix = season.Name.Replace(" ", string.Empty, StringComparison.Ordinal).ToLowerInvariant();
 | 
			
		||||
 | 
			
		||||
            var filenamePrefixes = new List<string> { prefix };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,14 +10,28 @@
 | 
			
		||||
    <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="..\SharedVersion.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.1</TargetFramework>
 | 
			
		||||
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
 | 
			
		||||
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
 | 
			
		||||
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
 | 
			
		||||
    <Nullable>enable</Nullable>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="..\SharedVersion.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <!-- Code Analyzers-->
 | 
			
		||||
  <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
 | 
			
		||||
    <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
 | 
			
		||||
    <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
 | 
			
		||||
    <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
 | 
			
		||||
    <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
 | 
			
		||||
    <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -14,24 +14,21 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Provides a base class for parsing metadata xml
 | 
			
		||||
    /// Provides a base class for parsing metadata xml.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <typeparam name="T"></typeparam>
 | 
			
		||||
    /// <typeparam name="T">Type of item xml parser.</typeparam>
 | 
			
		||||
    public class BaseItemXmlParser<T>
 | 
			
		||||
        where T : BaseItem
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// The logger
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected ILogger<BaseItemXmlParser<T>> Logger { get; private set; }
 | 
			
		||||
        protected IProviderManager ProviderManager { get; private set; }
 | 
			
		||||
        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 | 
			
		||||
 | 
			
		||||
        private Dictionary<string, string> _validProviderIds;
 | 
			
		||||
        private Dictionary<string, string>? _validProviderIds;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="BaseItemXmlParser{T}" /> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="logger">The logger.</param>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{BaseItemXmlParser}"/> interface.</param>
 | 
			
		||||
        /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
 | 
			
		||||
        public BaseItemXmlParser(ILogger<BaseItemXmlParser<T>> logger, IProviderManager providerManager)
 | 
			
		||||
        {
 | 
			
		||||
            Logger = logger;
 | 
			
		||||
@ -39,12 +36,22 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Fetches metadata for an item from one xml file
 | 
			
		||||
        /// Gets the logger.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected ILogger<BaseItemXmlParser<T>> Logger { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the provider manager.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected IProviderManager ProviderManager { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Fetches metadata for an item from one xml file.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="metadataFile">The metadata file.</param>
 | 
			
		||||
        /// <param name="cancellationToken">The cancellation token.</param>
 | 
			
		||||
        /// <exception cref="ArgumentNullException"></exception>
 | 
			
		||||
        /// <exception cref="ArgumentNullException">Item is null.</exception>
 | 
			
		||||
        public void Fetch(MetadataResult<T> item, string metadataFile, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            if (item == null)
 | 
			
		||||
@ -57,7 +64,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                throw new ArgumentException("The metadata file was empty or null.", nameof(metadataFile));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var settings = new XmlReaderSettings()
 | 
			
		||||
            var settings = new XmlReaderSettings
 | 
			
		||||
            {
 | 
			
		||||
                ValidationType = ValidationType.None,
 | 
			
		||||
                CheckCharacters = false,
 | 
			
		||||
@ -78,10 +85,10 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Additional Mappings
 | 
			
		||||
            // Additional Mappings
 | 
			
		||||
            _validProviderIds.Add("IMDB", "Imdb");
 | 
			
		||||
 | 
			
		||||
            //Fetch(item, metadataFile, settings, Encoding.GetEncoding("ISO-8859-1"), cancellationToken);
 | 
			
		||||
            // Fetch(item, metadataFile, settings, Encoding.GetEncoding("ISO-8859-1"), cancellationToken);
 | 
			
		||||
            Fetch(item, metadataFile, settings, Encoding.UTF8, cancellationToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -97,10 +104,9 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
        {
 | 
			
		||||
            item.ResetPeople();
 | 
			
		||||
 | 
			
		||||
            using (var fileStream = File.OpenRead(metadataFile))
 | 
			
		||||
            using (var streamReader = new StreamReader(fileStream, encoding))
 | 
			
		||||
            using (var reader = XmlReader.Create(streamReader, settings))
 | 
			
		||||
            {
 | 
			
		||||
            using var fileStream = File.OpenRead(metadataFile);
 | 
			
		||||
            using var streamReader = new StreamReader(fileStream, encoding);
 | 
			
		||||
            using var reader = XmlReader.Create(streamReader, settings);
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            reader.Read();
 | 
			
		||||
 | 
			
		||||
@ -119,12 +125,9 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Fetches metadata from one Xml Element
 | 
			
		||||
        /// Fetches metadata from one Xml Element.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="reader">The reader.</param>
 | 
			
		||||
        /// <param name="itemResult">The item result.</param>
 | 
			
		||||
@ -150,6 +153,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            Logger.LogWarning("Invalid Added value found: " + val);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -161,6 +165,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        item.OriginalTitle = val;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -191,6 +196,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        item.ForcedSortName = val;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -231,10 +237,9 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(val))
 | 
			
		||||
                    {
 | 
			
		||||
                            var person = item as Person;
 | 
			
		||||
                            if (person != null)
 | 
			
		||||
                        if (item is Person person)
 | 
			
		||||
                        {
 | 
			
		||||
                                person.ProductionLocations = new string[] { val };
 | 
			
		||||
                            person.ProductionLocations = new[] { val };
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
@ -255,8 +260,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            return null;
 | 
			
		||||
 | 
			
		||||
                            }).Where(i => i.HasValue).Select(i => i.Value).ToArray();
 | 
			
		||||
                        }).Where(i => i.HasValue).Select(i => i!.Value).ToArray();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
@ -275,6 +279,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -284,13 +289,14 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                        {
 | 
			
		||||
                                FetchFromCountriesNode(subtree, item);
 | 
			
		||||
                            FetchFromCountriesNode(subtree);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -303,6 +309,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        item.OfficialRating = rating;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -314,6 +321,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        item.CustomRating = val;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -328,6 +336,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            item.RunTimeTicks = TimeSpan.FromMinutes(runtime).Ticks;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -340,6 +349,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        hasAspectRatio.AspectRatio = val;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -351,6 +361,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        item.IsLocked = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -362,8 +373,10 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                        {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        item.AddStudio(name);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -375,10 +388,13 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                        {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        itemResult.AddPerson(p);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case "Writer":
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var p in SplitNames(reader.ReadElementContentAsString()).Select(v => new PersonInfo { Name = v.Trim(), Type = PersonType.Writer }))
 | 
			
		||||
@ -387,21 +403,23 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                        {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        itemResult.AddPerson(p);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                case "Actors":
 | 
			
		||||
                {
 | 
			
		||||
 | 
			
		||||
                    var actors = reader.ReadInnerXml();
 | 
			
		||||
 | 
			
		||||
                        if (actors.Contains("<"))
 | 
			
		||||
                    if (actors.Contains("<", StringComparison.Ordinal))
 | 
			
		||||
                    {
 | 
			
		||||
                        // This is one of the mis-named "Actors" full nodes created by MB2
 | 
			
		||||
                        // Create a reader and pass it to the persons node processor
 | 
			
		||||
                            FetchDataFromPersonsNode(XmlReader.Create(new StringReader("<Persons>" + actors + "</Persons>")), itemResult);
 | 
			
		||||
                        using var xmlReader = XmlReader.Create(new StringReader($"<Persons>{actors}</Persons>"));
 | 
			
		||||
                        FetchDataFromPersonsNode(xmlReader, itemResult);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
@ -412,9 +430,11 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            itemResult.AddPerson(p);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -426,8 +446,10 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                        {
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        itemResult.AddPerson(p);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -439,6 +461,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        item.AddTrailerUrl(val);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -454,6 +477,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            hasDisplayOrder.DisplayOrder = val;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -461,15 +485,14 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                {
 | 
			
		||||
                    if (!reader.IsEmptyElement)
 | 
			
		||||
                    {
 | 
			
		||||
                            using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                            {
 | 
			
		||||
                        using var subtree = reader.ReadSubtree();
 | 
			
		||||
                        FetchDataFromTrailersNode(subtree, item);
 | 
			
		||||
                    }
 | 
			
		||||
                        }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -491,7 +514,6 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                case "Rating":
 | 
			
		||||
                case "IMDBrating":
 | 
			
		||||
                {
 | 
			
		||||
 | 
			
		||||
                    var rating = reader.ReadElementContentAsString();
 | 
			
		||||
 | 
			
		||||
                    if (!string.IsNullOrWhiteSpace(rating))
 | 
			
		||||
@ -502,6 +524,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            item.CommunityRating = val;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -545,21 +568,21 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        item.SetProviderId(MetadataProvider.TmdbCollection, tmdbCollection);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case "Genres":
 | 
			
		||||
                {
 | 
			
		||||
                    if (!reader.IsEmptyElement)
 | 
			
		||||
                    {
 | 
			
		||||
                            using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                            {
 | 
			
		||||
                        using var subtree = reader.ReadSubtree();
 | 
			
		||||
                        FetchFromGenresNode(subtree, item);
 | 
			
		||||
                    }
 | 
			
		||||
                        }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -567,15 +590,14 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                {
 | 
			
		||||
                    if (!reader.IsEmptyElement)
 | 
			
		||||
                    {
 | 
			
		||||
                            using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                            {
 | 
			
		||||
                        using var subtree = reader.ReadSubtree();
 | 
			
		||||
                        FetchFromTagsNode(subtree, item);
 | 
			
		||||
                    }
 | 
			
		||||
                        }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -583,15 +605,14 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                {
 | 
			
		||||
                    if (!reader.IsEmptyElement)
 | 
			
		||||
                    {
 | 
			
		||||
                            using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                            {
 | 
			
		||||
                        using var subtree = reader.ReadSubtree();
 | 
			
		||||
                        FetchDataFromPersonsNode(subtree, itemResult);
 | 
			
		||||
                    }
 | 
			
		||||
                        }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -599,15 +620,14 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                {
 | 
			
		||||
                    if (!reader.IsEmptyElement)
 | 
			
		||||
                    {
 | 
			
		||||
                            using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                            {
 | 
			
		||||
                        using var subtree = reader.ReadSubtree();
 | 
			
		||||
                        FetchFromStudiosNode(subtree, item);
 | 
			
		||||
                    }
 | 
			
		||||
                        }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -615,19 +635,17 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                {
 | 
			
		||||
                    if (!reader.IsEmptyElement)
 | 
			
		||||
                    {
 | 
			
		||||
                            using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                            {
 | 
			
		||||
                                var hasShares = item as IHasShares;
 | 
			
		||||
                                if (hasShares != null)
 | 
			
		||||
                        using var subtree = reader.ReadSubtree();
 | 
			
		||||
                        if (item is IHasShares hasShares)
 | 
			
		||||
                        {
 | 
			
		||||
                            FetchFromSharesNode(subtree, hasShares);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                        }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@ -635,9 +653,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                {
 | 
			
		||||
                    var val = reader.ReadElementContentAsString();
 | 
			
		||||
 | 
			
		||||
                        var video = item as Video;
 | 
			
		||||
 | 
			
		||||
                        if (video != null)
 | 
			
		||||
                    if (item is Video video)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (string.Equals("HSBS", val, StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
                        {
 | 
			
		||||
@ -660,13 +676,14 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            video.Video3DFormat = Video3DFormat.MVC;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                {
 | 
			
		||||
                    string readerName = reader.Name;
 | 
			
		||||
                        if (_validProviderIds.TryGetValue(readerName, out string providerIdValue))
 | 
			
		||||
                    if (_validProviderIds!.TryGetValue(readerName, out string providerIdValue))
 | 
			
		||||
                    {
 | 
			
		||||
                        var id = reader.ReadElementContentAsString();
 | 
			
		||||
                        if (!string.IsNullOrWhiteSpace(id))
 | 
			
		||||
@ -680,10 +697,10 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        private void FetchFromSharesNode(XmlReader reader, IHasShares item)
 | 
			
		||||
        {
 | 
			
		||||
            var list = new List<Share>();
 | 
			
		||||
@ -718,6 +735,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                        {
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
@ -756,7 +774,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
 | 
			
		||||
                        case "CanEdit":
 | 
			
		||||
                        {
 | 
			
		||||
                                share.CanEdit = string.Equals(reader.ReadElementContentAsString(), true.ToString(), StringComparison.OrdinalIgnoreCase);
 | 
			
		||||
                            share.CanEdit = string.Equals(reader.ReadElementContentAsString(), true.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase);
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -774,7 +792,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
            return share;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FetchFromCountriesNode(XmlReader reader, T item)
 | 
			
		||||
        private void FetchFromCountriesNode(XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            reader.Read();
 | 
			
		||||
@ -793,6 +811,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            if (!string.IsNullOrWhiteSpace(val))
 | 
			
		||||
                            {
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -833,8 +852,10 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                item.Tagline = val;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
                            break;
 | 
			
		||||
@ -872,6 +893,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                item.AddGenre(genre);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -909,6 +931,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                tags.Add(tag);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -951,6 +974,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                                reader.Read();
 | 
			
		||||
                                continue;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            using (var subtree = reader.ReadSubtree())
 | 
			
		||||
                            {
 | 
			
		||||
                                foreach (var person in GetPersonsFromXmlNode(subtree))
 | 
			
		||||
@ -959,9 +983,11 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                                    {
 | 
			
		||||
                                        continue;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    item.AddPerson(person);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -997,6 +1023,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                item.AddTrailerUrl(val);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -1037,6 +1064,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                item.AddStudio(studio);
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -1086,6 +1114,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                type = val;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -1097,8 +1126,10 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            {
 | 
			
		||||
                                role = val;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        case "SortOrder":
 | 
			
		||||
                        {
 | 
			
		||||
                            var val = reader.ReadElementContentAsString();
 | 
			
		||||
@ -1110,6 +1141,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                                    sortOrder = intVal;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@ -1124,23 +1156,19 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var personInfo = new PersonInfo
 | 
			
		||||
            {
 | 
			
		||||
                Name = name.Trim(),
 | 
			
		||||
                Role = role,
 | 
			
		||||
                Type = type,
 | 
			
		||||
                SortOrder = sortOrder
 | 
			
		||||
            };
 | 
			
		||||
            var personInfo = new PersonInfo { Name = name.Trim(), Role = role, Type = type, SortOrder = sortOrder };
 | 
			
		||||
 | 
			
		||||
            return new[] { personInfo };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected LinkedChild GetLinkedChild(XmlReader reader)
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get linked child.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="reader">The xml reader.</param>
 | 
			
		||||
        /// <returns>The linked child.</returns>
 | 
			
		||||
        protected LinkedChild? GetLinkedChild(XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            var linkedItem = new LinkedChild
 | 
			
		||||
            {
 | 
			
		||||
                Type = LinkedChildType.Manual
 | 
			
		||||
            };
 | 
			
		||||
            var linkedItem = new LinkedChild { Type = LinkedChildType.Manual };
 | 
			
		||||
 | 
			
		||||
            reader.MoveToContent();
 | 
			
		||||
            reader.Read();
 | 
			
		||||
@ -1157,6 +1185,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            linkedItem.Path = reader.ReadElementContentAsString();
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        case "ItemId":
 | 
			
		||||
                        {
 | 
			
		||||
                            linkedItem.LibraryItemId = reader.ReadElementContentAsString();
 | 
			
		||||
@ -1183,7 +1212,12 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected Share GetShare(XmlReader reader)
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get share.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="reader">The xml reader.</param>
 | 
			
		||||
        /// <returns>The share.</returns>
 | 
			
		||||
        protected Share? GetShare(XmlReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            var item = new Share();
 | 
			
		||||
 | 
			
		||||
@ -1208,6 +1242,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                            item.CanEdit = string.Equals(reader.ReadElementContentAsString(), "true", StringComparison.OrdinalIgnoreCase);
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                        {
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
@ -1230,19 +1265,19 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Used to split names of comma or pipe delimeted genres and people
 | 
			
		||||
        /// Used to split names of comma or pipe delimited genres and people.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="value">The value.</param>
 | 
			
		||||
        /// <returns>IEnumerable{System.String}.</returns>
 | 
			
		||||
        private IEnumerable<string> SplitNames(string value)
 | 
			
		||||
        {
 | 
			
		||||
            value = value ?? string.Empty;
 | 
			
		||||
            value ??= string.Empty;
 | 
			
		||||
 | 
			
		||||
            // Only split by comma if there is no pipe in the string
 | 
			
		||||
            // We have to be careful to not split names like Matthew, Jr.
 | 
			
		||||
            var separator = value.IndexOf('|') == -1 && value.IndexOf(';') == -1 ? new[] { ',' } : new[] { '|', ';' };
 | 
			
		||||
            var separator = value.IndexOf('|', StringComparison.Ordinal) == -1
 | 
			
		||||
                            && value.IndexOf(';', StringComparison.Ordinal) == -1 ? new[] { ',' } : new[] { '|', ';' };
 | 
			
		||||
 | 
			
		||||
            value = value.Trim().Trim(separator);
 | 
			
		||||
 | 
			
		||||
@ -1250,7 +1285,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Provides an additional overload for string.split
 | 
			
		||||
        /// Provides an additional overload for string.split.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="val">The val.</param>
 | 
			
		||||
        /// <param name="separators">The separators.</param>
 | 
			
		||||
@ -1260,6 +1295,5 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
        {
 | 
			
		||||
            return val.Split(separators, options);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,22 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// The box set xml parser.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class BoxSetXmlParser : BaseItemXmlParser<BoxSet>
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="BoxSetXmlParser"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{BoxSetXmlParset}"/> interface.</param>
 | 
			
		||||
        /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
 | 
			
		||||
        public BoxSetXmlParser(ILogger<BoxSetXmlParser> logger, IProviderManager providerManager)
 | 
			
		||||
            : base(logger, providerManager)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<BoxSet> item)
 | 
			
		||||
        {
 | 
			
		||||
            switch (reader.Name)
 | 
			
		||||
@ -26,6 +40,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
@ -69,6 +84,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                        {
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
@ -84,10 +100,5 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
 | 
			
		||||
            item.Item.LinkedChildren = list.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public BoxSetXmlParser(ILogger<BoxSetXmlParser> logger, IProviderManager providerManager)
 | 
			
		||||
            : base(logger, providerManager)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,8 +7,22 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Playlist xml parser.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PlaylistXmlParser : BaseItemXmlParser<Playlist>
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="PlaylistXmlParser"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{PlaylistXmlParser}"/> interface.</param>
 | 
			
		||||
        /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
 | 
			
		||||
        public PlaylistXmlParser(ILogger<PlaylistXmlParser> logger, IProviderManager providerManager)
 | 
			
		||||
            : base(logger, providerManager)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void FetchDataFromXmlNode(XmlReader reader, MetadataResult<Playlist> result)
 | 
			
		||||
        {
 | 
			
		||||
            var item = result.Item;
 | 
			
		||||
@ -35,6 +49,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
                    {
 | 
			
		||||
                        reader.Read();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
@ -77,6 +92,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
 | 
			
		||||
                            break;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        default:
 | 
			
		||||
                        {
 | 
			
		||||
                            reader.Skip();
 | 
			
		||||
@ -92,10 +108,5 @@ namespace MediaBrowser.LocalMetadata.Parsers
 | 
			
		||||
 | 
			
		||||
            item.LinkedChildren = list.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public PlaylistXmlParser(ILogger<PlaylistXmlParser> logger, IProviderManager providerManager)
 | 
			
		||||
            : base(logger, providerManager)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,12 @@ namespace MediaBrowser.LocalMetadata.Providers
 | 
			
		||||
        private readonly ILogger<BoxSetXmlParser> _logger;
 | 
			
		||||
        private readonly IProviderManager _providerManager;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="BoxSetXmlProvider"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{BoxSetXmlParser}"/> interface.</param>
 | 
			
		||||
        /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
 | 
			
		||||
        public BoxSetXmlProvider(IFileSystem fileSystem, ILogger<BoxSetXmlParser> logger, IProviderManager providerManager)
 | 
			
		||||
            : base(fileSystem)
 | 
			
		||||
        {
 | 
			
		||||
@ -23,11 +29,13 @@ namespace MediaBrowser.LocalMetadata.Providers
 | 
			
		||||
            _providerManager = providerManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void Fetch(MetadataResult<BoxSet> result, string path, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            new BoxSetXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            return directoryService.GetFile(Path.Combine(info.Path, "collection.xml"));
 | 
			
		||||
 | 
			
		||||
@ -8,11 +8,20 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Providers
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Playlist xml provider.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PlaylistXmlProvider : BaseXmlProvider<Playlist>
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ILogger<PlaylistXmlParser> _logger;
 | 
			
		||||
        private readonly IProviderManager _providerManager;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="PlaylistXmlProvider"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{PlaylistXmlParser}"/> interface.</param>
 | 
			
		||||
        /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
 | 
			
		||||
        public PlaylistXmlProvider(
 | 
			
		||||
            IFileSystem fileSystem,
 | 
			
		||||
            ILogger<PlaylistXmlParser> logger,
 | 
			
		||||
@ -23,14 +32,16 @@ namespace MediaBrowser.LocalMetadata.Providers
 | 
			
		||||
            _providerManager = providerManager;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void Fetch(MetadataResult<Playlist> result, string path, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            new PlaylistXmlParser(_logger, _providerManager).Fetch(result, path, cancellationToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override FileSystemMetadata GetXmlFile(ItemInfo info, IDirectoryService directoryService)
 | 
			
		||||
        {
 | 
			
		||||
            return directoryService.GetFile(PlaylistXmlSaver.GetSavePath(info.Path, FileSystem));
 | 
			
		||||
            return directoryService.GetFile(PlaylistXmlSaver.GetSavePath(info.Path));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -17,10 +17,25 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
{
 | 
			
		||||
    /// <inheritdoc />
 | 
			
		||||
    public abstract class BaseXmlSaver : IMetadataFileSaver
 | 
			
		||||
    {
 | 
			
		||||
        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the date added format.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
 | 
			
		||||
 | 
			
		||||
        private static readonly CultureInfo _usCulture = new CultureInfo("en-US");
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="BaseXmlSaver"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        /// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
 | 
			
		||||
        /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
 | 
			
		||||
        /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
 | 
			
		||||
        /// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{BaseXmlSaver}"/> interface.</param>
 | 
			
		||||
        public BaseXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<BaseXmlSaver> logger)
 | 
			
		||||
        {
 | 
			
		||||
            FileSystem = fileSystem;
 | 
			
		||||
@ -31,15 +46,40 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            Logger = logger;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the file system.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected IFileSystem FileSystem { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the configuration manager.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected IServerConfigurationManager ConfigurationManager { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the library manager.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected ILibraryManager LibraryManager { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the user manager.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected IUserManager UserManager { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the user data manager.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected IUserDataManager UserDataManager { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the logger.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        protected ILogger<BaseXmlSaver> Logger { get; private set; }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public string Name => XmlProviderUtils.Name;
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public string GetSavePath(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            return GetLocalSavePath(item);
 | 
			
		||||
@ -70,13 +110,13 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
        /// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
 | 
			
		||||
        public abstract bool IsEnabledFor(BaseItem item, ItemUpdateType updateType);
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public void Save(BaseItem item, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            var path = GetSavePath(item);
 | 
			
		||||
 | 
			
		||||
            using (var memoryStream = new MemoryStream())
 | 
			
		||||
            {
 | 
			
		||||
                Save(item, memoryStream, path);
 | 
			
		||||
            using var memoryStream = new MemoryStream();
 | 
			
		||||
            Save(item, memoryStream);
 | 
			
		||||
 | 
			
		||||
            memoryStream.Position = 0;
 | 
			
		||||
 | 
			
		||||
@ -84,7 +124,6 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
 | 
			
		||||
            SaveToFile(memoryStream, path);
 | 
			
		||||
        }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SaveToFile(Stream stream, string path)
 | 
			
		||||
        {
 | 
			
		||||
@ -115,7 +154,7 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Save(BaseItem item, Stream stream, string xmlPath)
 | 
			
		||||
        private void Save(BaseItem item, Stream stream)
 | 
			
		||||
        {
 | 
			
		||||
            var settings = new XmlWriterSettings
 | 
			
		||||
            {
 | 
			
		||||
@ -136,7 +175,7 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
 | 
			
		||||
                if (baseItem != null)
 | 
			
		||||
                {
 | 
			
		||||
                    AddCommonNodes(baseItem, writer, LibraryManager, UserManager, UserDataManager, FileSystem, ConfigurationManager);
 | 
			
		||||
                    AddCommonNodes(baseItem, writer, LibraryManager);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                WriteCustomElements(item, writer);
 | 
			
		||||
@ -147,22 +186,27 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Write custom elements.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="writer">The xml writer.</param>
 | 
			
		||||
        protected abstract void WriteCustomElements(BaseItem item, XmlWriter writer);
 | 
			
		||||
 | 
			
		||||
        public const string DateAddedFormat = "yyyy-MM-dd HH:mm:ss";
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds the common nodes.
 | 
			
		||||
        /// Adds common notes.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>Task.</returns>
 | 
			
		||||
        public static void AddCommonNodes(BaseItem item, XmlWriter writer, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataRepo, IFileSystem fileSystem, IServerConfigurationManager config)
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="writer">The xml writer.</param>
 | 
			
		||||
        /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
 | 
			
		||||
        public static void AddCommonNodes(BaseItem item, XmlWriter writer, ILibraryManager libraryManager)
 | 
			
		||||
        {
 | 
			
		||||
            if (!string.IsNullOrEmpty(item.OfficialRating))
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("ContentRating", item.OfficialRating);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            writer.WriteElementString("Added", item.DateCreated.ToLocalTime().ToString("G"));
 | 
			
		||||
            writer.WriteElementString("Added", item.DateCreated.ToLocalTime().ToString("G", CultureInfo.InvariantCulture));
 | 
			
		||||
 | 
			
		||||
            writer.WriteElementString("LockData", item.IsLocked.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 | 
			
		||||
 | 
			
		||||
@ -173,7 +217,7 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
 | 
			
		||||
            if (item.CriticRating.HasValue)
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("CriticRating", item.CriticRating.Value.ToString(UsCulture));
 | 
			
		||||
                writer.WriteElementString("CriticRating", item.CriticRating.Value.ToString(_usCulture));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!string.IsNullOrEmpty(item.Overview))
 | 
			
		||||
@ -185,6 +229,7 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("OriginalTitle", item.OriginalTitle);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!string.IsNullOrEmpty(item.CustomRating))
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("CustomRating", item.CustomRating);
 | 
			
		||||
@ -205,11 +250,11 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            {
 | 
			
		||||
                if (item is Person)
 | 
			
		||||
                {
 | 
			
		||||
                    writer.WriteElementString("BirthDate", item.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd"));
 | 
			
		||||
                    writer.WriteElementString("BirthDate", item.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
 | 
			
		||||
                }
 | 
			
		||||
                else if (!(item is Episode))
 | 
			
		||||
                {
 | 
			
		||||
                    writer.WriteElementString("PremiereDate", item.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd"));
 | 
			
		||||
                    writer.WriteElementString("PremiereDate", item.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -217,11 +262,11 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            {
 | 
			
		||||
                if (item is Person)
 | 
			
		||||
                {
 | 
			
		||||
                    writer.WriteElementString("DeathDate", item.EndDate.Value.ToLocalTime().ToString("yyyy-MM-dd"));
 | 
			
		||||
                    writer.WriteElementString("DeathDate", item.EndDate.Value.ToLocalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
 | 
			
		||||
                }
 | 
			
		||||
                else if (!(item is Episode))
 | 
			
		||||
                {
 | 
			
		||||
                    writer.WriteElementString("EndDate", item.EndDate.Value.ToLocalTime().ToString("yyyy-MM-dd"));
 | 
			
		||||
                    writer.WriteElementString("EndDate", item.EndDate.Value.ToLocalTime().ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -257,12 +302,12 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
 | 
			
		||||
            if (item.CommunityRating.HasValue)
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("Rating", item.CommunityRating.Value.ToString(UsCulture));
 | 
			
		||||
                writer.WriteElementString("Rating", item.CommunityRating.Value.ToString(_usCulture));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (item.ProductionYear.HasValue && !(item is Person))
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("ProductionYear", item.ProductionYear.Value.ToString(UsCulture));
 | 
			
		||||
                writer.WriteElementString("ProductionYear", item.ProductionYear.Value.ToString(_usCulture));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var hasAspectRatio = item as IHasAspectRatio;
 | 
			
		||||
@ -278,6 +323,7 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("Language", item.PreferredMetadataLanguage);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!string.IsNullOrEmpty(item.PreferredMetadataCountryCode))
 | 
			
		||||
            {
 | 
			
		||||
                writer.WriteElementString("CountryCode", item.PreferredMetadataCountryCode);
 | 
			
		||||
@ -288,9 +334,9 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
 | 
			
		||||
            if (runTimeTicks.HasValue)
 | 
			
		||||
            {
 | 
			
		||||
                var timespan = TimeSpan.FromTicks(runTimeTicks.Value);
 | 
			
		||||
                var timespan = TimeSpan.FromTicks(runTimeTicks!.Value);
 | 
			
		||||
 | 
			
		||||
                writer.WriteElementString("RunningTime", Math.Floor(timespan.TotalMinutes).ToString(UsCulture));
 | 
			
		||||
                writer.WriteElementString("RunningTime", Math.Floor(timespan.TotalMinutes).ToString(_usCulture));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (item.ProviderIds != null)
 | 
			
		||||
@ -363,7 +409,7 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
 | 
			
		||||
                    if (person.SortOrder.HasValue)
 | 
			
		||||
                    {
 | 
			
		||||
                        writer.WriteElementString("SortOrder", person.SortOrder.Value.ToString(UsCulture));
 | 
			
		||||
                        writer.WriteElementString("SortOrder", person.SortOrder.Value.ToString(_usCulture));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    writer.WriteEndElement();
 | 
			
		||||
@ -393,6 +439,11 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            AddMediaInfo(item, writer);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Add shares.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="writer">The xml writer.</param>
 | 
			
		||||
        public static void AddShares(IHasShares item, XmlWriter writer)
 | 
			
		||||
        {
 | 
			
		||||
            writer.WriteStartElement("Shares");
 | 
			
		||||
@ -415,13 +466,13 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Appends the media info.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <typeparam name="T"></typeparam>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="writer">The xml writer.</param>
 | 
			
		||||
        /// <typeparam name="T">Type of item.</typeparam>
 | 
			
		||||
        public static void AddMediaInfo<T>(T item, XmlWriter writer)
 | 
			
		||||
            where T : BaseItem
 | 
			
		||||
        {
 | 
			
		||||
            var video = item as Video;
 | 
			
		||||
 | 
			
		||||
            if (video != null)
 | 
			
		||||
            if (item is Video video)
 | 
			
		||||
            {
 | 
			
		||||
                if (video.Video3DFormat.HasValue)
 | 
			
		||||
                {
 | 
			
		||||
@ -447,6 +498,13 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// ADd linked children.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="item">The item.</param>
 | 
			
		||||
        /// <param name="writer">The xml writer.</param>
 | 
			
		||||
        /// <param name="pluralNodeName">The plural node name.</param>
 | 
			
		||||
        /// <param name="singularNodeName">The singular node name.</param>
 | 
			
		||||
        public static void AddLinkedChildren(Folder item, XmlWriter writer, string pluralNodeName, string singularNodeName)
 | 
			
		||||
        {
 | 
			
		||||
            var items = item.LinkedChildren
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,26 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Box set xml saver.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class BoxSetXmlSaver : BaseXmlSaver
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="BoxSetXmlSaver"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        /// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
 | 
			
		||||
        /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
 | 
			
		||||
        /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
 | 
			
		||||
        /// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{BoxSetXmlSaver}"/> interface.</param>
 | 
			
		||||
        public BoxSetXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<BoxSetXmlSaver> logger)
 | 
			
		||||
            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
 | 
			
		||||
        {
 | 
			
		||||
            if (!item.SupportsLocalMetadata)
 | 
			
		||||
@ -21,18 +39,15 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            return item is BoxSet && updateType >= ItemUpdateType.MetadataDownload;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override string GetLocalSavePath(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            return Path.Combine(item.Path, "collection.xml");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public BoxSetXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<BoxSetXmlSaver> logger)
 | 
			
		||||
            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,9 @@ using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Playlist xml saver.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class PlaylistXmlSaver : BaseXmlSaver
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
@ -16,6 +19,21 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public const string DefaultPlaylistFilename = "playlist.xml";
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Initializes a new instance of the <see cref="PlaylistXmlSaver"/> class.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
 | 
			
		||||
        /// <param name="configurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
 | 
			
		||||
        /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
 | 
			
		||||
        /// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
 | 
			
		||||
        /// <param name="userDataManager">Instance of the <see cref="IUserDataManager"/> interface.</param>
 | 
			
		||||
        /// <param name="logger">Instance of the <see cref="ILogger{PlaylistXmlSaver}"/> interface.</param>
 | 
			
		||||
        public PlaylistXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<PlaylistXmlSaver> logger)
 | 
			
		||||
            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        public override bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
 | 
			
		||||
        {
 | 
			
		||||
            if (!item.SupportsLocalMetadata)
 | 
			
		||||
@ -26,6 +44,7 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            return item is Playlist && updateType >= ItemUpdateType.MetadataImport;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
 | 
			
		||||
        {
 | 
			
		||||
            var game = (Playlist)item;
 | 
			
		||||
@ -36,12 +55,18 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc />
 | 
			
		||||
        protected override string GetLocalSavePath(BaseItem item)
 | 
			
		||||
        {
 | 
			
		||||
            return GetSavePath(item.Path, FileSystem);
 | 
			
		||||
            return GetSavePath(item.Path);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static string GetSavePath(string itemPath, IFileSystem fileSystem)
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get the save path.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="itemPath">The item path.</param>
 | 
			
		||||
        /// <returns>The save path.</returns>
 | 
			
		||||
        public static string GetSavePath(string itemPath)
 | 
			
		||||
        {
 | 
			
		||||
            var path = itemPath;
 | 
			
		||||
 | 
			
		||||
@ -52,10 +77,5 @@ namespace MediaBrowser.LocalMetadata.Savers
 | 
			
		||||
 | 
			
		||||
            return Path.Combine(path, DefaultPlaylistFilename);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public PlaylistXmlSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger<PlaylistXmlSaver> logger)
 | 
			
		||||
            : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								MediaBrowser.LocalMetadata/XmlProviderUtils.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								MediaBrowser.LocalMetadata/XmlProviderUtils.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
namespace MediaBrowser.LocalMetadata
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// The xml provider utils.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class XmlProviderUtils
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string Name => "Emby Xml";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user