using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Api { /// /// Class GetCriticReviews /// [Route("/Items/{Id}/CriticReviews", "GET")] [Api(Description = "Gets critic reviews for an item")] public class GetCriticReviews : IReturn { /// /// 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; } /// /// Skips over a given number of items within the results. Use for paging. /// /// The start index. [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? StartIndex { get; set; } /// /// The maximum number of items to return /// /// The limit. [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] public int? Limit { get; set; } } /// /// Class GetThemeSongs /// [Route("/Items/{Id}/ThemeSongs", "GET")] [Api(Description = "Gets theme songs for an item")] public class GetThemeSongs : IReturn { /// /// Gets or sets the user id. /// /// The user id. [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; } [ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public bool InheritFromParent { get; set; } } /// /// Class GetThemeVideos /// [Route("/Items/{Id}/ThemeVideos", "GET")] [Api(Description = "Gets theme videos for an item")] public class GetThemeVideos : IReturn { /// /// Gets or sets the user id. /// /// The user id. [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; } [ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public bool InheritFromParent { get; set; } } /// /// Class GetThemeVideos /// [Route("/Items/{Id}/ThemeMedia", "GET")] [Api(Description = "Gets theme videos and songs for an item")] public class GetThemeMedia : IReturn { /// /// Gets or sets the user id. /// /// The user id. [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; } [ApiMember(Name = "InheritFromParent", Description = "Determines whether or not parent items should be searched for theme media.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public bool InheritFromParent { get; set; } } [Route("/Library/Refresh", "POST")] [Api(Description = "Starts a library scan")] public class RefreshLibrary : IReturnVoid { } [Route("/Items/{Id}", "DELETE")] [Api(Description = "Deletes an item from the library and file system")] public class DeleteItem : IReturnVoid { [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")] public string Id { get; set; } } [Route("/Items/Counts", "GET")] [Api(Description = "Gets counts of various item types")] public class GetItemCounts : IReturn { [ApiMember(Name = "UserId", Description = "Optional. Get counts from a specific user's library.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public Guid? UserId { get; set; } } [Route("/Items/{Id}/Ancestors", "GET")] [Api(Description = "Gets all parents of an item")] public class GetAncestors : IReturn { /// /// Gets or sets the user id. /// /// The user id. [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; } } /// /// Class LibraryService /// public class LibraryService : BaseApiService { /// /// The _item repo /// private readonly IItemRepository _itemRepo; private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; private readonly IUserDataRepository _userDataRepository; /// /// Initializes a new instance of the class. /// /// The item repo. /// The library manager. /// The user manager. /// The user data repository. public LibraryService(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(GetAncestors request) { var result = GetAncestors(request).Result; return ToOptimizedResult(result); } /// /// Gets the ancestors. /// /// The request. /// Task{BaseItemDto[]}. public async Task GetAncestors(GetAncestors request) { var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager); var tasks = new List>(); var user = request.UserId.HasValue ? _userManager.GetUserById(request.UserId.Value) : null; // 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, _itemRepo); BaseItem parent = item.Parent; while (parent != null) { if (user != null) { parent = TranslateParentItem(parent, user); } tasks.Add(dtoBuilder.GetBaseItemDto(parent, fields, user)); if (parent is UserRootFolder) { break; } parent = parent.Parent; } return await Task.WhenAll(tasks).ConfigureAwait(false); } private BaseItem TranslateParentItem(BaseItem item, User user) { if (item.Parent is AggregateFolder) { return user.RootFolder.GetChildren(user, true).FirstOrDefault(i => { try { return i.LocationType == LocationType.FileSystem && i.ResolveArgs.PhysicalLocations.Contains(item.Path); } catch (Exception ex) { Logger.ErrorException("Error getting ResolveArgs for {0}", ex, i.Path); return false; } }); } return item; } /// /// Gets the specified request. /// /// The request. /// System.Object. public object Get(GetCriticReviews request) { var result = GetCriticReviewsAsync(request).Result; return ToOptimizedResult(result); } /// /// Gets the specified request. /// /// The request. /// System.Object. public object Get(GetItemCounts request) { var items = GetItems(request.UserId).ToList(); var counts = new ItemCounts { AlbumCount = items.OfType().Count(), EpisodeCount = items.OfType().Count(), GameCount = items.OfType().Count(), MovieCount = items.OfType().Count(), SeriesCount = items.OfType().Count(), SongCount = items.OfType