diff options
| author | Luke <luke.pulverenti@gmail.com> | 2016-12-18 00:44:33 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-12-18 00:44:33 -0500 |
| commit | e7cebb91a73354dc3e0d0b6340c9fbd6511f4406 (patch) | |
| tree | 6f1c368c766c17b7514fe749c0e92e69cd89194a /Emby.Server.Implementations/Playlists | |
| parent | 025905a3e4d50b9a2e07fbf4ff0a203af6604ced (diff) | |
| parent | aaa027f3229073e9a40756c3157d41af2a442922 (diff) | |
Merge pull request #2350 from MediaBrowser/beta
Beta
Diffstat (limited to 'Emby.Server.Implementations/Playlists')
3 files changed, 412 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs new file mode 100644 index 0000000000..ef7d6dba82 --- /dev/null +++ b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs @@ -0,0 +1,104 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Emby.Server.Implementations.Images; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Querying; + +namespace Emby.Server.Implementations.Playlists +{ + public class PlaylistImageProvider : BaseDynamicImageProvider<Playlist> + { + public PlaylistImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + } + + protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item) + { + var playlist = (Playlist)item; + + var items = playlist.GetManageableItems() + .Select(i => + { + var subItem = i.Item2; + + var episode = subItem as Episode; + + if (episode != null) + { + var series = episode.Series; + if (series != null && series.HasImage(ImageType.Primary)) + { + return series; + } + } + + if (subItem.HasImage(ImageType.Primary)) + { + return subItem; + } + + var parent = subItem.GetParent(); + + if (parent != null && parent.HasImage(ImageType.Primary)) + { + if (parent is MusicAlbum) + { + return parent; + } + } + + return null; + }) + .Where(i => i != null) + .DistinctBy(i => i.Id) + .ToList(); + + return Task.FromResult(GetFinalItems(items)); + } + } + + public class MusicGenreImageProvider : BaseDynamicImageProvider<MusicGenre> + { + private readonly ILibraryManager _libraryManager; + + public MusicGenreImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, ILibraryManager libraryManager) : base(fileSystem, providerManager, applicationPaths, imageProcessor) + { + _libraryManager = libraryManager; + } + + protected override Task<List<BaseItem>> GetItemsWithImages(IHasImages item) + { + var items = _libraryManager.GetItemList(new InternalItemsQuery + { + Genres = new[] { item.Name }, + IncludeItemTypes = new[] { typeof(MusicAlbum).Name, typeof(MusicVideo).Name, typeof(Audio).Name }, + SortBy = new[] { ItemSortBy.Random }, + Limit = 4, + Recursive = true, + ImageTypes = new[] { ImageType.Primary } + + }).ToList(); + + return Task.FromResult(GetFinalItems(items)); + } + + //protected override Task<string> CreateImage(IHasImages item, List<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) + //{ + // return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); + //} + } + +} diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs new file mode 100644 index 0000000000..9583141e0d --- /dev/null +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -0,0 +1,276 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Playlists; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Playlists; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; + +namespace Emby.Server.Implementations.Playlists +{ + public class PlaylistManager : IPlaylistManager + { + private readonly ILibraryManager _libraryManager; + private readonly IFileSystem _fileSystem; + private readonly ILibraryMonitor _iLibraryMonitor; + private readonly ILogger _logger; + private readonly IUserManager _userManager; + private readonly IProviderManager _providerManager; + + public PlaylistManager(ILibraryManager libraryManager, IFileSystem fileSystem, ILibraryMonitor iLibraryMonitor, ILogger logger, IUserManager userManager, IProviderManager providerManager) + { + _libraryManager = libraryManager; + _fileSystem = fileSystem; + _iLibraryMonitor = iLibraryMonitor; + _logger = logger; + _userManager = userManager; + _providerManager = providerManager; + } + + public IEnumerable<Playlist> GetPlaylists(string userId) + { + var user = _userManager.GetUserById(userId); + + return GetPlaylistsFolder(userId).GetChildren(user, true).OfType<Playlist>(); + } + + public async Task<PlaylistCreationResult> CreatePlaylist(PlaylistCreationRequest options) + { + var name = options.Name; + + var folderName = _fileSystem.GetValidFilename(name) + " [playlist]"; + + var parentFolder = GetPlaylistsFolder(null); + + if (parentFolder == null) + { + throw new ArgumentException(); + } + + if (string.IsNullOrWhiteSpace(options.MediaType)) + { + foreach (var itemId in options.ItemIdList) + { + var item = _libraryManager.GetItemById(itemId); + + if (item == null) + { + throw new ArgumentException("No item exists with the supplied Id"); + } + + if (!string.IsNullOrWhiteSpace(item.MediaType)) + { + options.MediaType = item.MediaType; + } + else if (item is MusicArtist || item is MusicAlbum || item is MusicGenre) + { + options.MediaType = MediaType.Audio; + } + else if (item is Genre) + { + options.MediaType = MediaType.Video; + } + else + { + var folder = item as Folder; + if (folder != null) + { + options.MediaType = folder.GetRecursiveChildren(i => !i.IsFolder && i.SupportsAddingToPlaylist) + .Select(i => i.MediaType) + .FirstOrDefault(i => !string.IsNullOrWhiteSpace(i)); + } + } + + if (!string.IsNullOrWhiteSpace(options.MediaType)) + { + break; + } + } + } + + if (string.IsNullOrWhiteSpace(options.MediaType)) + { + throw new ArgumentException("A playlist media type is required."); + } + + var user = _userManager.GetUserById(options.UserId); + + var path = Path.Combine(parentFolder.Path, folderName); + path = GetTargetPath(path); + + _iLibraryMonitor.ReportFileSystemChangeBeginning(path); + + try + { + _fileSystem.CreateDirectory(path); + + var playlist = new Playlist + { + Name = name, + Path = path + }; + + playlist.Shares.Add(new Share + { + UserId = options.UserId, + CanEdit = true + }); + + playlist.SetMediaType(options.MediaType); + + await parentFolder.AddChild(playlist, CancellationToken.None).ConfigureAwait(false); + + await playlist.RefreshMetadata(new MetadataRefreshOptions(_fileSystem) { ForceSave = true }, CancellationToken.None) + .ConfigureAwait(false); + + if (options.ItemIdList.Count > 0) + { + await AddToPlaylistInternal(playlist.Id.ToString("N"), options.ItemIdList, user); + } + + return new PlaylistCreationResult + { + Id = playlist.Id.ToString("N") + }; + } + finally + { + // Refresh handled internally + _iLibraryMonitor.ReportFileSystemChangeComplete(path, false); + } + } + + private string GetTargetPath(string path) + { + while (_fileSystem.DirectoryExists(path)) + { + path += "1"; + } + + return path; + } + + private Task<IEnumerable<BaseItem>> GetPlaylistItems(IEnumerable<string> itemIds, string playlistMediaType, User user) + { + var items = itemIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null); + + return Playlist.GetPlaylistItems(playlistMediaType, items, user); + } + + public Task AddToPlaylist(string playlistId, IEnumerable<string> itemIds, string userId) + { + var user = string.IsNullOrWhiteSpace(userId) ? null : _userManager.GetUserById(userId); + + return AddToPlaylistInternal(playlistId, itemIds, user); + } + + private async Task AddToPlaylistInternal(string playlistId, IEnumerable<string> itemIds, User user) + { + var playlist = _libraryManager.GetItemById(playlistId) as Playlist; + + if (playlist == null) + { + throw new ArgumentException("No Playlist exists with the supplied Id"); + } + + var list = new List<LinkedChild>(); + + var items = (await GetPlaylistItems(itemIds, playlist.MediaType, user).ConfigureAwait(false)) + .Where(i => i.SupportsAddingToPlaylist) + .ToList(); + + foreach (var item in items) + { + list.Add(LinkedChild.Create(item)); + } + + playlist.LinkedChildren.AddRange(list); + + await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + + _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(_fileSystem) + { + ForceSave = true + }); + } + + public async Task RemoveFromPlaylist(string playlistId, IEnumerable<string> entryIds) + { + var playlist = _libraryManager.GetItemById(playlistId) as Playlist; + + if (playlist == null) + { + throw new ArgumentException("No Playlist exists with the supplied Id"); + } + + var children = playlist.GetManageableItems().ToList(); + + var idList = entryIds.ToList(); + + var removals = children.Where(i => idList.Contains(i.Item1.Id)); + + playlist.LinkedChildren = children.Except(removals) + .Select(i => i.Item1) + .ToList(); + + await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + + _providerManager.QueueRefresh(playlist.Id, new MetadataRefreshOptions(_fileSystem) + { + ForceSave = true + }); + } + + public async Task MoveItem(string playlistId, string entryId, int newIndex) + { + var playlist = _libraryManager.GetItemById(playlistId) as Playlist; + + if (playlist == null) + { + throw new ArgumentException("No Playlist exists with the supplied Id"); + } + + var children = playlist.GetManageableItems().ToList(); + + var oldIndex = children.FindIndex(i => string.Equals(entryId, i.Item1.Id, StringComparison.OrdinalIgnoreCase)); + + if (oldIndex == newIndex) + { + return; + } + + var item = playlist.LinkedChildren[oldIndex]; + + playlist.LinkedChildren.Remove(item); + + if (newIndex >= playlist.LinkedChildren.Count) + { + playlist.LinkedChildren.Add(item); + } + else + { + playlist.LinkedChildren.Insert(newIndex, item); + } + + await playlist.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + } + + public Folder GetPlaylistsFolder(string userId) + { + var typeName = "PlaylistsFolder"; + + return _libraryManager.RootFolder.Children.OfType<Folder>().FirstOrDefault(i => string.Equals(i.GetType().Name, typeName, StringComparison.Ordinal)) ?? + _libraryManager.GetUserRootFolder().Children.OfType<Folder>().FirstOrDefault(i => string.Equals(i.GetType().Name, typeName, StringComparison.Ordinal)); + } + } +} diff --git a/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs b/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs new file mode 100644 index 0000000000..dacc937e1a --- /dev/null +++ b/Emby.Server.Implementations/Playlists/PlaylistsDynamicFolder.cs @@ -0,0 +1,32 @@ +using System.IO; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.IO; +using MediaBrowser.Server.Implementations.Playlists; + +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 + }; + } + } +} |
