using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; namespace MediaBrowser.Api.UserLibrary { /// /// Class BaseItemsByNameService /// /// The type of the T item type. public abstract class BaseItemsByNameService : BaseRestService where TItemType : BaseItem { /// /// The _user manager /// protected readonly IUserManager UserManager; protected readonly ILibraryManager LibraryManager; /// /// Initializes a new instance of the class. /// /// The user manager. protected BaseItemsByNameService(IUserManager userManager, ILibraryManager libraryManager) { UserManager = userManager; LibraryManager = libraryManager; } /// /// Gets the specified request. /// /// The request. /// Task{ItemsResult}. protected async Task GetResult(GetItemsByName request) { var user = UserManager.GetUserById(request.UserId); var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.Id, UserManager, LibraryManager, user.Id); IEnumerable items; if (item.IsFolder) { var folder = (Folder)item; items = request.Recursive ? folder.GetRecursiveChildren(user) : folder.GetChildren(user); } else { items = new[] { item }; } var ibnItemsArray = GetAllItems(request, items, user).ToArray(); IEnumerable>> ibnItems = ibnItemsArray; var result = new ItemsResult { TotalRecordCount = ibnItemsArray.Length }; if (request.StartIndex.HasValue || request.Limit.HasValue) { if (request.StartIndex.HasValue) { ibnItems = ibnItems.Skip(request.StartIndex.Value); } if (request.Limit.HasValue) { ibnItems = ibnItems.Take(request.Limit.Value); } } var fields = GetItemFields(request).ToList(); var tasks = ibnItems.Select(i => GetDto(i, user, fields)); var resultItems = await Task.WhenAll(tasks).ConfigureAwait(false); result.Items = resultItems.Where(i => i != null).ToArray(); return result; } /// /// Gets the item fields. /// /// The request. /// IEnumerable{ItemFields}. private IEnumerable GetItemFields(GetItemsByName request) { var val = request.Fields; if (string.IsNullOrEmpty(val)) { return new ItemFields[] { }; } return val.Split(',').Select(v => (ItemFields)Enum.Parse(typeof(ItemFields), v, true)); } /// /// Gets all items. /// /// The request. /// The items. /// The user. /// IEnumerable{Tuple{System.StringFunc{System.Int32}}}. protected abstract IEnumerable>> GetAllItems(GetItemsByName request, IEnumerable items, User user); /// /// Gets the entity. /// /// The name. /// Task{BaseItem}. protected abstract Task GetEntity(string name); /// /// Gets the dto. /// /// The stub. /// The user. /// The fields. /// Task{DtoBaseItem}. private async Task GetDto(Tuple> stub, User user, List fields) { BaseItem item; try { item = await GetEntity(stub.Item1).ConfigureAwait(false); } catch (IOException ex) { Logger.ErrorException("Error getting IBN item {0}", ex, stub.Item1); return null; } var dto = await new DtoBuilder(Logger).GetBaseItemDto(item, user, fields, LibraryManager).ConfigureAwait(false); dto.ChildCount = stub.Item2(); return dto; } } /// /// Class GetItemsByName /// public class GetItemsByName : IReturn { /// /// Gets or sets the user id. /// /// The user id. [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] public Guid UserId { get; set; } /// /// Gets or sets the start index. /// /// 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; } /// /// Gets or sets the size of the page. /// /// The size of the page. [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; } /// /// Gets or sets a value indicating whether this is recursive. /// /// true if recursive; otherwise, false. [ApiMember(Name = "Recursive", Description = "When searching within folders, this determines whether or not the search will be recursive. true/false", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] public bool Recursive { get; set; } /// /// Gets or sets the sort order. /// /// The sort order. [ApiMember(Name = "SortOrder", Description = "Sort Order - Ascending,Descending", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public SortOrder? SortOrder { get; set; } /// /// If specified the search will be localized within a specific item or folder /// /// The item id. [ApiMember(Name = "Id", Description = "If specified the search will be localized within a specific item or folder", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string Id { get; set; } /// /// Fields to return within the items, in addition to basic information /// /// The fields. public string Fields { get; set; } } }