using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Dto; 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.UserLibrary { /// /// Class BaseItemsByNameService /// /// The type of the T item type. public abstract class BaseItemsByNameService : BaseApiService where TItemType : BaseItem { /// /// The _user manager /// protected readonly IUserManager UserManager; /// /// The library manager /// protected readonly ILibraryManager LibraryManager; protected readonly IUserDataRepository UserDataRepository; /// /// Initializes a new instance of the class. /// /// The user manager. /// The library manager. /// The user data repository. protected BaseItemsByNameService(IUserManager userManager, ILibraryManager libraryManager, IUserDataRepository userDataRepository) { UserManager = userManager; LibraryManager = libraryManager; UserDataRepository = userDataRepository; } /// /// 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.ParentId) ? user.RootFolder : DtoBuilder.GetItemByClientId(request.ParentId, 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 }; } items = FilterItems(request, items, user); var extractedItems = GetAllItems(request, items, user); var ibnItemsArray = SortItems(request, extractedItems).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 = request.GetItemFields().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; } /// /// Sorts the items. /// /// The request. /// The items. /// IEnumerable{BaseItem}. private IEnumerable>>> SortItems(GetItemsByName request, IEnumerable>>> items) { if (string.Equals(request.SortBy, "SortName", StringComparison.OrdinalIgnoreCase)) { if (request.SortOrder.HasValue && request.SortOrder.Value == Model.Entities.SortOrder.Descending) { items = items.OrderByDescending(i => i.Item1); } else { items = items.OrderBy(i => i.Item1); } } return items; } /// /// Filters the items. /// /// The request. /// The items. /// The user. /// IEnumerable{BaseItem}. private IEnumerable FilterItems(GetItemsByName request, IEnumerable items, User user) { // Exclude item types if (!string.IsNullOrEmpty(request.ExcludeItemTypes)) { var vals = request.ExcludeItemTypes.Split(','); items = items.Where(f => !vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)); } // Include item types if (!string.IsNullOrEmpty(request.IncludeItemTypes)) { var vals = request.IncludeItemTypes.Split(','); items = items.Where(f => vals.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase)); } return items; } /// /// 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, LibraryManager, UserDataRepository).GetBaseItemDto(item, user, fields).ConfigureAwait(false); if (fields.Contains(ItemFields.ItemCounts)) { var items = stub.Item2().ToList(); dto.ChildCount = items.Count; dto.RecentlyAddedItemCount = items.Count(i => i.IsRecentlyAdded(user)); } return dto; } /// /// Marks the favorite. /// /// The get item. /// The user id. /// if set to true [is favorite]. /// Task. protected async Task MarkFavorite(Func> getItem, Guid userId, bool isFavorite) { var user = UserManager.GetUserById(userId); var item = await getItem().ConfigureAwait(false); var key = item.GetUserDataKey(); // Get the user data for this item var data = await UserDataRepository.GetUserData(user.Id, key).ConfigureAwait(false); // Set favorite status data.IsFavorite = isFavorite; await UserDataRepository.SaveUserData(user.Id, key, data, CancellationToken.None).ConfigureAwait(false); } } /// /// Class GetItemsByName /// public class GetItemsByName : BaseItemsRequest, IReturn { /// /// What to sort the results by /// /// The sort by. [ApiMember(Name = "SortBy", Description = "Optional. Options: SortName", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string SortBy { get; set; } } }