Browse Source

Rewrite PlaylistItemsProvider as ILocalMetadataProvider

Shadowghost 1 năm trước cách đây
mục cha
commit
8882bb495c
1 tập tin đã thay đổi với 164 bổ sung136 xóa
  1. 164 136
      MediaBrowser.Providers/Playlists/PlaylistItemsProvider.cs

+ 164 - 136
MediaBrowser.Providers/Playlists/PlaylistItemsProvider.cs

@@ -1,7 +1,5 @@
 #nullable disable
 
-#pragma warning disable CS1591
-
 using System;
 using System.Collections.Generic;
 using System.IO;
@@ -18,182 +16,212 @@ using MediaBrowser.Model.IO;
 using Microsoft.Extensions.Logging;
 using PlaylistsNET.Content;
 
-namespace MediaBrowser.Providers.Playlists
+namespace MediaBrowser.Providers.Playlists;
+
+/// <summary>
+/// Local playlist provider.
+/// </summary>
+public class PlaylistItemsProvider : ILocalMetadataProvider<Playlist>,
+    IHasOrder,
+    IForcedProvider,
+    IHasItemChangeMonitor
 {
-    public class PlaylistItemsProvider : ICustomMetadataProvider<Playlist>,
-        IHasOrder,
-        IForcedProvider,
-        IPreRefreshProvider,
-        IHasItemChangeMonitor
+    private readonly IFileSystem _fileSystem;
+    private readonly ILibraryManager _libraryManager;
+    private readonly ILogger<PlaylistItemsProvider> _logger;
+    private readonly CollectionType[] _ignoredCollections = [CollectionType.livetv, CollectionType.boxsets, CollectionType.playlists];
+
+    /// <summary>
+    /// Initializes a new instance of the <see cref="PlaylistItemsProvider"/> class.
+    /// </summary>
+    /// <param name="logger">Instance of the <see cref="ILogger{PlaylistItemsProvider}"/> interface.</param>
+    /// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
+    /// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
+    public PlaylistItemsProvider(ILogger<PlaylistItemsProvider> logger, ILibraryManager libraryManager, IFileSystem fileSystem)
     {
-        private readonly IFileSystem _fileSystem;
-        private readonly ILibraryManager _libraryManager;
-        private readonly ILogger<PlaylistItemsProvider> _logger;
-        private readonly CollectionType[] _ignoredCollections = [CollectionType.livetv, CollectionType.boxsets, CollectionType.playlists];
+        _logger = logger;
+        _libraryManager = libraryManager;
+        _fileSystem = fileSystem;
+    }
+
+    /// <inheritdoc />
+    public string Name => "Playlist Item Provider";
+
+    /// <inheritdoc />
+    public int Order => 100;
 
-        public PlaylistItemsProvider(ILogger<PlaylistItemsProvider> logger, ILibraryManager libraryManager, IFileSystem fileSystem)
+    /// <inheritdoc />
+    public Task<MetadataResult<Playlist>> GetMetadata(
+        ItemInfo info,
+        IDirectoryService directoryService,
+        CancellationToken cancellationToken)
+    {
+        var result = new MetadataResult<Playlist>()
         {
-            _logger = logger;
-            _libraryManager = libraryManager;
-            _fileSystem = fileSystem;
+            Item = new Playlist
+            {
+                Path = info.Path
+            }
+        };
+        Fetch(result);
+
+        return Task.FromResult(result);
+    }
+
+    private void Fetch(MetadataResult<Playlist> result)
+    {
+        var item = result.Item;
+        var path = item.Path;
+        if (!Playlist.IsPlaylistFile(path))
+        {
+            return;
         }
 
-        public string Name => "Playlist Reader";
+        var extension = Path.GetExtension(path);
+        if (!Playlist.SupportedExtensions.Contains(extension ?? string.Empty, StringComparison.OrdinalIgnoreCase))
+        {
+            return;
+        }
+
+        var items = GetItems(path, extension).ToArray();
+        if (items.Length > 0)
+        {
+            result.HasMetadata = true;
+            item.LinkedChildren = items;
+        }
 
-        // Run last
-        public int Order => 100;
+        return;
+    }
 
-        public Task<ItemUpdateType> FetchAsync(Playlist item, MetadataRefreshOptions options, CancellationToken cancellationToken)
+    private IEnumerable<LinkedChild> GetItems(string path, string extension)
+    {
+        var libraryRoots = _libraryManager.GetUserRootFolder().Children
+                            .OfType<CollectionFolder>()
+                            .Where(f => f.CollectionType.HasValue && !_ignoredCollections.Contains(f.CollectionType.Value))
+                            .SelectMany(f => f.PhysicalLocations)
+                            .Distinct(StringComparer.OrdinalIgnoreCase)
+                            .ToList();
+
+        using (var stream = File.OpenRead(path))
         {
-            var path = item.Path;
-            if (!Playlist.IsPlaylistFile(path))
+            if (string.Equals(".wpl", extension, StringComparison.OrdinalIgnoreCase))
             {
-                return Task.FromResult(ItemUpdateType.None);
+                return GetWplItems(stream, path, libraryRoots);
             }
 
-            var extension = Path.GetExtension(path);
-            if (!Playlist.SupportedExtensions.Contains(extension ?? string.Empty, StringComparison.OrdinalIgnoreCase))
+            if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase))
             {
-                return Task.FromResult(ItemUpdateType.None);
+                return GetZplItems(stream, path, libraryRoots);
             }
 
-            var items = GetItems(path, extension).ToArray();
-
-            item.LinkedChildren = items;
-
-            return Task.FromResult(ItemUpdateType.MetadataImport);
-        }
+            if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase))
+            {
+                return GetM3uItems(stream, path, libraryRoots);
+            }
 
-        private IEnumerable<LinkedChild> GetItems(string path, string extension)
-        {
-            var libraryRoots = _libraryManager.GetUserRootFolder().Children
-                                .OfType<CollectionFolder>()
-                                .Where(f => f.CollectionType.HasValue && !_ignoredCollections.Contains(f.CollectionType.Value))
-                                .SelectMany(f => f.PhysicalLocations)
-                                .Distinct(StringComparer.OrdinalIgnoreCase)
-                                .ToList();
-
-            using (var stream = File.OpenRead(path))
+            if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase))
             {
-                if (string.Equals(".wpl", extension, StringComparison.OrdinalIgnoreCase))
-                {
-                    return GetWplItems(stream, path, libraryRoots);
-                }
-
-                if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase))
-                {
-                    return GetZplItems(stream, path, libraryRoots);
-                }
-
-                if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase))
-                {
-                    return GetM3uItems(stream, path, libraryRoots);
-                }
-
-                if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase))
-                {
-                    return GetM3uItems(stream, path, libraryRoots);
-                }
-
-                if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase))
-                {
-                    return GetPlsItems(stream, path, libraryRoots);
-                }
+                return GetM3uItems(stream, path, libraryRoots);
             }
 
-            return Enumerable.Empty<LinkedChild>();
+            if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase))
+            {
+                return GetPlsItems(stream, path, libraryRoots);
+            }
         }
 
-        private IEnumerable<LinkedChild> GetPlsItems(Stream stream, string playlistPath, List<string> libraryRoots)
-        {
-            var content = new PlsContent();
-            var playlist = content.GetFromStream(stream);
+        return Enumerable.Empty<LinkedChild>();
+    }
 
-            return playlist.PlaylistEntries
-                    .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
-                    .Where(i => i is not null);
-        }
+    private IEnumerable<LinkedChild> GetPlsItems(Stream stream, string playlistPath, List<string> libraryRoots)
+    {
+        var content = new PlsContent();
+        var playlist = content.GetFromStream(stream);
 
-        private IEnumerable<LinkedChild> GetM3uItems(Stream stream, string playlistPath, List<string> libraryRoots)
-        {
-            var content = new M3uContent();
-            var playlist = content.GetFromStream(stream);
+        return playlist.PlaylistEntries
+                .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
+                .Where(i => i is not null);
+    }
 
-            return playlist.PlaylistEntries
-                    .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
-                    .Where(i => i is not null);
-        }
+    private IEnumerable<LinkedChild> GetM3uItems(Stream stream, string playlistPath, List<string> libraryRoots)
+    {
+        var content = new M3uContent();
+        var playlist = content.GetFromStream(stream);
 
-        private IEnumerable<LinkedChild> GetZplItems(Stream stream, string playlistPath, List<string> libraryRoots)
-        {
-            var content = new ZplContent();
-            var playlist = content.GetFromStream(stream);
+        return playlist.PlaylistEntries
+                .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
+                .Where(i => i is not null);
+    }
 
-            return playlist.PlaylistEntries
-                    .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
-                    .Where(i => i is not null);
-        }
+    private IEnumerable<LinkedChild> GetZplItems(Stream stream, string playlistPath, List<string> libraryRoots)
+    {
+        var content = new ZplContent();
+        var playlist = content.GetFromStream(stream);
 
-        private IEnumerable<LinkedChild> GetWplItems(Stream stream, string playlistPath, List<string> libraryRoots)
-        {
-            var content = new WplContent();
-            var playlist = content.GetFromStream(stream);
+        return playlist.PlaylistEntries
+                .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
+                .Where(i => i is not null);
+    }
 
-            return playlist.PlaylistEntries
-                    .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
-                    .Where(i => i is not null);
-        }
+    private IEnumerable<LinkedChild> GetWplItems(Stream stream, string playlistPath, List<string> libraryRoots)
+    {
+        var content = new WplContent();
+        var playlist = content.GetFromStream(stream);
+
+        return playlist.PlaylistEntries
+                .Select(i => GetLinkedChild(i.Path, playlistPath, libraryRoots))
+                .Where(i => i is not null);
+    }
 
-        private LinkedChild GetLinkedChild(string itemPath, string playlistPath, List<string> libraryRoots)
+    private LinkedChild GetLinkedChild(string itemPath, string playlistPath, List<string> libraryRoots)
+    {
+        if (TryGetPlaylistItemPath(itemPath, playlistPath, libraryRoots, out var parsedPath))
         {
-            if (TryGetPlaylistItemPath(itemPath, playlistPath, libraryRoots, out var parsedPath))
+            return new LinkedChild
             {
-                return new LinkedChild
-                {
-                    Path = parsedPath,
-                    Type = LinkedChildType.Manual
-                };
-            }
-
-            return null;
+                Path = parsedPath,
+                Type = LinkedChildType.Manual
+            };
         }
 
-        private bool TryGetPlaylistItemPath(string itemPath, string playlistPath, List<string> libraryPaths, out string path)
+        return null;
+    }
+
+    private bool TryGetPlaylistItemPath(string itemPath, string playlistPath, List<string> libraryPaths, out string path)
+    {
+        path = null;
+        string pathToCheck = _fileSystem.MakeAbsolutePath(Path.GetDirectoryName(playlistPath), itemPath);
+        if (!File.Exists(pathToCheck))
         {
-            path = null;
-            string pathToCheck = _fileSystem.MakeAbsolutePath(Path.GetDirectoryName(playlistPath), itemPath);
-            if (!File.Exists(pathToCheck))
-            {
-                return false;
-            }
+            return false;
+        }
 
-            foreach (var libraryPath in libraryPaths)
+        foreach (var libraryPath in libraryPaths)
+        {
+            if (pathToCheck.StartsWith(libraryPath, StringComparison.OrdinalIgnoreCase))
             {
-                if (pathToCheck.StartsWith(libraryPath, StringComparison.OrdinalIgnoreCase))
-                {
-                    path = pathToCheck;
-                    return true;
-                }
+                path = pathToCheck;
+                return true;
             }
-
-            return false;
         }
 
-        public bool HasChanged(BaseItem item, IDirectoryService directoryService)
-        {
-            var path = item.Path;
+        return false;
+    }
 
-            if (!string.IsNullOrWhiteSpace(path) && item.IsFileProtocol)
+    /// <inheritdoc />
+    public bool HasChanged(BaseItem item, IDirectoryService directoryService)
+    {
+        var path = item.Path;
+        if (!string.IsNullOrWhiteSpace(path) && item.IsFileProtocol)
+        {
+            var file = directoryService.GetFile(path);
+            if (file is not null && file.LastWriteTimeUtc != item.DateModified)
             {
-                var file = directoryService.GetFile(path);
-                if (file is not null && file.LastWriteTimeUtc != item.DateModified)
-                {
-                    _logger.LogDebug("Refreshing {Path} due to date modified timestamp change.", path);
-                    return true;
-                }
+                _logger.LogDebug("Refreshing {Path} due to date modified timestamp change.", path);
+                return true;
             }
-
-            return false;
         }
+
+        return false;
     }
 }