diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/Library/SearchEngine.cs')
| -rw-r--r-- | MediaBrowser.Server.Implementations/Library/SearchEngine.cs | 266 |
1 files changed, 85 insertions, 181 deletions
diff --git a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs index 05dde5b3e..d4ff89b4f 100644 --- a/MediaBrowser.Server.Implementations/Library/SearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/SearchEngine.cs @@ -33,30 +33,17 @@ namespace MediaBrowser.Server.Implementations.Library public async Task<QueryResult<SearchHintInfo>> GetSearchHints(SearchQuery query) { - IEnumerable<BaseItem> inputItems; - - Func<BaseItem, bool> filter = i => !(i is ICollectionFolder); + User user = null; if (string.IsNullOrWhiteSpace(query.UserId)) { - inputItems = _libraryManager.RootFolder.GetRecursiveChildren(filter); } else { - var user = _userManager.GetUserById(query.UserId); - - inputItems = user.RootFolder.GetRecursiveChildren(user, filter); + user = _userManager.GetUserById(query.UserId); } - inputItems = _libraryManager.ReplaceVideosWithPrimaryVersions(inputItems); - - var results = await GetSearchHints(inputItems, query).ConfigureAwait(false); - - // Include item types - if (query.IncludeItemTypes.Length > 0) - { - results = results.Where(f => query.IncludeItemTypes.Contains(f.Item.GetType().Name, StringComparer.OrdinalIgnoreCase)); - } + var results = await GetSearchHints(query, user).ConfigureAwait(false); var searchResultArray = results.ToArray(); results = searchResultArray; @@ -81,14 +68,22 @@ namespace MediaBrowser.Server.Implementations.Library }; } + private void AddIfMissing(List<string> list, string value) + { + if (!list.Contains(value, StringComparer.OrdinalIgnoreCase)) + { + list.Add(value); + } + } + /// <summary> /// Gets the search hints. /// </summary> - /// <param name="inputItems">The input items.</param> /// <param name="query">The query.</param> + /// <param name="user">The user.</param> /// <returns>IEnumerable{SearchHintResult}.</returns> /// <exception cref="System.ArgumentNullException">searchTerm</exception> - private Task<IEnumerable<SearchHintInfo>> GetSearchHints(IEnumerable<BaseItem> inputItems, SearchQuery query) + private Task<IEnumerable<SearchHintInfo>> GetSearchHints(SearchQuery query, User user) { var searchTerm = query.SearchTerm; @@ -98,195 +93,85 @@ namespace MediaBrowser.Server.Implementations.Library } searchTerm = searchTerm.RemoveDiacritics(); - + var terms = GetWords(searchTerm); var hints = new List<Tuple<BaseItem, string, int>>(); - var items = inputItems.Where(i => !(i is MusicArtist)).ToList(); + var excludeItemTypes = new List<string>(); + var includeItemTypes = (query.IncludeItemTypes ?? new string[] { }).ToList(); - if (query.IncludeMedia) - { - // Add search hints based on item name - hints.AddRange(items.Where(i => !string.IsNullOrWhiteSpace(i.Name) && IncludeInSearch(i)).Select(item => - { - var index = GetIndex(item.Name, searchTerm, terms); + excludeItemTypes.Add(typeof(Year).Name); - return new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2); - })); - } - - if (query.IncludeArtists) + if (query.IncludeGenres && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Genre", StringComparer.OrdinalIgnoreCase))) { - // Find artists - var artists = items.OfType<Audio>() - .SelectMany(i => i.AllArtists) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .DistinctNames() - .ToList(); - - foreach (var item in artists) + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var artist = _libraryManager.GetArtist(item); - - hints.Add(new Tuple<BaseItem, string, int>(artist, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(Genre).Name); + AddIfMissing(includeItemTypes, typeof(GameGenre).Name); + AddIfMissing(includeItemTypes, typeof(MusicGenre).Name); } } - - if (query.IncludeGenres) + else { - // Find genres, from non-audio items - var genres = items.Where(i => !(i is IHasMusicGenres) && !(i is Game)) - .SelectMany(i => i.Genres) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - foreach (var item in genres) - { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var genre = _libraryManager.GetGenre(item); - - hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } - } - - // Find music genres - var musicGenres = items.Where(i => i is IHasMusicGenres) - .SelectMany(i => i.Genres) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); + AddIfMissing(excludeItemTypes, typeof(Genre).Name); + AddIfMissing(excludeItemTypes, typeof(GameGenre).Name); + AddIfMissing(excludeItemTypes, typeof(MusicGenre).Name); + } - foreach (var item in musicGenres) + if (query.IncludePeople && (includeItemTypes.Count == 0 || includeItemTypes.Contains("People", StringComparer.OrdinalIgnoreCase))) + { + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var genre = _libraryManager.GetMusicGenre(item); - - hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(Person).Name); } + } + else + { + AddIfMissing(excludeItemTypes, typeof(Person).Name); + } - // Find music genres - var gameGenres = items.OfType<Game>() - .SelectMany(i => i.Genres) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - foreach (var item in gameGenres) + if (query.IncludeStudios && (includeItemTypes.Count == 0 || includeItemTypes.Contains("Studio", StringComparer.OrdinalIgnoreCase))) + { + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var genre = _libraryManager.GetGameGenre(item); - - hints.Add(new Tuple<BaseItem, string, int>(genre, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(Studio).Name); } } - - if (query.IncludeStudios) + else { - // Find studios - var studios = items.SelectMany(i => i.Studios) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); + AddIfMissing(excludeItemTypes, typeof(Studio).Name); + } - foreach (var item in studios) + if (query.IncludeArtists && (includeItemTypes.Count == 0 || includeItemTypes.Contains("MusicArtist", StringComparer.OrdinalIgnoreCase))) + { + if (!query.IncludeMedia) { - var index = GetIndex(item, searchTerm, terms); - - if (index.Item2 != -1) - { - try - { - var studio = _libraryManager.GetStudio(item); - - hints.Add(new Tuple<BaseItem, string, int>(studio, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } + AddIfMissing(includeItemTypes, typeof(MusicArtist).Name); } } + else + { + AddIfMissing(excludeItemTypes, typeof(MusicArtist).Name); + } - if (query.IncludePeople) + var mediaItems = _libraryManager.GetItems(new InternalItemsQuery { - var itemIds = items.Select(i => i.Id).ToList(); + NameContains = searchTerm, + ExcludeItemTypes = excludeItemTypes.ToArray(), + IncludeItemTypes = includeItemTypes.ToArray(), + MaxParentalRating = user == null ? null : user.Policy.MaxParentalRating, + Limit = query.Limit.HasValue ? query.Limit * 3 : null - // Find persons - var persons = _libraryManager.GetPeople(new InternalPeopleQuery - { - NameContains = searchTerm - }) - .Where(i => itemIds.Contains(i.ItemId)) - .Select(i => i.Name) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList(); - - foreach (var item in persons) - { - var index = GetIndex(item, searchTerm, terms); + }).Items; - if (index.Item2 != -1) - { - try - { - var person = _libraryManager.GetPerson(item); - - hints.Add(new Tuple<BaseItem, string, int>(person, index.Item1, index.Item2)); - } - catch (Exception ex) - { - _logger.ErrorException("Error getting {0}", ex, item); - } - } - } - } + // Add search hints based on item name + hints.AddRange(mediaItems.Where(i => IncludeInSearch(i) && IsVisible(i, user) && !(i is CollectionFolder)).Select(item => + { + var index = GetIndex(item.Name, searchTerm, terms); + + return new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2); + })); var returnValue = hints.Where(i => i.Item3 >= 0).OrderBy(i => i.Item3).Select(i => new SearchHintInfo { @@ -297,13 +182,32 @@ namespace MediaBrowser.Server.Implementations.Library return Task.FromResult(returnValue); } + private bool IsVisible(BaseItem item, User user) + { + if (user == null) + { + return true; + } + + if (item is IItemByName) + { + var dual = item as IHasDualAccess; + if (dual == null || dual.IsAccessedByName) + { + return true; + } + } + + return item.IsVisibleStandalone(user); + } + private bool IncludeInSearch(BaseItem item) { var episode = item as Episode; if (episode != null) { - if (episode.IsVirtualUnaired || episode.IsMissingEpisode) + if (episode.IsMissingEpisode) { return false; } |
