refactoring the code.

This commit is contained in:
Ben
2024-06-04 17:32:31 +08:00
parent 9d85ca07f4
commit 7f970d489f
51 changed files with 806 additions and 700 deletions

View File

@ -1,23 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using HtmlAgilityPack;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Oqtane.Infrastructure;
using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Security;
using Oqtane.Shared;
namespace Oqtane.Services
{
public class SearchService : ISearchService
{
private const string SearchProviderSettingName = "SearchProvider";
private const string SearchEnabledSettingName = "SearchEnabled";
private readonly IServiceProvider _serviceProvider;
private readonly ITenantManager _tenantManager;
private readonly IAliasRepository _aliasRepository;
private readonly ISettingRepository _settingRepository;
private readonly IPermissionRepository _permissionRepository;
private readonly ILogger<SearchService> _logger;
private readonly IMemoryCache _cache;
@ -26,12 +33,14 @@ namespace Oqtane.Services
ITenantManager tenantManager,
IAliasRepository aliasRepository,
ISettingRepository settingRepository,
IPermissionRepository permissionRepository,
ILogger<SearchService> logger,
IMemoryCache cache)
{
_tenantManager = tenantManager;
_aliasRepository = aliasRepository;
_settingRepository = settingRepository;
_permissionRepository = permissionRepository;
_serviceProvider = serviceProvider;
_logger = logger;
_cache = cache;
@ -68,8 +77,8 @@ namespace Oqtane.Services
{
_logger.LogDebug($"Search: Begin Index {searchIndexManager.Name}");
var count = searchIndexManager.IndexDocuments(siteId, startTime, SaveIndexDocuments, handleError);
logNote($"Search: Indexer {searchIndexManager.Name} processed {count} documents.<br />");
var count = searchIndexManager.IndexContent(siteId, startTime, SaveSearchContent, handleError);
logNote($"Search: Indexer {searchIndexManager.Name} processed {count} search content.<br />");
_logger.LogDebug($"Search: End Index {searchIndexManager.Name}");
}
@ -79,7 +88,7 @@ namespace Oqtane.Services
public async Task<SearchResults> SearchAsync(SearchQuery searchQuery)
{
var searchProvider = GetSearchProvider(searchQuery.SiteId);
var searchResults = await searchProvider.SearchAsync(searchQuery, HasViewPermission);
var searchResults = await searchProvider.SearchAsync(searchQuery, Visible);
//generate the document url if it's not set.
foreach (var result in searchResults.Results)
@ -108,7 +117,7 @@ namespace Oqtane.Services
private string GetSearchProviderSetting(int siteId)
{
var setting = _settingRepository.GetSetting(EntityNames.Site, siteId, Constants.SearchProviderSettingName);
var setting = _settingRepository.GetSetting(EntityNames.Site, siteId, SearchProviderSettingName);
if(!string.IsNullOrEmpty(setting?.SettingValue))
{
return setting.SettingValue;
@ -119,7 +128,7 @@ namespace Oqtane.Services
private bool SearchEnabled(int siteId)
{
var setting = _settingRepository.GetSetting(EntityNames.Site, siteId, Constants.SearchEnabledSettingName);
var setting = _settingRepository.GetSetting(EntityNames.Site, siteId, SearchEnabledSettingName);
if (!string.IsNullOrEmpty(setting?.SettingValue))
{
return bool.TryParse(setting.SettingValue, out bool enabled) && enabled;
@ -167,21 +176,22 @@ namespace Oqtane.Services
return managers.ToList();
}
private void SaveIndexDocuments(IList<SearchDocument> searchDocuments)
private void SaveSearchContent(IList<SearchContent> searchContentList)
{
if(searchDocuments.Any())
if(searchContentList.Any())
{
var searchProvider = GetSearchProvider(searchDocuments.First().SiteId);
var searchProvider = GetSearchProvider(searchContentList.First().SiteId);
foreach (var searchDocument in searchDocuments)
foreach (var searchContent in searchContentList)
{
try
{
searchProvider.SaveDocument(searchDocument);
CleanSearchContent(searchContent);
searchProvider.SaveSearchContent(searchContent);
}
catch(Exception ex)
{
_logger.LogError(ex, $"Search: Save search document {searchDocument.UniqueKey} failed.");
_logger.LogError(ex, $"Search: Save search content {searchContent.UniqueKey} failed.");
}
}
@ -190,19 +200,30 @@ namespace Oqtane.Services
}
}
private bool HasViewPermission(SearchDocument searchDocument, SearchQuery searchQuery)
private bool Visible(SearchContent searchContent, SearchQuery searchQuery)
{
var searchResultManager = GetSearchResultManagers().FirstOrDefault(i => i.Name == searchDocument.IndexerName);
if(!HasViewPermission(searchQuery.SiteId, searchQuery.User, searchContent.EntityName, searchContent.EntityId))
{
return false;
}
var searchResultManager = GetSearchResultManagers().FirstOrDefault(i => i.Name == searchContent.EntityName);
if (searchResultManager != null)
{
return searchResultManager.Visible(searchDocument, searchQuery);
return searchResultManager.Visible(searchContent, searchQuery);
}
return true;
}
private bool HasViewPermission(int siteId, User user, string entityName, int entityId)
{
var permissions = _permissionRepository.GetPermissions(siteId, entityName, entityId).ToList();
return UserSecurity.IsAuthorized(user, PermissionNames.View, permissions);
}
private string GetDocumentUrl(SearchResult result, SearchQuery searchQuery)
{
var searchResultManager = GetSearchResultManagers().FirstOrDefault(i => i.Name == result.IndexerName);
var searchResultManager = GetSearchResultManagers().FirstOrDefault(i => i.Name == result.EntityName);
if(searchResultManager != null)
{
return searchResultManager.GetUrl(result, searchQuery);
@ -210,5 +231,35 @@ namespace Oqtane.Services
return string.Empty;
}
private void CleanSearchContent(SearchContent searchContent)
{
searchContent.Title = GetCleanContent(searchContent.Title);
searchContent.Description = GetCleanContent(searchContent.Description);
searchContent.Body = GetCleanContent(searchContent.Body);
searchContent.AdditionalContent = GetCleanContent(searchContent.AdditionalContent);
}
private string GetCleanContent(string content)
{
if(string.IsNullOrWhiteSpace(content))
{
return string.Empty;
}
content = WebUtility.HtmlDecode(content);
var page = new HtmlDocument();
page.LoadHtml(content);
var phrases = page.DocumentNode.Descendants().Where(i =>
i.NodeType == HtmlNodeType.Text &&
i.ParentNode.Name != "script" &&
i.ParentNode.Name != "style" &&
!string.IsNullOrEmpty(i.InnerText.Trim())
).Select(i => i.InnerText);
return string.Join(" ", phrases);
}
}
}