From d55af4f5292236317f572e0bddfe9575a21c4662 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 15 Mar 2014 00:14:07 -0400 Subject: support grouping behind boxsets --- .../Collections/CollectionManager.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'MediaBrowser.Server.Implementations/Collections') diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs index 9a196cc47a..8e70c1d3dc 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs @@ -126,6 +126,18 @@ namespace MediaBrowser.Server.Implementations.Collections ItemType = item.GetType().Name, Type = LinkedChildType.Manual }); + + var supportsGrouping = item as ISupportsBoxSetGrouping; + + if (supportsGrouping != null) + { + var boxsetIdList = supportsGrouping.BoxSetIdList.ToList(); + if (!boxsetIdList.Contains(collectionId)) + { + boxsetIdList.Add(collectionId); + } + supportsGrouping.BoxSetIdList = boxsetIdList; + } } collection.LinkedChildren.AddRange(list); @@ -156,6 +168,16 @@ namespace MediaBrowser.Server.Implementations.Collections } list.Add(child); + + var childItem = _libraryManager.GetItemById(itemId); + var supportsGrouping = childItem as ISupportsBoxSetGrouping; + + if (supportsGrouping != null) + { + var boxsetIdList = supportsGrouping.BoxSetIdList.ToList(); + boxsetIdList.Remove(collectionId); + supportsGrouping.BoxSetIdList = boxsetIdList; + } } var shortcutFiles = Directory -- cgit v1.2.3 From 9a6afa92889c57e5f7b0e8cc937376fe6393ebb4 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 15 Mar 2014 11:17:46 -0400 Subject: Add new params to collection creation --- MediaBrowser.Controller/Collections/CollectionCreationOptions.cs | 3 +++ MediaBrowser.Controller/Collections/ICollectionManager.cs | 5 +++-- .../Collections/CollectionManager.cs | 9 ++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Collections') diff --git a/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs b/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs index e147e09056..74ae420950 100644 --- a/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs +++ b/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs @@ -14,9 +14,12 @@ namespace MediaBrowser.Controller.Collections public Dictionary ProviderIds { get; set; } + public List ItemIdList { get; set; } + public CollectionCreationOptions() { ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); + ItemIdList = new List(); } } } diff --git a/MediaBrowser.Controller/Collections/ICollectionManager.cs b/MediaBrowser.Controller/Collections/ICollectionManager.cs index d7bc178ad3..af65bbacaf 100644 --- a/MediaBrowser.Controller/Collections/ICollectionManager.cs +++ b/MediaBrowser.Controller/Collections/ICollectionManager.cs @@ -1,4 +1,5 @@ -using System; +using MediaBrowser.Controller.Entities.Movies; +using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -11,7 +12,7 @@ namespace MediaBrowser.Controller.Collections /// /// The options. /// Task. - Task CreateCollection(CollectionCreationOptions options); + Task CreateCollection(CollectionCreationOptions options); /// /// Adds to collection. diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs index 8e70c1d3dc..60d631c1ad 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs @@ -26,7 +26,7 @@ namespace MediaBrowser.Server.Implementations.Collections _iLibraryMonitor = iLibraryMonitor; } - public async Task CreateCollection(CollectionCreationOptions options) + public async Task CreateCollection(CollectionCreationOptions options) { var name = options.Name; @@ -64,6 +64,13 @@ namespace MediaBrowser.Server.Implementations.Collections await collection.RefreshMetadata(new MetadataRefreshOptions(), CancellationToken.None) .ConfigureAwait(false); + + if (options.ItemIdList.Count > 0) + { + await AddToCollection(collection.Id, options.ItemIdList); + } + + return collection; } finally { -- cgit v1.2.3 From b36aea4ff74052ae40c27db057f50f645659aa57 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 16 Mar 2014 00:23:58 -0400 Subject: #712 - Support grouping multiple versions of a movie --- MediaBrowser.Api/VideosService.cs | 95 +++++++++++++++++++++- MediaBrowser.Controller/Entities/Video.cs | 86 ++++++++++++++++---- MediaBrowser.Dlna/PlayTo/DlnaController.cs | 21 +++-- MediaBrowser.Dlna/PlayTo/PlayToManager.cs | 2 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 3 +- MediaBrowser.Model/Session/PlayRequest.cs | 6 ++ MediaBrowser.Model/Session/PlaystateCommand.cs | 6 ++ MediaBrowser.Providers/All/LocalImageProvider.cs | 15 ++-- .../Collections/CollectionManager.cs | 3 +- .../Dto/DtoService.cs | 7 +- .../Library/Resolvers/Movies/MovieResolver.cs | 2 +- .../Session/SessionManager.cs | 10 +++ 12 files changed, 217 insertions(+), 39 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Collections') diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs index 31fda199e5..af200895eb 100644 --- a/MediaBrowser.Api/VideosService.cs +++ b/MediaBrowser.Api/VideosService.cs @@ -1,4 +1,7 @@ -using MediaBrowser.Controller.Dto; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Querying; @@ -37,14 +40,44 @@ namespace MediaBrowser.Api [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public string Id { get; set; } } - + + [Route("/Videos/{Id}/AlternateVersions", "POST")] + [Api(Description = "Assigns videos as alternates of antoher.")] + public class PostAlternateVersions : IReturnVoid + { + [ApiMember(Name = "AlternateVersionIds", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] + public string AlternateVersionIds { get; set; } + + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + + [Route("/Videos/{Id}/AlternateVersions", "DELETE")] + [Api(Description = "Assigns videos as alternates of antoher.")] + public class DeleteAlternateVersions : IReturnVoid + { + [ApiMember(Name = "AlternateVersionIds", Description = "Item id, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")] + public string AlternateVersionIds { get; set; } + + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] + public string Id { get; set; } + } + public class VideosService : BaseApiService { private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; private readonly IDtoService _dtoService; - public VideosService( ILibraryManager libraryManager, IUserManager userManager, IDtoService dtoService) + public VideosService(ILibraryManager libraryManager, IUserManager userManager, IDtoService dtoService) { _libraryManager = libraryManager; _userManager = userManager; @@ -115,5 +148,61 @@ namespace MediaBrowser.Api return ToOptimizedSerializedResultUsingCache(result); } + + public void Post(PostAlternateVersions request) + { + var task = AddAlternateVersions(request); + + Task.WaitAll(task); + } + + public void Delete(DeleteAlternateVersions request) + { + var task = RemoveAlternateVersions(request); + + Task.WaitAll(task); + } + + private async Task AddAlternateVersions(PostAlternateVersions request) + { + var video = (Video)_dtoService.GetItemByDtoId(request.Id); + + var list = new List(); + var currentAlternateVersions = video.GetAlternateVersions().ToList(); + + foreach (var itemId in request.AlternateVersionIds.Split(',').Select(i => new Guid(i))) + { + var item = _libraryManager.GetItemById(itemId) as Video; + + if (item == null) + { + throw new ArgumentException("No item exists with the supplied Id"); + } + + if (currentAlternateVersions.Any(i => i.Id == itemId)) + { + throw new ArgumentException("Item already exists."); + } + + list.Add(new LinkedChild + { + Path = item.Path, + Type = LinkedChildType.Manual + }); + + item.PrimaryVersionId = video.Id; + } + + video.LinkedAlternateVersions.AddRange(list); + + await video.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false); + + await video.RefreshMetadata(CancellationToken.None).ConfigureAwait(false); + } + + private async Task RemoveAlternateVersions(DeleteAlternateVersions request) + { + var video = (Video)_dtoService.GetItemByDtoId(request.Id); + } } } diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index e30458dd8f..18db21f382 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; @@ -20,26 +21,27 @@ namespace MediaBrowser.Controller.Entities { public bool IsMultiPart { get; set; } public bool HasLocalAlternateVersions { get; set; } + public Guid? PrimaryVersionId { get; set; } public List AdditionalPartIds { get; set; } - public List AlternateVersionIds { get; set; } + public List LocalAlternateVersionIds { get; set; } public Video() { PlayableStreamFileNames = new List(); AdditionalPartIds = new List(); - AlternateVersionIds = new List(); + LocalAlternateVersionIds = new List(); Tags = new List(); SubtitleFiles = new List(); LinkedAlternateVersions = new List(); } [IgnoreDataMember] - public bool HasAlternateVersions + public int AlternateVersionCount { get { - return HasLocalAlternateVersions || LinkedAlternateVersions.Count > 0; + return LinkedAlternateVersions.Count + LocalAlternateVersionIds.Count; } } @@ -51,7 +53,7 @@ namespace MediaBrowser.Controller.Entities /// IEnumerable{BaseItem}. public IEnumerable GetAlternateVersions() { - var filesWithinSameDirectory = AlternateVersionIds + var filesWithinSameDirectory = LocalAlternateVersionIds .Select(i => LibraryManager.GetItemById(i)) .Where(i => i != null) .OfType /// The part count. public int? PartCount { get; set; } - public bool? HasAlternateVersions { get; set; } + public int? AlternateVersionCount { get; set; } + public string PrimaryVersionId { get; set; } /// /// Determines whether the specified type is type. diff --git a/MediaBrowser.Model/Session/PlayRequest.cs b/MediaBrowser.Model/Session/PlayRequest.cs index 57f6c37f57..949274a5d5 100644 --- a/MediaBrowser.Model/Session/PlayRequest.cs +++ b/MediaBrowser.Model/Session/PlayRequest.cs @@ -23,6 +23,12 @@ namespace MediaBrowser.Model.Session /// /// The play command. public PlayCommand PlayCommand { get; set; } + + /// + /// Gets or sets the controlling user identifier. + /// + /// The controlling user identifier. + public string ControllingUserId { get; set; } } /// diff --git a/MediaBrowser.Model/Session/PlaystateCommand.cs b/MediaBrowser.Model/Session/PlaystateCommand.cs index 918f4f70f4..b0dec66d4f 100644 --- a/MediaBrowser.Model/Session/PlaystateCommand.cs +++ b/MediaBrowser.Model/Session/PlaystateCommand.cs @@ -37,5 +37,11 @@ namespace MediaBrowser.Model.Session public PlaystateCommand Command { get; set; } public long? SeekPositionTicks { get; set; } + + /// + /// Gets or sets the controlling user identifier. + /// + /// The controlling user identifier. + public string ControllingUserId { get; set; } } } \ No newline at end of file diff --git a/MediaBrowser.Providers/All/LocalImageProvider.cs b/MediaBrowser.Providers/All/LocalImageProvider.cs index 6ef5f6bf37..1d10fcfa35 100644 --- a/MediaBrowser.Providers/All/LocalImageProvider.cs +++ b/MediaBrowser.Providers/All/LocalImageProvider.cs @@ -94,14 +94,13 @@ namespace MediaBrowser.Providers.All public List GetImages(IHasImages item, IEnumerable paths, IDirectoryService directoryService) { var files = paths.SelectMany(directoryService.GetFiles) - .Where(i => - { - var ext = i.Extension; - - return !string.IsNullOrEmpty(ext) && - BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase); - }) - .Cast() + .Where(i => + { + var ext = i.Extension; + + return !string.IsNullOrEmpty(ext) && + BaseItem.SupportedImageExtensions.Contains(ext, StringComparer.OrdinalIgnoreCase); + }) .ToList(); var list = new List(); diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs index 60d631c1ad..c188562935 100644 --- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs +++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs @@ -111,6 +111,7 @@ namespace MediaBrowser.Server.Implementations.Collections } var list = new List(); + var currentLinkedChildren = collection.GetLinkedChildren().ToList(); foreach (var itemId in ids) { @@ -121,7 +122,7 @@ namespace MediaBrowser.Server.Implementations.Collections throw new ArgumentException("No item exists with the supplied Id"); } - if (collection.LinkedChildren.Any(i => i.ItemId.HasValue && i.ItemId == itemId)) + if (currentLinkedChildren.Any(i => i.Id == itemId)) { throw new ArgumentException("Item already exists in collection"); } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 6f6a3f0435..19d834c208 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1082,7 +1082,12 @@ namespace MediaBrowser.Server.Implementations.Dto dto.IsHD = video.IsHD; dto.PartCount = video.AdditionalPartIds.Count + 1; - dto.HasAlternateVersions = video.HasAlternateVersions; + dto.AlternateVersionCount = video.AlternateVersionCount; + + if (video.PrimaryVersionId.HasValue) + { + dto.PrimaryVersionId = video.PrimaryVersionId.Value.ToString("N"); + } if (fields.Contains(ItemFields.Chapters)) { diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index de10e669e2..b11457ec54 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -410,7 +410,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies if (!string.IsNullOrWhiteSpace(filenamePrefix)) { - if (sortedMovies.All(i => Path.GetFileNameWithoutExtension(i.Path).StartsWith(filenamePrefix, StringComparison.OrdinalIgnoreCase))) + if (sortedMovies.Skip(1).All(i => Path.GetFileNameWithoutExtension(i.Path).StartsWith(filenamePrefix + " - ", StringComparison.OrdinalIgnoreCase))) { firstMovie.HasLocalAlternateVersions = true; diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 71d95b97bd..cea70a8b4e 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -690,6 +690,11 @@ namespace MediaBrowser.Server.Implementations.Session } } + if (session.UserId.HasValue) + { + command.ControllingUserId = session.UserId.Value.ToString("N"); + } + return session.SessionController.SendPlayCommand(command, cancellationToken); } @@ -723,6 +728,11 @@ namespace MediaBrowser.Server.Implementations.Session throw new ArgumentException(string.Format("Session {0} is unable to seek.", session.Id)); } + if (session.UserId.HasValue) + { + command.ControllingUserId = session.UserId.Value.ToString("N"); + } + return session.SessionController.SendPlaystateCommand(command, cancellationToken); } -- cgit v1.2.3