diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 32c1bfaf5..5f846a417 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -86,6 +86,7 @@ + diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs new file mode 100644 index 000000000..a3d228529 --- /dev/null +++ b/MediaBrowser.Api/SearchService.cs @@ -0,0 +1,192 @@ +using System.Collections; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Search; +using ServiceStack.ServiceHost; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Linq; + +namespace MediaBrowser.Api +{ + /// + /// Class GetSearchHints + /// + [Route("/Search/Hints", "GET")] + [Api(Description = "Gets search hints based on a search term")] + public class GetSearchHints : IReturn> + { + /// + /// 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; } + + /// + /// Gets or sets the user id. + /// + /// The user id. + [ApiMember(Name = "UserId", Description = "Optional. Supply a user id to search within a user's library or omit to search all.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + public Guid? UserId { get; set; } + + /// + /// Search characters used to find items + /// + /// The index by. + [ApiMember(Name = "SearchTerm", Description = "The search term to filter on", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] + public string SearchTerm { get; set; } + } + + /// + /// Class SearchService + /// + public class SearchService : BaseApiService + { + /// + /// The _user manager + /// + private readonly IUserManager _userManager; + /// + /// The _search engine + /// + private readonly ILibrarySearchEngine _searchEngine; + private readonly ILibraryManager _libraryManager; + + /// + /// Initializes a new instance of the class. + /// + /// The user manager. + /// The search engine. + /// The library manager. + public SearchService(IUserManager userManager, ILibrarySearchEngine searchEngine, ILibraryManager libraryManager) + { + _userManager = userManager; + _searchEngine = searchEngine; + _libraryManager = libraryManager; + } + + /// + /// Gets the specified request. + /// + /// The request. + /// System.Object. + public object Get(GetSearchHints request) + { + var result = GetSearchHintsAsync(request).Result; + + return ToOptimizedResult(result); + } + + /// + /// Gets the search hints async. + /// + /// The request. + /// Task{IEnumerable{SearchHintResult}}. + private async Task> GetSearchHintsAsync(GetSearchHints request) + { + IEnumerable inputItems; + + if (request.UserId.HasValue) + { + var user = _userManager.GetUserById(request.UserId.Value); + + inputItems = user.RootFolder.GetRecursiveChildren(user); + } + else + { + inputItems = _libraryManager.RootFolder.RecursiveChildren; + } + + var results = await _searchEngine.GetSearchHints(inputItems, request.SearchTerm).ConfigureAwait(false); + + if (request.StartIndex.HasValue) + { + results = results.Skip(request.StartIndex.Value); + } + + if (request.Limit.HasValue) + { + results = results.Take(request.Limit.Value); + } + + return results.Select(GetSearchHintResult); + } + + /// + /// Gets the search hint result. + /// + /// The item. + /// SearchHintResult. + private SearchHintResult GetSearchHintResult(BaseItem item) + { + var result = new SearchHintResult + { + Name = item.Name, + IndexNumber = item.IndexNumber, + ParentIndexNumber = item.ParentIndexNumber, + ItemId = DtoBuilder.GetClientItemId(item), + Type = item.GetType().Name, + MediaType = item.MediaType + }; + + if (item.HasImage(ImageType.Primary)) + { + result.PrimaryImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(item, ImageType.Primary, item.GetImage(ImageType.Primary)); + } + + var episode = item as Episode; + + if (episode != null) + { + result.Series = episode.Series.Name; + } + + var season = item as Season; + + if (season != null) + { + result.Series = season.Series.Name; + } + + var album = item as MusicAlbum; + + if (album != null) + { + var songs = album.Children.OfType