diff --git a/MediaBrowser.Api/LibraryService.cs b/MediaBrowser.Api/LibraryService.cs index 16f862cf0e..8f4d147d70 100644 --- a/MediaBrowser.Api/LibraryService.cs +++ b/MediaBrowser.Api/LibraryService.cs @@ -415,26 +415,24 @@ namespace MediaBrowser.Api : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, request.UserId); // Get everything - var fields = - Enum.GetNames(typeof(ItemFields)) + var fields = Enum.GetNames(typeof(ItemFields)) .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) .ToList(); var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository); - var items = - _itemRepo.GetItems(item.ThemeSongIds) + var items = _itemRepo.GetItems(item.ThemeSongIds) .OrderBy(i => i.SortName) .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user)) .Select(t => t.Result) .ToArray(); var result = new ThemeSongsResult - { - Items = items, - TotalRecordCount = items.Length, - OwnerId = DtoBuilder.GetClientItemId(item) - }; + { + Items = items, + TotalRecordCount = items.Length, + OwnerId = DtoBuilder.GetClientItemId(item) + }; return ToOptimizedResult(result); } diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 13098b716b..82c632c114 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -114,6 +114,7 @@ + diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs new file mode 100644 index 0000000000..d2b58dc968 --- /dev/null +++ b/MediaBrowser.Api/VideosService.cs @@ -0,0 +1,82 @@ +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Model.Querying; +using ServiceStack.ServiceHost; +using System; +using System.Linq; + +namespace MediaBrowser.Api +{ + [Route("/Videos/{Id}/AdditionalParts", "GET")] + [Api(Description = "Gets additional parts for a video.")] + public class GetAdditionalParts : IReturn + { + [ApiMember(Name = "UserId", Description = "Optional. Filter by user id, and attach user data", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public Guid? UserId { 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 IItemRepository _itemRepo; + + private readonly ILibraryManager _libraryManager; + private readonly IUserManager _userManager; + private readonly IUserDataRepository _userDataRepository; + + public VideosService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, IUserDataRepository userDataRepository) + { + _itemRepo = itemRepo; + _libraryManager = libraryManager; + _userManager = userManager; + _userDataRepository = userDataRepository; + } + + /// + /// Gets the specified request. + /// + /// The request. + /// System.Object. + public object Get(GetAdditionalParts request) + { + var user = request.UserId.HasValue ? _userManager.GetUserById(request.UserId.Value) : null; + + var item = string.IsNullOrEmpty(request.Id) + ? (request.UserId.HasValue + ? user.RootFolder + : (Folder)_libraryManager.RootFolder) + : DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, request.UserId); + + // Get everything + var fields = Enum.GetNames(typeof(ItemFields)) + .Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)) + .ToList(); + + var dtoBuilder = new DtoBuilder(Logger, _libraryManager, _userDataRepository); + + var video = (Video)item; + + var items = _itemRepo.GetItems(video.AdditionalPartIds) + .OrderBy(i => i.SortName) + .Select(i => dtoBuilder.GetBaseItemDto(i, fields, user)) + .Select(t => t.Result) + .ToArray(); + + var result = new ItemsResult + { + Items = items, + TotalRecordCount = items.Length + }; + + return ToOptimizedResult(result); + } + } +} diff --git a/MediaBrowser.Controller/Dto/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs index 2543d70374..7fd188acb5 100644 --- a/MediaBrowser.Controller/Dto/DtoBuilder.cs +++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs @@ -183,7 +183,7 @@ namespace MediaBrowser.Controller.Dto } dto.OriginalPrimaryImageAspectRatio = size.Width / size.Height; - + var supportedEnhancers = Kernel.Instance.ImageManager.ImageEnhancers.Where(i => { try @@ -239,7 +239,7 @@ namespace MediaBrowser.Controller.Dto dto.LockedImages = item.LockedImages; dto.EnableInternetProviders = !item.DontFetchMeta; } - + if (fields.Contains(ItemFields.Budget)) { dto.Budget = item.Budget; @@ -264,7 +264,7 @@ namespace MediaBrowser.Controller.Dto { dto.Tags = item.Tags; } - + if (fields.Contains(ItemFields.ProductionLocations)) { dto.ProductionLocations = item.ProductionLocations; @@ -441,6 +441,8 @@ namespace MediaBrowser.Controller.Dto dto.VideoFormat = video.VideoFormat; dto.IsoType = video.IsoType; + dto.PartCount = video.AdditionalPartIds.Count + 1; + if (fields.Contains(ItemFields.Chapters) && video.Chapters != null) { dto.Chapters = video.Chapters.Select(c => GetChapterInfoDto(c, item)).ToList(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 3a28793138..9e28e42424 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -753,7 +753,7 @@ namespace MediaBrowser.Controller.Entities // Support xbmc trailers (-trailer suffix on video file names) files.AddRange(resolveArgs.FileSystemChildren.Where(i => { - if (!i.Attributes.HasFlag(FileAttributes.Directory)) + if ((i.Attributes & FileAttributes.Directory) != FileAttributes.Directory) { if (System.IO.Path.GetFileNameWithoutExtension(i.Name).EndsWith(XbmcTrailerFileSuffix, StringComparison.OrdinalIgnoreCase) && !string.Equals(Path, i.FullName, StringComparison.OrdinalIgnoreCase)) { @@ -916,14 +916,11 @@ namespace MediaBrowser.Controller.Entities /// if set to true [is new item]. /// if set to true [force]. /// if set to true [allow slow providers]. - /// if set to true [reset resolve args]. /// true if a provider reports we changed - public virtual async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public virtual async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) { - if (resetResolveArgs) - { - ResolveArgs = null; - } + // Reload this + ResolveArgs = null; // Refresh for the item var itemRefreshTask = ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh, allowSlowProviders); diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 2033130937..ce36366b43 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -768,7 +768,7 @@ namespace MediaBrowser.Controller.Entities var child = currentTuple.Item1; //refresh it - await child.RefreshMetadata(cancellationToken, resetResolveArgs: child.IsFolder, forceSave: currentTuple.Item2, forceRefresh: forceRefreshMetadata).ConfigureAwait(false); + await child.RefreshMetadata(cancellationToken, forceSave: currentTuple.Item2, forceRefresh: forceRefreshMetadata).ConfigureAwait(false); // Refresh children if a folder and the item changed or recursive is set to true var refreshChildren = child.IsFolder && (currentTuple.Item2 || (recursive.HasValue && recursive.Value)); diff --git a/MediaBrowser.Controller/Entities/IndexFolder.cs b/MediaBrowser.Controller/Entities/IndexFolder.cs index 165bab6328..c748b231ed 100644 --- a/MediaBrowser.Controller/Entities/IndexFolder.cs +++ b/MediaBrowser.Controller/Entities/IndexFolder.cs @@ -195,9 +195,8 @@ namespace MediaBrowser.Controller.Entities /// if set to true [is new item]. /// if set to true [force]. /// if set to true [allow slow providers]. - /// if set to true [reset resolve args]. /// Task{System.Boolean}. - public override Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public override Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) { // We should never get in here since these are not part of the library return Task.FromResult(false); diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs index 5a3fb88188..2e9cc3bea3 100644 --- a/MediaBrowser.Controller/Entities/Movies/Movie.cs +++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs @@ -62,12 +62,11 @@ namespace MediaBrowser.Controller.Entities.Movies /// if set to true [is new item]. /// if set to true [force]. /// if set to true [allow slow providers]. - /// if set to true [reset resolve args]. /// Task{System.Boolean}. - public override async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true, bool resetResolveArgs = true) + public override async Task RefreshMetadata(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false, bool allowSlowProviders = true) { // Kick off a task to refresh the main item - var result = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders, resetResolveArgs).ConfigureAwait(false); + var result = await base.RefreshMetadata(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); var specialFeaturesChanged = await RefreshSpecialFeatures(cancellationToken, forceSave, forceRefresh, allowSlowProviders).ConfigureAwait(false); @@ -127,7 +126,7 @@ namespace MediaBrowser.Controller.Entities.Movies } catch (IOException ex) { - Logger.ErrorException("Error loading trailers for {0}", ex, Name); + Logger.ErrorException("Error loading special features for {0}", ex, Name); return new List