Implemented groundwork for search configuration.
This commit is contained in:
14
Props/Services/Modules/IShopManager.cs
Normal file
14
Props/Services/Modules/IShopManager.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Props.Models.Search;
|
||||
using Props.Shop.Framework;
|
||||
|
||||
namespace Props.Services.Modules
|
||||
{
|
||||
public interface IShopManager
|
||||
{
|
||||
public IEnumerable<string> AvailableShops();
|
||||
public Task<IList<ProductListing>> Search(string query, SearchOutline searchOutline);
|
||||
}
|
||||
}
|
107
Props/Services/Modules/LocalShopManager.cs
Normal file
107
Props/Services/Modules/LocalShopManager.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Props.Models.Search;
|
||||
using Props.Options;
|
||||
using Props.Shop.Framework;
|
||||
|
||||
namespace Props.Services.Modules
|
||||
{
|
||||
public class LocalShopManager : IShopManager
|
||||
{
|
||||
private ILogger<LocalShopManager> logger;
|
||||
private Dictionary<string, IShop> shops;
|
||||
private ModulesOptions options;
|
||||
private IConfiguration configuration;
|
||||
public LocalShopManager(IConfiguration configuration, ILogger<LocalShopManager> logger)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.logger = logger;
|
||||
options = configuration.GetSection(ModulesOptions.Modules).Get<ModulesOptions>();
|
||||
|
||||
shops = new Dictionary<string, IShop>();
|
||||
foreach (IShop shop in LoadShops(options.ShopsDir, options.ShopRegex, options.RecursiveLoad))
|
||||
{
|
||||
if (!shops.TryAdd(shop.ShopName, shop))
|
||||
{
|
||||
logger.LogWarning("Duplicate shop {0} detected. Ignoring the latter.", shop.ShopName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> AvailableShops()
|
||||
{
|
||||
return shops.Keys;
|
||||
}
|
||||
|
||||
public async Task<IList<ProductListing>> Search(string query, SearchOutline searchOutline)
|
||||
{
|
||||
List<ProductListing> results = new List<ProductListing>();
|
||||
foreach (string shopName in shops.Keys)
|
||||
{
|
||||
if (!searchOutline.Disabled[shopName])
|
||||
{
|
||||
int amount = 0;
|
||||
await foreach (ProductListing product in shops[shopName].Search(query, searchOutline.Filters))
|
||||
{
|
||||
if (searchOutline.Filters.Validate(product))
|
||||
{
|
||||
amount += 1;
|
||||
results.Add(product);
|
||||
}
|
||||
if (amount >= options.MaxResults) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private IEnumerable<IShop> LoadShops(string shopsDir, string shopRegex, bool recursiveLoad)
|
||||
{
|
||||
Stack<string> directories = new Stack<string>();
|
||||
directories.Push(shopsDir);
|
||||
string currentDirectory = null;
|
||||
while (directories.TryPop(out currentDirectory))
|
||||
{
|
||||
if (recursiveLoad)
|
||||
{
|
||||
foreach (string dir in Directory.EnumerateDirectories(currentDirectory))
|
||||
{
|
||||
directories.Push(dir);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string file in Directory.EnumerateFiles(currentDirectory))
|
||||
{
|
||||
if (Path.GetExtension(file).Equals(".dll") && Regex.IsMatch(file, shopRegex))
|
||||
{
|
||||
ShopAssemblyLoadContext context = new ShopAssemblyLoadContext(file);
|
||||
Assembly assembly = context.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(file)));
|
||||
int success = 0;
|
||||
foreach (Type type in assembly.GetTypes())
|
||||
{
|
||||
if (typeof(IShop).IsAssignableFrom(type))
|
||||
{
|
||||
IShop shop = Activator.CreateInstance(type) as IShop;
|
||||
if (shop != null)
|
||||
{
|
||||
success += 1;
|
||||
yield return shop;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success == 0)
|
||||
{
|
||||
logger.LogWarning("There were no shops found within the assembly at path \"{0}\".", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using Props.Shop.Framework;
|
||||
|
||||
namespace Props.Services.Modules
|
||||
{
|
||||
@@ -16,6 +17,7 @@ namespace Props.Services.Modules
|
||||
|
||||
protected override Assembly Load(AssemblyName assemblyName)
|
||||
{
|
||||
if (assemblyName.FullName.Equals(typeof(IShop).Assembly.FullName)) return null;
|
||||
string assemblyPath = resolver.ResolveAssemblyToPath(assemblyName);
|
||||
return assemblyPath != null ? LoadFromAssemblyPath(assemblyPath) : null;
|
||||
}
|
||||
|
Reference in New Issue
Block a user