diff options
| author | stefan <stefan@hegedues.at> | 2018-09-12 19:26:21 +0200 |
|---|---|---|
| committer | stefan <stefan@hegedues.at> | 2018-09-12 19:26:21 +0200 |
| commit | 48facb797ed912e4ea6b04b17d1ff190ac2daac4 (patch) | |
| tree | 8dae77a31670a888d733484cb17dd4077d5444e8 /Emby.Server.Implementations/Playlists | |
| parent | c32d8656382a0eacb301692e0084377fc433ae9b (diff) | |
Update to 3.5.2 and .net core 2.1
Diffstat (limited to 'Emby.Server.Implementations/Playlists')
4 files changed, 259 insertions, 83 deletions
diff --git a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs index 2a178895cc..908fa65de1 100644 --- a/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs +++ b/Emby.Server.Implementations/Playlists/ManualPlaylistsFolder.cs @@ -50,8 +50,16 @@ namespace Emby.Server.Implementations.Playlists protected override QueryResult<BaseItem> GetItemsInternal(InternalItemsQuery query) { - query.Recursive = false; - return base.GetItemsInternal(query); + if (query.User == null) + { + query.Recursive = false; + return base.GetItemsInternal(query); + } + + query.Recursive = true; + query.IncludeItemTypes = new string[] { "Playlist" }; + query.Parent = null; + return LibraryManager.GetItemsResult(query); } } } diff --git a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs index 36e8b4dd89..e69b4a34e3 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs @@ -28,11 +28,11 @@ namespace Emby.Server.Implementations.Playlists { } - protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) + protected override List<BaseItem> GetItemsWithImages(BaseItem item) { var playlist = (Playlist)item; - var items = playlist.GetManageableItems() + return playlist.GetManageableItems() .Select(i => { var subItem = i.Item2; @@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Playlists return subItem; } - var parent = subItem.IsOwnedItem ? subItem.GetOwner() : subItem.GetParent(); + var parent = subItem.GetOwner() ?? subItem.GetParent(); if (parent != null && parent.HasImage(ImageType.Primary)) { @@ -66,9 +66,9 @@ namespace Emby.Server.Implementations.Playlists return null; }) .Where(i => i != null) - .DistinctBy(i => i.Id); - - return GetFinalItems(items); + .OrderBy(i => Guid.NewGuid()) + .DistinctBy(i => i.Id) + .ToList(); } } @@ -81,27 +81,20 @@ namespace Emby.Server.Implementations.Playlists _libraryManager = libraryManager; } - protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) + protected override List<BaseItem> GetItemsWithImages(BaseItem item) { - var items = _libraryManager.GetItemList(new InternalItemsQuery + return _libraryManager.GetItemList(new InternalItemsQuery { Genres = new[] { item.Name }, IncludeItemTypes = new[] { typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Audio).Name }, - OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, + OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, Limit = 4, Recursive = true, ImageTypes = new[] { ImageType.Primary }, DtoOptions = new DtoOptions(false) }); - - return GetFinalItems(items); } - - //protected override Task<string> CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) - //{ - // return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); - //} } public class GenreImageProvider : BaseDynamicImageProvider<Genre> @@ -113,21 +106,18 @@ namespace Emby.Server.Implementations.Playlists _libraryManager = libraryManager; } - protected override List<BaseItem> GetItemsWithImages(IHasMetadata item) + protected override List<BaseItem> GetItemsWithImages(BaseItem item) { - var items = _libraryManager.GetItemList(new InternalItemsQuery + return _libraryManager.GetItemList(new InternalItemsQuery { Genres = new[] { item.Name }, IncludeItemTypes = new[] { typeof(Series).Name, typeof(Movie).Name }, - OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, + OrderBy = new[] { new ValueTuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) }, Limit = 4, Recursive = true, ImageTypes = new[] { ImageType.Primary }, DtoOptions = new DtoOptions(false) - }); - - return GetFinalItems(items); } //protected override Task<string> CreateImage(IHasMetadata item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index f268e9c0c1..e0a6f56ecf 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -15,6 +15,10 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Dto; using MediaBrowser.Model.IO; using MediaBrowser.Model.Extensions; +using PlaylistsNET; +using PlaylistsNET.Content; +using PlaylistsNET.Models; +using PlaylistsNET.Utils; namespace Emby.Server.Implementations.Playlists { @@ -37,7 +41,7 @@ namespace Emby.Server.Implementations.Playlists _providerManager = providerManager; } - public IEnumerable<Playlist> GetPlaylists(string userId) + public IEnumerable<Playlist> GetPlaylists(Guid userId) { var user = _userManager.GetUserById(userId); @@ -50,14 +54,14 @@ namespace Emby.Server.Implementations.Playlists var folderName = _fileSystem.GetValidFilename(name) + " [playlist]"; - var parentFolder = GetPlaylistsFolder(null); + var parentFolder = GetPlaylistsFolder(Guid.Empty); if (parentFolder == null) { throw new ArgumentException(); } - if (string.IsNullOrWhiteSpace(options.MediaType)) + if (string.IsNullOrEmpty(options.MediaType)) { foreach (var itemId in options.ItemIdList) { @@ -68,7 +72,7 @@ namespace Emby.Server.Implementations.Playlists throw new ArgumentException("No item exists with the supplied Id"); } - if (!string.IsNullOrWhiteSpace(item.MediaType)) + if (!string.IsNullOrEmpty(item.MediaType)) { options.MediaType = item.MediaType; } @@ -87,18 +91,18 @@ namespace Emby.Server.Implementations.Playlists { options.MediaType = folder.GetRecursiveChildren(i => !i.IsFolder && i.SupportsAddingToPlaylist) .Select(i => i.MediaType) - .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + .FirstOrDefault(i => !string.IsNullOrEmpty(i)); } } - if (!string.IsNullOrWhiteSpace(options.MediaType)) + if (!string.IsNullOrEmpty(options.MediaType)) { break; } } } - if (string.IsNullOrWhiteSpace(options.MediaType)) + if (string.IsNullOrEmpty(options.MediaType)) { options.MediaType = "Audio"; } @@ -117,15 +121,17 @@ namespace Emby.Server.Implementations.Playlists var playlist = new Playlist { Name = name, - Path = path + Path = path, + Shares = new[] + { + new Share + { + UserId = options.UserId.Equals(Guid.Empty) ? null : options.UserId.ToString("N"), + CanEdit = true + } + } }; - playlist.Shares.Add(new Share - { - UserId = options.UserId, - CanEdit = true - }); - playlist.SetMediaType(options.MediaType); parentFolder.AddChild(playlist, CancellationToken.None); @@ -135,7 +141,7 @@ namespace Emby.Server.Implementations.Playlists if (options.ItemIdList.Length > 0) { - await AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user, new DtoOptions(false) + AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user, new DtoOptions(false) { EnableImages = true }); @@ -163,24 +169,24 @@ namespace Emby.Server.Implementations.Playlists return path; } - private List<BaseItem> GetPlaylistItems(IEnumerable<string> itemIds, string playlistMediaType, User user, DtoOptions options) + private List<BaseItem> GetPlaylistItems(IEnumerable<Guid> itemIds, string playlistMediaType, User user, DtoOptions options) { var items = itemIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null); return Playlist.GetPlaylistItems(playlistMediaType, items, user, options); } - public Task AddToPlaylist(string playlistId, IEnumerable<string> itemIds, string userId) + public void AddToPlaylist(string playlistId, IEnumerable<Guid> itemIds, Guid userId) { - var user = string.IsNullOrWhiteSpace(userId) ? null : _userManager.GetUserById(userId); + var user = userId.Equals(Guid.Empty) ? null : _userManager.GetUserById(userId); - return AddToPlaylistInternal(playlistId, itemIds, user, new DtoOptions(false) + AddToPlaylistInternal(playlistId, itemIds, user, new DtoOptions(false) { EnableImages = true }); } - private async Task AddToPlaylistInternal(string playlistId, IEnumerable<string> itemIds, User user, DtoOptions options) + private void AddToPlaylistInternal(string playlistId, IEnumerable<Guid> itemIds, User user, DtoOptions options) { var playlist = _libraryManager.GetItemById(playlistId) as Playlist; @@ -197,11 +203,6 @@ namespace Emby.Server.Implementations.Playlists foreach (var item in items) { - if (string.IsNullOrWhiteSpace(item.Path)) - { - continue; - } - list.Add(LinkedChild.Create(item)); } @@ -211,6 +212,11 @@ namespace Emby.Server.Implementations.Playlists playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None); + if (playlist.IsFile) + { + SavePlaylistFile(playlist); + } + _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(_fileSystem) { ForceSave = true @@ -218,7 +224,7 @@ namespace Emby.Server.Implementations.Playlists }, RefreshPriority.High); } - public async Task RemoveFromPlaylist(string playlistId, IEnumerable<string> entryIds) + public void RemoveFromPlaylist(string playlistId, IEnumerable<string> entryIds) { var playlist = _libraryManager.GetItemById(playlistId) as Playlist; @@ -239,6 +245,11 @@ namespace Emby.Server.Implementations.Playlists playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None); + if (playlist.IsFile) + { + SavePlaylistFile(playlist); + } + _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(_fileSystem) { ForceSave = true @@ -246,7 +257,7 @@ namespace Emby.Server.Implementations.Playlists }, RefreshPriority.High); } - public async Task MoveItem(string playlistId, string entryId, int newIndex) + public void MoveItem(string playlistId, string entryId, int newIndex) { var playlist = _libraryManager.GetItemById(playlistId) as Playlist; @@ -282,9 +293,207 @@ namespace Emby.Server.Implementations.Playlists playlist.LinkedChildren = newList.ToArray(newList.Count); playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None); + + if (playlist.IsFile) + { + SavePlaylistFile(playlist); + } + } + + private void SavePlaylistFile(Playlist item) + { + // This is probably best done as a metatata provider, but saving a file over itself will first require some core work to prevent this from happening when not needed + var playlistPath = item.Path; + var extension = Path.GetExtension(playlistPath); + + if (string.Equals(".wpl", extension, StringComparison.OrdinalIgnoreCase)) + { + var playlist = new WplPlaylist(); + foreach (var child in item.GetLinkedChildren()) + { + var entry = new WplPlaylistEntry() + { + Path = NormalizeItemPath(playlistPath, child.Path), + TrackTitle = child.Name, + AlbumTitle = child.Album + }; + + var hasAlbumArtist = child as IHasAlbumArtist; + if (hasAlbumArtist != null) + { + entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); + } + + var hasArtist = child as IHasArtist; + if (hasArtist != null) + { + entry.TrackArtist = hasArtist.Artists.FirstOrDefault(); + } + + if (child.RunTimeTicks.HasValue) + { + entry.Duration = TimeSpan.FromTicks(child.RunTimeTicks.Value); + } + playlist.PlaylistEntries.Add(entry); + } + + _fileSystem.WriteAllText(playlistPath, new WplContent().ToText(playlist)); + } + if (string.Equals(".zpl", extension, StringComparison.OrdinalIgnoreCase)) + { + var playlist = new ZplPlaylist(); + foreach (var child in item.GetLinkedChildren()) + { + var entry = new ZplPlaylistEntry() + { + Path = NormalizeItemPath(playlistPath, child.Path), + TrackTitle = child.Name, + AlbumTitle = child.Album + }; + + var hasAlbumArtist = child as IHasAlbumArtist; + if (hasAlbumArtist != null) + { + entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); + } + + var hasArtist = child as IHasArtist; + if (hasArtist != null) + { + entry.TrackArtist = hasArtist.Artists.FirstOrDefault(); + } + + if (child.RunTimeTicks.HasValue) + { + entry.Duration = TimeSpan.FromTicks(child.RunTimeTicks.Value); + } + playlist.PlaylistEntries.Add(entry); + } + + _fileSystem.WriteAllText(playlistPath, new ZplContent().ToText(playlist)); + } + if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase)) + { + var playlist = new M3uPlaylist(); + playlist.IsExtended = true; + foreach (var child in item.GetLinkedChildren()) + { + var entry = new M3uPlaylistEntry() + { + Path = NormalizeItemPath(playlistPath, child.Path), + Title = child.Name, + Album = child.Album + }; + + var hasAlbumArtist = child as IHasAlbumArtist; + if (hasAlbumArtist != null) + { + entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); + } + + if (child.RunTimeTicks.HasValue) + { + entry.Duration = TimeSpan.FromTicks(child.RunTimeTicks.Value); + } + playlist.PlaylistEntries.Add(entry); + } + + _fileSystem.WriteAllText(playlistPath, new M3uContent().ToText(playlist)); + } + if (string.Equals(".m3u8", extension, StringComparison.OrdinalIgnoreCase)) + { + var playlist = new M3uPlaylist(); + playlist.IsExtended = true; + foreach (var child in item.GetLinkedChildren()) + { + var entry = new M3uPlaylistEntry() + { + Path = NormalizeItemPath(playlistPath, child.Path), + Title = child.Name, + Album = child.Album + }; + + var hasAlbumArtist = child as IHasAlbumArtist; + if (hasAlbumArtist != null) + { + entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); + } + + if (child.RunTimeTicks.HasValue) + { + entry.Duration = TimeSpan.FromTicks(child.RunTimeTicks.Value); + } + playlist.PlaylistEntries.Add(entry); + } + + _fileSystem.WriteAllText(playlistPath, new M3u8Content().ToText(playlist)); + } + if (string.Equals(".pls", extension, StringComparison.OrdinalIgnoreCase)) + { + var playlist = new PlsPlaylist(); + foreach (var child in item.GetLinkedChildren()) + { + var entry = new PlsPlaylistEntry() + { + Path = NormalizeItemPath(playlistPath, child.Path), + Title = child.Name + }; + + if (child.RunTimeTicks.HasValue) + { + entry.Length = TimeSpan.FromTicks(child.RunTimeTicks.Value); + } + playlist.PlaylistEntries.Add(entry); + } + + _fileSystem.WriteAllText(playlistPath, new PlsContent().ToText(playlist)); + } + } + + private string NormalizeItemPath(string playlistPath, string itemPath) + { + return MakeRelativePath(_fileSystem.GetDirectoryName(playlistPath), itemPath); + } + + private static String MakeRelativePath(string folderPath, string fileAbsolutePath) + { + if (String.IsNullOrEmpty(folderPath)) throw new ArgumentNullException("folderPath"); + if (String.IsNullOrEmpty(fileAbsolutePath)) throw new ArgumentNullException("filePath"); + + if (!folderPath.EndsWith(Path.DirectorySeparatorChar.ToString())) + { + folderPath = folderPath + Path.DirectorySeparatorChar; + } + + Uri folderUri = new Uri(folderPath); + Uri fileAbsoluteUri = new Uri(fileAbsolutePath); + + if (folderUri.Scheme != fileAbsoluteUri.Scheme) { return fileAbsolutePath; } // path can't be made relative. + + Uri relativeUri = folderUri.MakeRelativeUri(fileAbsoluteUri); + String relativePath = Uri.UnescapeDataString(relativeUri.ToString()); + + if (fileAbsoluteUri.Scheme.Equals("file", StringComparison.CurrentCultureIgnoreCase)) + { + relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); + } + + return relativePath; + } + + private static string UnEscape(string content) + { + if (content == null) return content; + return content.Replace("&", "&").Replace("'", "'").Replace(""", "\"").Replace(">", ">").Replace("<", "<"); + } + + private static string Escape(string content) + { + if (content == null) return null; + return content.Replace("&", "&").Replace("'", "'").Replace("\"", """).Replace(">", ">").Replace("<", "<"); } - public Folder GetPlaylistsFolder(string userId) + public Folder GetPlaylistsFolder(Guid userId) { var typeName = "PlaylistsFolder"; diff --git a/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs b/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs deleted file mode 100644 index 2ce835576e..0000000000 --- a/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.IO; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Model.IO; - -namespace Emby.Server.Implementations.Playlists -{ - public class PlaylistsDynamicFolder : IVirtualFolderCreator - { - private readonly IApplicationPaths _appPaths; - private readonly IFileSystem _fileSystem; - - public PlaylistsDynamicFolder(IApplicationPaths appPaths, IFileSystem fileSystem) - { - _appPaths = appPaths; - _fileSystem = fileSystem; - } - - public BasePluginFolder GetFolder() - { - var path = Path.Combine(_appPaths.DataPath, "playlists"); - - _fileSystem.CreateDirectory(path); - - return new PlaylistsFolder - { - Path = path - }; - } - } -} |
