SearchEngine.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #nullable disable
  2. #pragma warning disable CS1591
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using Jellyfin.Data.Entities;
  7. using Jellyfin.Data.Enums;
  8. using Jellyfin.Extensions;
  9. using MediaBrowser.Controller.Dto;
  10. using MediaBrowser.Controller.Entities;
  11. using MediaBrowser.Controller.Library;
  12. using MediaBrowser.Model.Querying;
  13. using MediaBrowser.Model.Search;
  14. namespace Emby.Server.Implementations.Library
  15. {
  16. public class SearchEngine : ISearchEngine
  17. {
  18. private readonly ILibraryManager _libraryManager;
  19. private readonly IUserManager _userManager;
  20. public SearchEngine(ILibraryManager libraryManager, IUserManager userManager)
  21. {
  22. _libraryManager = libraryManager;
  23. _userManager = userManager;
  24. }
  25. public QueryResult<SearchHintInfo> GetSearchHints(SearchQuery query)
  26. {
  27. User user = null;
  28. if (!query.UserId.Equals(default))
  29. {
  30. user = _userManager.GetUserById(query.UserId);
  31. }
  32. var results = GetSearchHints(query, user);
  33. var totalRecordCount = results.Count;
  34. if (query.StartIndex.HasValue)
  35. {
  36. results = results.GetRange(query.StartIndex.Value, totalRecordCount - query.StartIndex.Value);
  37. }
  38. if (query.Limit.HasValue)
  39. {
  40. results = results.GetRange(0, Math.Min(query.Limit.Value, results.Count));
  41. }
  42. return new QueryResult<SearchHintInfo>(
  43. query.StartIndex,
  44. totalRecordCount,
  45. results);
  46. }
  47. private static void AddIfMissing(List<BaseItemKind> list, BaseItemKind value)
  48. {
  49. if (!list.Contains(value))
  50. {
  51. list.Add(value);
  52. }
  53. }
  54. /// <summary>
  55. /// Gets the search hints.
  56. /// </summary>
  57. /// <param name="query">The query.</param>
  58. /// <param name="user">The user.</param>
  59. /// <returns>IEnumerable{SearchHintResult}.</returns>
  60. /// <exception cref="ArgumentException"><c>query.SearchTerm</c> is <c>null</c> or empty.</exception>
  61. private List<SearchHintInfo> GetSearchHints(SearchQuery query, User user)
  62. {
  63. var searchTerm = query.SearchTerm;
  64. ArgumentException.ThrowIfNullOrEmpty(searchTerm);
  65. searchTerm = searchTerm.Trim().RemoveDiacritics();
  66. var excludeItemTypes = query.ExcludeItemTypes.ToList();
  67. var includeItemTypes = (query.IncludeItemTypes ?? Array.Empty<BaseItemKind>()).ToList();
  68. excludeItemTypes.Add(BaseItemKind.Year);
  69. excludeItemTypes.Add(BaseItemKind.Folder);
  70. if (query.IncludeGenres && (includeItemTypes.Count == 0 || includeItemTypes.Contains(BaseItemKind.Genre)))
  71. {
  72. if (!query.IncludeMedia)
  73. {
  74. AddIfMissing(includeItemTypes, BaseItemKind.Genre);
  75. AddIfMissing(includeItemTypes, BaseItemKind.MusicGenre);
  76. }
  77. }
  78. else
  79. {
  80. AddIfMissing(excludeItemTypes, BaseItemKind.Genre);
  81. AddIfMissing(excludeItemTypes, BaseItemKind.MusicGenre);
  82. }
  83. if (query.IncludePeople && (includeItemTypes.Count == 0 || includeItemTypes.Contains(BaseItemKind.Person)))
  84. {
  85. if (!query.IncludeMedia)
  86. {
  87. AddIfMissing(includeItemTypes, BaseItemKind.Person);
  88. }
  89. }
  90. else
  91. {
  92. AddIfMissing(excludeItemTypes, BaseItemKind.Person);
  93. }
  94. if (query.IncludeStudios && (includeItemTypes.Count == 0 || includeItemTypes.Contains(BaseItemKind.Studio)))
  95. {
  96. if (!query.IncludeMedia)
  97. {
  98. AddIfMissing(includeItemTypes, BaseItemKind.Studio);
  99. }
  100. }
  101. else
  102. {
  103. AddIfMissing(excludeItemTypes, BaseItemKind.Studio);
  104. }
  105. if (query.IncludeArtists && (includeItemTypes.Count == 0 || includeItemTypes.Contains(BaseItemKind.MusicArtist)))
  106. {
  107. if (!query.IncludeMedia)
  108. {
  109. AddIfMissing(includeItemTypes, BaseItemKind.MusicArtist);
  110. }
  111. }
  112. else
  113. {
  114. AddIfMissing(excludeItemTypes, BaseItemKind.MusicArtist);
  115. }
  116. AddIfMissing(excludeItemTypes, BaseItemKind.CollectionFolder);
  117. AddIfMissing(excludeItemTypes, BaseItemKind.Folder);
  118. var mediaTypes = query.MediaTypes.ToList();
  119. if (includeItemTypes.Count > 0)
  120. {
  121. excludeItemTypes.Clear();
  122. mediaTypes.Clear();
  123. }
  124. var searchQuery = new InternalItemsQuery(user)
  125. {
  126. SearchTerm = searchTerm,
  127. ExcludeItemTypes = excludeItemTypes.ToArray(),
  128. IncludeItemTypes = includeItemTypes.ToArray(),
  129. Limit = query.Limit,
  130. IncludeItemsByName = !query.ParentId.HasValue,
  131. ParentId = query.ParentId ?? Guid.Empty,
  132. OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) },
  133. Recursive = true,
  134. IsKids = query.IsKids,
  135. IsMovie = query.IsMovie,
  136. IsNews = query.IsNews,
  137. IsSeries = query.IsSeries,
  138. IsSports = query.IsSports,
  139. MediaTypes = mediaTypes.ToArray(),
  140. DtoOptions = new DtoOptions
  141. {
  142. Fields = new ItemFields[]
  143. {
  144. ItemFields.AirTime,
  145. ItemFields.DateCreated,
  146. ItemFields.ChannelInfo,
  147. ItemFields.ParentId
  148. }
  149. }
  150. };
  151. List<BaseItem> mediaItems;
  152. if (searchQuery.IncludeItemTypes.Length == 1 && searchQuery.IncludeItemTypes[0] == BaseItemKind.MusicArtist)
  153. {
  154. if (!searchQuery.ParentId.Equals(default))
  155. {
  156. searchQuery.AncestorIds = new[] { searchQuery.ParentId };
  157. searchQuery.ParentId = Guid.Empty;
  158. }
  159. searchQuery.IncludeItemsByName = true;
  160. searchQuery.IncludeItemTypes = Array.Empty<BaseItemKind>();
  161. mediaItems = _libraryManager.GetAllArtists(searchQuery).Items.Select(i => i.Item).ToList();
  162. }
  163. else
  164. {
  165. mediaItems = _libraryManager.GetItemList(searchQuery);
  166. }
  167. return mediaItems.Select(i => new SearchHintInfo
  168. {
  169. Item = i
  170. }).ToList();
  171. }
  172. }
  173. }