Tim Eisele 1 год назад
Родитель
Сommit
c9cd17220a

+ 22 - 8
Emby.Server.Implementations/Playlists/PlaylistManager.cs

@@ -22,7 +22,6 @@ using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Playlists;
 using MediaBrowser.Model.Playlists;
-using Microsoft.EntityFrameworkCore.Diagnostics;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
 using PlaylistsNET.Content;
 using PlaylistsNET.Content;
@@ -68,8 +67,14 @@ namespace Emby.Server.Implementations.Playlists
         public IEnumerable<Playlist> GetPlaylists(Guid userId)
         public IEnumerable<Playlist> GetPlaylists(Guid userId)
         {
         {
             var user = _userManager.GetUserById(userId);
             var user = _userManager.GetUserById(userId);
-
-            return GetPlaylistsFolder(userId).GetChildren(user, true).OfType<Playlist>();
+            return _libraryManager.GetItemList(new InternalItemsQuery
+            {
+                IncludeItemTypes = [BaseItemKind.Playlist],
+                Recursive = true,
+                DtoOptions = new DtoOptions(false)
+            })
+            .Cast<Playlist>()
+            .Where(p => p.IsVisible(user));
         }
         }
 
 
         public async Task<PlaylistCreationResult> CreatePlaylist(PlaylistCreationRequest request)
         public async Task<PlaylistCreationResult> CreatePlaylist(PlaylistCreationRequest request)
@@ -162,6 +167,13 @@ namespace Emby.Server.Implementations.Playlists
             }
             }
         }
         }
 
 
+        private List<Playlist> GetUserPlaylists(Guid userId)
+        {
+            var user = _userManager.GetUserById(userId);
+
+            return GetPlaylistsFolder(userId).GetChildren(user, true).OfType<Playlist>().ToList();
+        }
+
         private static string GetTargetPath(string path)
         private static string GetTargetPath(string path)
         {
         {
             while (Directory.Exists(path))
             while (Directory.Exists(path))
@@ -227,7 +239,7 @@ namespace Emby.Server.Implementations.Playlists
             }
             }
 
 
             // Update the playlist in the repository
             // Update the playlist in the repository
-            playlist.LinkedChildren = [..playlist.LinkedChildren, ..childrenToAdd];
+            playlist.LinkedChildren = [.. playlist.LinkedChildren, .. childrenToAdd];
 
 
             await UpdatePlaylistInternal(playlist).ConfigureAwait(false);
             await UpdatePlaylistInternal(playlist).ConfigureAwait(false);
 
 
@@ -501,11 +513,13 @@ namespace Emby.Server.Implementations.Playlists
             return relativePath;
             return relativePath;
         }
         }
 
 
+        /// <inheritdoc />
         public Folder GetPlaylistsFolder()
         public Folder GetPlaylistsFolder()
         {
         {
             return GetPlaylistsFolder(Guid.Empty);
             return GetPlaylistsFolder(Guid.Empty);
         }
         }
 
 
+        /// <inheritdoc />
         public Folder GetPlaylistsFolder(Guid userId)
         public Folder GetPlaylistsFolder(Guid userId)
         {
         {
             const string TypeName = "PlaylistsFolder";
             const string TypeName = "PlaylistsFolder";
@@ -517,7 +531,7 @@ namespace Emby.Server.Implementations.Playlists
         /// <inheritdoc />
         /// <inheritdoc />
         public async Task RemovePlaylistsAsync(Guid userId)
         public async Task RemovePlaylistsAsync(Guid userId)
         {
         {
-            var playlists = GetPlaylists(userId);
+            var playlists = GetUserPlaylists(userId);
             foreach (var playlist in playlists)
             foreach (var playlist in playlists)
             {
             {
                 // Update owner if shared
                 // Update owner if shared
@@ -555,9 +569,9 @@ namespace Emby.Server.Implementations.Playlists
 
 
                 var user = _userManager.GetUserById(request.UserId);
                 var user = _userManager.GetUserById(request.UserId);
                 await AddToPlaylistInternal(request.Id, request.Ids, user, new DtoOptions(false)
                 await AddToPlaylistInternal(request.Id, request.Ids, user, new DtoOptions(false)
-                    {
-                        EnableImages = true
-                    }).ConfigureAwait(false);
+                {
+                    EnableImages = true
+                }).ConfigureAwait(false);
 
 
                 playlist = GetPlaylistForUser(request.Id, request.UserId);
                 playlist = GetPlaylistForUser(request.Id, request.UserId);
             }
             }

+ 6 - 2
Jellyfin.Api/Controllers/PlaylistsController.cs

@@ -206,9 +206,13 @@ public class PlaylistsController : BaseJellyfinApiController
             return NotFound("Playlist not found");
             return NotFound("Playlist not found");
         }
         }
 
 
+        if (playlist.OwnerUserId.Equals(callingUserId))
+        {
+            return new PlaylistUserPermissions(callingUserId, true);
+        }
+
         var userPermission = playlist.Shares.FirstOrDefault(s => s.UserId.Equals(userId));
         var userPermission = playlist.Shares.FirstOrDefault(s => s.UserId.Equals(userId));
-        var isPermitted = playlist.OwnerUserId.Equals(callingUserId)
-            || playlist.Shares.Any(s => s.CanEdit && s.UserId.Equals(callingUserId))
+        var isPermitted = playlist.Shares.Any(s => s.CanEdit && s.UserId.Equals(callingUserId))
             || userId.Equals(callingUserId);
             || userId.Equals(callingUserId);
 
 
         if (!isPermitted)
         if (!isPermitted)

+ 1 - 1
MediaBrowser.Controller/Playlists/IPlaylistManager.cs

@@ -34,7 +34,7 @@ namespace MediaBrowser.Controller.Playlists
         Task UpdatePlaylist(PlaylistUpdateRequest request);
         Task UpdatePlaylist(PlaylistUpdateRequest request);
 
 
         /// <summary>
         /// <summary>
-        /// Gets the playlists.
+        /// Gets all playlists a user has access to.
         /// </summary>
         /// </summary>
         /// <param name="userId">The user identifier.</param>
         /// <param name="userId">The user identifier.</param>
         /// <returns>IEnumerable&lt;Playlist&gt;.</returns>
         /// <returns>IEnumerable&lt;Playlist&gt;.</returns>

+ 49 - 35
MediaBrowser.Providers/Playlists/PlaylistItemsProvider.cs

@@ -50,106 +50,120 @@ namespace MediaBrowser.Providers.Playlists
                 return Task.FromResult(ItemUpdateType.None);
                 return Task.FromResult(ItemUpdateType.None);
             }
             }
 
 
-            using (var stream = File.OpenRead(path))
-            {
-                var items = GetItems(stream, extension).ToArray();
+            var items = GetItems(path, extension).ToArray();
 
 
-                item.LinkedChildren = items;
-            }
+            item.LinkedChildren = items;
 
 
             return Task.FromResult(ItemUpdateType.None);
             return Task.FromResult(ItemUpdateType.None);
         }
         }
 
 
-        private IEnumerable<LinkedChild> GetItems(Stream stream, string extension)
+        private IEnumerable<LinkedChild> GetItems(string path, string extension)
         {
         {
-            if (string.Equals(".wpl", extension, StringComparison.OrdinalIgnoreCase))
+            using (var stream = File.OpenRead(path))
             {
             {
-                return GetWplItems(stream);
-            }
+                if (string.Equals(".wpl", extension, StringComparison.OrdinalIgnoreCase))
+                {
+                    return GetWplItems(stream, path);
+                }
 
 
-            if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase))
-            {
-                return GetZplItems(stream);
-            }
+                if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase))
+                {
+                    return GetZplItems(stream, path);
+                }
 
 
-            if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase))
-            {
-                return GetM3uItems(stream);
-            }
+                if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase))
+                {
+                    return GetM3uItems(stream, path);
+                }
 
 
-            if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase))
-            {
-                return GetM3u8Items(stream);
-            }
+                if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase))
+                {
+                    return GetM3u8Items(stream, path);
+                }
 
 
-            if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase))
-            {
-                return GetPlsItems(stream);
+                if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase))
+                {
+                    return GetPlsItems(stream, path);
+                }
             }
             }
 
 
             return Enumerable.Empty<LinkedChild>();
             return Enumerable.Empty<LinkedChild>();
         }
         }
 
 
-        private IEnumerable<LinkedChild> GetPlsItems(Stream stream)
+        private IEnumerable<LinkedChild> GetPlsItems(Stream stream, string path)
         {
         {
             var content = new PlsContent();
             var content = new PlsContent();
             var playlist = content.GetFromStream(stream);
             var playlist = content.GetFromStream(stream);
 
 
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             {
             {
-                Path = i.Path,
+                Path = GetPlaylistItemPath(i.Path, path),
                 Type = LinkedChildType.Manual
                 Type = LinkedChildType.Manual
             });
             });
         }
         }
 
 
-        private IEnumerable<LinkedChild> GetM3u8Items(Stream stream)
+        private IEnumerable<LinkedChild> GetM3u8Items(Stream stream, string path)
         {
         {
             var content = new M3uContent();
             var content = new M3uContent();
             var playlist = content.GetFromStream(stream);
             var playlist = content.GetFromStream(stream);
 
 
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             {
             {
-                Path = i.Path,
+                Path = GetPlaylistItemPath(i.Path, path),
                 Type = LinkedChildType.Manual
                 Type = LinkedChildType.Manual
             });
             });
         }
         }
 
 
-        private IEnumerable<LinkedChild> GetM3uItems(Stream stream)
+        private IEnumerable<LinkedChild> GetM3uItems(Stream stream, string path)
         {
         {
             var content = new M3uContent();
             var content = new M3uContent();
             var playlist = content.GetFromStream(stream);
             var playlist = content.GetFromStream(stream);
 
 
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             {
             {
-                Path = i.Path,
+                Path = GetPlaylistItemPath(i.Path, path),
                 Type = LinkedChildType.Manual
                 Type = LinkedChildType.Manual
             });
             });
         }
         }
 
 
-        private IEnumerable<LinkedChild> GetZplItems(Stream stream)
+        private IEnumerable<LinkedChild> GetZplItems(Stream stream, string path)
         {
         {
             var content = new ZplContent();
             var content = new ZplContent();
             var playlist = content.GetFromStream(stream);
             var playlist = content.GetFromStream(stream);
 
 
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             {
             {
-                Path = i.Path,
+                Path = GetPlaylistItemPath(i.Path, path),
                 Type = LinkedChildType.Manual
                 Type = LinkedChildType.Manual
             });
             });
         }
         }
 
 
-        private IEnumerable<LinkedChild> GetWplItems(Stream stream)
+        private IEnumerable<LinkedChild> GetWplItems(Stream stream, string path)
         {
         {
             var content = new WplContent();
             var content = new WplContent();
             var playlist = content.GetFromStream(stream);
             var playlist = content.GetFromStream(stream);
 
 
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             return playlist.PlaylistEntries.Select(i => new LinkedChild
             {
             {
-                Path = i.Path,
+                Path = GetPlaylistItemPath(i.Path, path),
                 Type = LinkedChildType.Manual
                 Type = LinkedChildType.Manual
             });
             });
         }
         }
 
 
+        private string GetPlaylistItemPath(string itemPath, string containingPlaylistFolder)
+        {
+            if (!File.Exists(itemPath))
+            {
+                var path = Path.Combine(Path.GetDirectoryName(containingPlaylistFolder), itemPath);
+                if (File.Exists(path))
+                {
+                    return path;
+                }
+            }
+
+            return itemPath;
+        }
+
         public bool HasChanged(BaseItem item, IDirectoryService directoryService)
         public bool HasChanged(BaseItem item, IDirectoryService directoryService)
         {
         {
             var path = item.Path;
             var path = item.Path;
@@ -159,7 +173,7 @@ namespace MediaBrowser.Providers.Playlists
                 var file = directoryService.GetFile(path);
                 var file = directoryService.GetFile(path);
                 if (file is not null && file.LastWriteTimeUtc != item.DateModified)
                 if (file is not null && file.LastWriteTimeUtc != item.DateModified)
                 {
                 {
-                    _logger.LogDebug("Refreshing {0} due to date modified timestamp change.", path);
+                    _logger.LogDebug("Refreshing {Path} due to date modified timestamp change.", path);
                     return true;
                     return true;
                 }
                 }
             }
             }