Skip to content

Commit 5f0f1be

Browse files
committed
Work on #64, #63, #62 ...
1 parent 628681c commit 5f0f1be

File tree

5 files changed

+140
-159
lines changed

5 files changed

+140
-159
lines changed

SmartImage.Lib/SearchClient.cs

Lines changed: 74 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ namespace SmartImage.Lib;
4242
public sealed class SearchClient : IDisposable
4343
{
4444

45+
public SearchQuery Query { get; set; }
46+
4547
public SearchConfig Config { get; init; }
4648

4749
public bool IsComplete { get; private set; }
@@ -54,16 +56,31 @@ public sealed class SearchClient : IDisposable
5456

5557
private static readonly ILogger s_logger = AppSupport.Factory.CreateLogger(nameof(SearchClient));
5658

57-
public SearchClient(SearchConfig cfg)
59+
private static readonly Lock m_lock = new Lock();
60+
61+
public SearchClient(SearchConfig cfg, SearchQuery query)
5862
{
63+
Query = query;
5964
Config = cfg;
6065
ConfigApplied = false;
6166
IsRunning = false;
6267

68+
Config.PropertyChanged += (sender, args) =>
69+
{
70+
if (args.PropertyName == nameof(SearchConfig.SearchEngines)) {
71+
lock (m_lock) {
72+
Engines = BaseSearchEngine.GetSelectedEngines(Config.SearchEngines).ToArray();
73+
74+
}
75+
}
76+
};
77+
6378
// GetSelectedEngines();
6479

6580
}
6681

82+
public SearchClient(SearchConfig cfg) : this(cfg, SearchQuery.Null) { }
83+
6784
static SearchClient() { }
6885

6986
[ModuleInitializer]
@@ -106,141 +123,43 @@ public void OpenChannel()
106123
// ...
107124
}
108125

109-
ResultChannel = Channel.CreateUnbounded<SearchResult>(new UnboundedChannelOptions()
126+
ResultChannel = Channel.CreateBounded<SearchResult>(new BoundedChannelOptions(Engines.Length)
110127
{
111128
SingleWriter = true,
112-
113129
});
114130
}
115131

116-
#if OLD
117-
/// <summary>
118-
/// Runs a search of <paramref name="query"/>.
119-
/// </summary>
120-
/// <param name="query">Search query</param>
121-
/// <param name="scheduler"></param>
122-
/// <param name="token">Cancellation token passed to <see cref="WebSearchEngine{T}.GetResultAsync(SmartImage.Lib.SearchQuery,System.Threading.CancellationToken)"/></param>
123-
public async Task<SearchResult[]> RunSearchAsync1(SearchQuery query,
124-
TaskScheduler scheduler = default,
125-
CancellationToken token = default)
126-
{
127-
scheduler ??= TaskScheduler.Default;
128-
129-
// Requires.NotNull(ResultChannel);
130-
if (ResultChannel == null || (IsComplete && !IsRunning)) {
131-
OpenChannel();
132-
}
133-
134-
if (!query.IsUploaded) {
135-
throw new ArgumentException($"Query was not uploaded", nameof(query));
136-
}
137-
138-
IsRunning = true;
139-
140-
if (!ConfigApplied) {
141-
await LoadEnginesAsync(token); // todo
142-
143-
}
144-
else {
145-
Debug.WriteLine("Not reloading engines");
146-
}
147-
148-
Debug.WriteLine($"Config: {Config} | {Engines.QuickJoin()}");
149-
150-
var tasks = GetSearchTasks(query, scheduler, token);
151-
152-
// var results = new SearchResult[tasks.Count];
153-
int i = 0;
154-
155-
/*while (tasks.Count > 0) {
156-
if (token.IsCancellationRequested) {
157-
158-
Debugger.Break();
159-
s_logger.LogWarning("Cancellation requested");
160-
CompleteSearchAsync();
161-
return results;
162-
}
163-
164-
Task<SearchResult> task = await Task.WhenAny(tasks);
165-
tasks.Remove(task);
166-
167-
if (task.IsFaulted) {
168-
Trace.WriteLine($"{task} faulted!",LogCategories.C_ERROR);
169-
}
170-
SearchResult result = await task;
171-
172-
results[i] = result;
173-
i++;
174-
}*/
175-
176-
177-
await foreach (var task in Task.WhenEach(tasks).WithCancellation(token)) {
178-
if (token.IsCancellationRequested) {
179-
180-
Debugger.Break();
181-
s_logger.LogWarning("Cancellation requested");
182-
CompleteSearchAsync();
183-
}
184-
185-
var result = await task;
186-
ProcessResult(result);
187-
}
188-
189-
CompleteSearchAsync();
190-
OnSearchComplete?.Invoke(this, results);
191-
192-
if (Config.PriorityEngines == SearchEngineOptions.Auto) {
193-
194-
try {
195-
196-
SearchResultItem item = GetBest(results);
197-
198-
if (item != null) {
199-
OpenResult(item.Url);
200-
}
201-
}
202-
catch (Exception e) {
203-
Debug.WriteLine($"{e.Message}");
204-
205-
Debugger.Break();
206-
}
207-
208-
}
209-
210-
IsRunning = false;
211-
212-
return results;
213-
}
214-
#endif
215-
216-
public async IAsyncEnumerable<SearchResult> RunSearchAsync(SearchQuery query,
217-
TaskScheduler scheduler = default,
132+
public async IAsyncEnumerable<SearchResult> RunSearchAsync(TaskScheduler scheduler = default,
218133
[EC] CancellationToken token = default)
219134
{
220-
await RunSearchAsync2(query, ResultChannel.Writer, token);
135+
await RunSearchAsync2(token);
221136

222-
await foreach (var result in ResultChannel.Reader.ReadAllAsync(token)) {
223-
yield return result;
137+
while (await ResultChannel.Reader.WaitToReadAsync(token)) {
138+
while (ResultChannel.Reader.TryRead(out var result)) {
139+
yield return result;
140+
}
224141
}
225142
}
226143

144+
public ValueTask<bool> RunSearchAsync2(CancellationToken token = default)
145+
=> RunSearchAsync2(ResultChannel.Writer, token);
227146

228-
/// <summary>
229-
/// Runs a search of <paramref name="query"/>.
230-
/// </summary>
231-
public async ValueTask<bool> RunSearchAsync2(SearchQuery query,
232-
ChannelWriter<SearchResult> cw,
147+
public async ValueTask<bool> RunSearchAsync2(ChannelWriter<SearchResult> cw,
233148
CancellationToken token = default)
234149
{
235-
if (!query.IsUploaded) {
236-
throw new SmartImageException($"{query} was not uploaded");
150+
if (!Query.IsUploaded) {
151+
throw new SmartImageException($"{Query} was not uploaded");
237152
}
238153

239-
var tasks = Engines.Select(e =>
240-
{
241-
var task = e.GetResultAsync(query, token);
242-
return task;
243-
});
154+
IEnumerable<Task<SearchResult>> tasks;
155+
156+
lock (m_lock) {
157+
tasks = Engines.Select(e =>
158+
{
159+
var task = e.GetResultAsync(Query, token);
160+
return task;
161+
});
162+
}
244163

245164
await foreach (var task in Task.WhenEach(tasks).WithCancellation(token)) {
246165

@@ -369,40 +288,16 @@ public async ValueTask LoadEnginesAsync(CancellationToken token = default)
369288

370289
Trace.WriteLine("Loading engines");
371290

372-
Engines = BaseSearchEngine.GetSelectedEngines(Config.SearchEngines).ToArray();
373291

374292
if (Config.ReadCookies) {
375293

376-
try {
377-
await ((DefaultCookiesProvider) DefaultCookiesProvider.Instance).OpenAsync();
378-
}
379-
catch (Exception e) {
380-
Trace.WriteLine($"{e}");
381-
Config.ReadCookies = false;
382-
DefaultCookiesProvider.Instance.Dispose();
383-
}
294+
await InitCookiesProvider();
384295
}
385296

386297
if (Config.FlareSolverr && !FlareSolverrClient.Value.IsInitialized) {
387298

388299

389-
var ok = FlareSolverrClient.Value.Configure(Config.FlareSolverrApiUrl);
390-
391-
if (!ok) {
392-
Debugger.Break();
393-
}
394-
else {
395-
// Ensure FlareSolverr
396-
397-
try {
398-
var idx = await FlareSolverrClient.Value.Clearance.Solverr.GetIndexAsync();
399-
}
400-
catch (Exception e) {
401-
Trace.WriteLine($"{nameof(FlareSolverrClient)}: {e.Message}");
402-
Config.FlareSolverr = false;
403-
FlareSolverrClient.Value.Dispose();
404-
}
405-
}
300+
await InitFlareSolverr();
406301
}
407302

408303
foreach (BaseSearchEngine bse in Engines) {
@@ -424,6 +319,39 @@ public async ValueTask LoadEnginesAsync(CancellationToken token = default)
424319
ConfigApplied = true;
425320
}
426321

322+
private async Task InitFlareSolverr()
323+
{
324+
var ok = FlareSolverrClient.Value.Configure(Config.FlareSolverrApiUrl);
325+
326+
if (!ok) {
327+
Debugger.Break();
328+
}
329+
else {
330+
// Ensure FlareSolverr
331+
332+
try {
333+
var idx = await FlareSolverrClient.Value.Clearance.Solverr.GetIndexAsync();
334+
}
335+
catch (Exception e) {
336+
Trace.WriteLine($"{nameof(FlareSolverrClient)}: {e.Message}");
337+
Config.FlareSolverr = false;
338+
FlareSolverrClient.Value.Dispose();
339+
}
340+
}
341+
}
342+
343+
private async Task InitCookiesProvider()
344+
{
345+
try {
346+
await ((DefaultCookiesProvider) DefaultCookiesProvider.Instance).OpenAsync();
347+
}
348+
catch (Exception e) {
349+
Trace.WriteLine($"{e}");
350+
Config.ReadCookies = false;
351+
DefaultCookiesProvider.Instance.Dispose();
352+
}
353+
}
354+
427355
public void Dispose()
428356
{
429357
Debug.WriteLine($"Disposing {nameof(SearchClient)}");

SmartImage.Lib/SearchServer.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,18 @@ private async Task<object> HandleRequestAsync(HttpListenerRequest request, HttpL
7474
Debug.WriteLine($"{sz}");
7575

7676
var sq = await SearchQuery.TryCreateAsync(sz);
77-
77+
Client.Query = sq;
7878
if (sq == SearchQuery.Null) {
7979
return R1.Err_Query;
8080
}
8181

8282
var url = await sq.UploadAsync();
8383

84-
var results1 = Client.RunSearchAsync(sq);
85-
84+
// todo
85+
var results1 = Client.RunSearchAsync();
86+
var results = new List<SearchResult>();
8687
await foreach (var v in results1) {
87-
88+
results.Add(v);
8889
}
8990

9091
var best = SearchClient.GetBest(results);
@@ -129,9 +130,9 @@ public class SearchResults
129130
public SearchResultItem Best { get; internal set; }
130131

131132
[JsonPropertyOrder(1)]
132-
public SearchResult[] Results { get; }
133+
public IList<SearchResult> Results { get; }
133134

134-
public SearchResults(SearchResult[] results, SearchResultItem best)
135+
public SearchResults(IList<SearchResult> results, SearchResultItem best)
135136
{
136137
Best = best;
137138
Results = results;

SmartImage.Lib/Utilities/SearchUtil.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ public static bool IsError(this SearchResultStatus s)
2626

2727
public static bool HasFlagFast(this SearchResultFlags value, SearchResultFlags status)
2828
=> (value & status) != 0;
29+
2930
}

SmartImage.Rdx/Commands/SearchCommand.cs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ public sealed class SearchCommand : AsyncCommand<SearchCommandSettings>, IDispos
5959

6060
public SearchClient Client { get; }
6161

62-
public SearchQuery Query { get; private set; }
62+
public SearchQuery Query
63+
{
64+
get => Client.Query;
65+
set => Client.Query = value;
66+
}
6367

6468
public SearchConfig Config { get; }
6569

@@ -76,7 +80,7 @@ public SearchCommand()
7680
Config = new SearchConfig();
7781

7882
// Config = (SearchConfig) cfg;
79-
Client = new SearchClient(Config);
83+
Client = new SearchClient(Config, Query);
8084

8185
// Client.OnSearchComplete += OnSearchComplete;
8286

@@ -298,6 +302,7 @@ await AnsiConsole.Live(m_table).StartAsync(async (f) =>
298302
// TODO: Rewrite RunSearch counterparts
299303

300304

305+
#if OLD
301306
private async Task RunSearchLiveAsync(LiveDisplayContext c)
302307
{
303308

@@ -334,6 +339,38 @@ private async Task RunSearchLiveAsync(LiveDisplayContext c)
334339
await search;
335340

336341
}
342+
#endif
343+
private async Task RunSearchLiveAsync(LiveDisplayContext c)
344+
{
345+
346+
#if UNITTEST
347+
return;
348+
#endif
349+
await foreach (var result in Client.RunSearchAsync(token: m_cts.Token)) {
350+
m_results.TryAdd(result, BaseOSIntegration.EC_ERROR);
351+
352+
// m_results.Add(result);
353+
354+
355+
/*var txt = new Text(result.Engine.Name, GetEngineColor(result.Engine.EngineOption));
356+
var txt2 = new Text($"{result.Results.Count}");
357+
358+
m_mainTable.AddRow(txt, txt2);*/
359+
360+
361+
var rows = CreateResultRows(result);
362+
363+
m_results[result] = m_table.Rows.Count;
364+
365+
foreach (IRenderable[] row in rows) {
366+
m_table.AddRow(row);
367+
}
368+
369+
c.Refresh();
370+
371+
}
372+
373+
}
337374

338375

339376
private async ValueTask ShowImageScanResultsAsync(SearchResultItem item)

0 commit comments

Comments
 (0)