aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations/Library/SearchEngine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Server.Implementations/Library/SearchEngine.cs')
-rw-r--r--MediaBrowser.Server.Implementations/Library/SearchEngine.cs266
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;
}