Skip to content

Commit 7cbc023

Browse files
committed
Refactoring
1 parent c08e5fb commit 7cbc023

36 files changed

Lines changed: 335 additions & 354 deletions

SmartImage.Lib/Clients/FlareSolverrClient.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
using System.Reflection;
66
using CliWrap;
77
using FlareSolverrSharp;
8+
using FlareSolverrSharp.Solvers;
9+
using FlareSolverrSharp.Types;
10+
using Microsoft.Extensions.Logging;
811
using SmartImage.Lib.Model;
12+
using SmartImage.Lib.Utilities;
913

1014
namespace SmartImage.Lib.Clients;
1115

@@ -25,6 +29,8 @@ public sealed class FlareSolverrClient : IDisposable, ISearchConfigReceiver
2529

2630
public HttpClient Client { get; private set; }
2731

32+
private static readonly ILogger s_logger = AppSupport.Factory.CreateLogger("FlareSolverr");
33+
2834
public bool Configure(string api)
2935
{
3036
Dispose();
@@ -36,28 +42,27 @@ public bool Configure(string api)
3642

3743
Client = new HttpClient(Clearance);
3844

39-
Trace.WriteLine($"{nameof(FlareSolverrClient)}: init {api}");
45+
s_logger.LogTrace("Init with {Api}", api);
4046

4147
return HasClient;
4248
}
4349

44-
private FlareSolverrClient() { }
50+
public FlareSolverrClient([CBN] string api = SearchConfig.FLARE_SOLVERR_API_URL_DEFAULT)
51+
{
52+
Configure(api);
53+
}
4554

4655
static FlareSolverrClient() { }
4756

48-
public static FlareSolverrClient Value { get; private set; } = new();
4957

5058
public void Dispose()
5159
{
52-
Debug.WriteLine($"Disposing {nameof(FlareSolverrClient)}");
5360
Clearance?.Dispose();
5461
Client?.Dispose();
5562
Clearance = null;
5663
Client = null;
5764
}
5865

59-
#region Implementation of ISearchConfigReceiver
60-
6166
public ValueTask<bool> ApplyConfigAsync(SearchConfig cfg, CancellationToken ct = default)
6267
{
6368
var ok = false;
@@ -67,6 +72,6 @@ public ValueTask<bool> ApplyConfigAsync(SearchConfig cfg, CancellationToken ct =
6772
return ValueTask.FromResult(ok);
6873
}
6974

70-
#endregion
75+
7176

7277
}

SmartImage.Lib/Engines/ParsedSearchEngine.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
namespace SmartImage.Lib.Engines;
1313

14+
/// <summary>
15+
/// Represents a search engine whose results are parsed: <para />
16+
/// <typeparamref name="TSource"/> &#8594; <typeparamref name="TIntermediate"/> &#8594; <typeparamref name="TItem"/>
17+
/// </summary>
1418
public abstract class ParsedSearchEngine<TItem, TIntermediate, TSource> : BaseSearchEngine
1519
where TItem : SearchResultItem
1620
{

SmartImage.Lib/Engines/Results/SearchResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace SmartImage.Lib.Engines.Results;
1818
public class SearchResult : IDisposable, INotifyPropertyChanged
1919
{
2020

21-
// IDEA: FLATTEN SearchResult to SearchResultItem and eliminate SearchResult ≡ SearchResultItem
21+
// IDEA: FLATTEN SearchResult to SearchResultItem and eliminate SearchResult ≡ SearchResultItem?
2222

2323
/// <summary>
2424
/// Engine which returned this result

SmartImage.Lib/Engines/Results/SearchResultItem.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717

1818
namespace SmartImage.Lib.Engines.Results;
1919

20-
public class SearchResultItem : UniImageUri, IComparable<SearchResultItem>, IComparable, IEquatable<SearchResultItem>
20+
// todo: refactor to not inherit from UniImageUrl and instead contain a UniImageUrl
21+
22+
public class SearchResultItem : UniImageUrl, IComparable<SearchResultItem>, IComparable, IEquatable<SearchResultItem>
2123
{
2224

2325
/// <summary>
@@ -204,7 +206,7 @@ internal SearchResultItem(SearchResult r, bool isRaw = false) : base(null)
204206

205207
#region
206208

207-
public override async Task<bool> AllocImageAsync(CancellationToken ct = default)
209+
public override async ValueTask<bool> AllocImageAsync(CancellationToken ct = default)
208210
{
209211
if (Url == null) {
210212
return false;
@@ -281,7 +283,7 @@ public SearchResultItem CloneWithUrl(Url s)
281283
var str = await sr.ReadToEndAsync(ct);
282284
283285
var hp = new HtmlParser();
284-
var urls = ImageScanner.ParseImageUrls(str, Url);
286+
var urls = ImageScanner.ParseImageUrlsByRegex(str, Url);
285287
using var doc = await hp.ParseDocumentAsync(str);
286288
var sriNews = new ConcurrentBag<SearchResultItem>();
287289
@@ -341,7 +343,7 @@ public async ValueTask<bool> ScanAsync2(CancellationToken ct = default)
341343
var str = await sr.ReadToEndAsync(ct);
342344

343345
var hp = new HtmlParser();
344-
var urls = ImageScanner.ParseImageUrls(str, Url);
346+
var urls = ImageScanner.ParseImageUrlsByRegex(str, Url);
345347
using var doc = await hp.ParseDocumentAsync(str);
346348
var sriNews = new ConcurrentBag<SearchResultItem>();
347349

SmartImage.Lib/Engines/Search/Ascii2DEngine.cs

Lines changed: 46 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using SmartImage.Lib.Clients;
1717
using SmartImage.Lib.Cookies;
1818
using SmartImage.Lib.Engines.Results;
19+
using SmartImage.Lib.Model;
1920

2021
// ReSharper disable CognitiveComplexity
2122

@@ -26,7 +27,7 @@ namespace SmartImage.Lib.Engines.Search;
2627

2728
// todo
2829

29-
public sealed class Ascii2DEngine : WebSearchEngine<Ascii2DItem, IList<INode>>, ICookiesReceiver
30+
public sealed class Ascii2DEngine : WebSearchEngine<Ascii2DItem, IList<INode>>, ICookiesReceiver, ISearchConfigReceiver
3031
{
3132

3233
public override SearchEngineOptions EngineOption => SearchEngineOptions.Ascii2D;
@@ -43,34 +44,15 @@ public sealed class Ascii2DEngine : WebSearchEngine<Ascii2DItem, IList<INode>>,
4344

4445
public const string MAIN_URL = "https://ascii2d.net/search/url/";
4546

47+
private FlareSolverrClient m_fsClient;
48+
4649
public Ascii2DEngine() : base(MAIN_URL)
4750
{
48-
Timeout = TimeSpan.FromSeconds(30);
51+
Timeout = TimeSpan.FromSeconds(30);
4952
MaxLength = 10_000_000;
50-
Jar = new CookieJar();
51-
}
52-
53-
public async ValueTask<bool> ApplyCookiesAsync(ICookiesSource source, CancellationToken ct)
54-
{
55-
if ( /*FlareSolverrClient.Value.IsInitialized*/ source == null) {
56-
return false;
57-
}
58-
59-
var cookies = await source.GetOrLoadCookiesAsync(ct).ConfigureAwait(false);
60-
61-
foreach (var bck in cookies) {
62-
var ck = bck.AsCookie();
63-
64-
if (ck.Domain.Contains("ascii2d")) {
65-
Jar.AddOrReplace(new FlurlCookie(ck.Name, ck.Value, BaseUrl));
66-
}
67-
}
68-
69-
70-
return true;
53+
Jar = new CookieJar();
7154
}
7255

73-
7456

7557
public override void Dispose() { }
7658

@@ -135,18 +117,10 @@ protected override ValueTask<IList<INode>> ParseIntermediateAsync(IDocument src)
135117

136118
protected override ValueTask<IEnumerable<Ascii2DItem>> ParseItemsAsync(IList<INode> source, SearchResult r)
137119
{
138-
var buf = new List<Ascii2DItem>(source.Count);
139-
140-
foreach (var node in source) {
141-
var item = Ascii2DItem.ParseSource(node, r);
142-
buf.Add(item);
143-
}
144-
145-
return ValueTask.FromResult<IEnumerable<Ascii2DItem>>(buf);
120+
return ValueTask.FromResult(source.Select(node => Ascii2DItem.ParseSource(node, r)));
146121
}
147122

148-
protected override async Task<IDocument> GetSourceAsync(SearchResult sr, SearchQuery query,
149-
CancellationToken token = default)
123+
protected override async Task<IDocument> GetSourceAsync(SearchResult sr, SearchQuery query, CancellationToken token = default)
150124
{
151125
var parser = new HtmlParser();
152126

@@ -169,48 +143,29 @@ protected override async Task<IDocument> GetSourceAsync(SearchResult sr, SearchQ
169143
170144
}*/
171145

172-
if (FlareSolverrClient.Value.IsInitialized) {
146+
if (m_fsClient.IsInitialized) {
173147

174148
var msg = new HttpRequestMessage(HttpMethod.Get, origin);
175149

176-
var fsr = await FlareSolverrClient.Value.Clearance.Solverr.SolveAsync(msg).ConfigureAwait(false);
150+
var fsr = await m_fsClient.Clearance.Solverr.SolveAsync(msg).ConfigureAwait(false);
177151
var cookies = fsr.Solution.Cookies;
178152
var newUrl = fsr.Solution.Url;
179153

154+
Logger.LogTrace("{Name} using {Fs}: {CookieCnt} {NewUrl}", Name, fsr, cookies.Length, newUrl);
180155

181156
foreach (FlareSolverrCookie cookie in cookies) {
182157
Jar.AddOrReplace(new FlurlCookie(cookie.Name, cookie.Value, fsr.Solution.Url));
183158
}
184-
185-
using var res = await Client.Request(newUrl)
186-
.WithSettings(static x => { x.HttpVersion = "2.0"; })
187-
.AllowAnyHttpStatus()
188-
.WithCookies(Jar)
189-
.WithTimeout(Timeout)
190-
/*.OnError(s =>
191-
{
192-
Debug.WriteLine($"{s.Response}");
193-
s.ExceptionHandled = true;
194-
195-
})*/
196-
.GetAsync(cancellationToken: token).ConfigureAwait(false);
197-
198-
199-
// var res1 = await FlareSolverrClient.Client.SendAsync(msg, token);
200-
// str = await res1.Content.ReadAsStringAsync(token);
201-
str = await res.GetStringAsync().ConfigureAwait(false);
202-
203159
}
204-
else {
205-
using var res = await GetResponseByUrlAsync(origin, token).ConfigureAwait(false);
206160

207-
if (res.StatusCode == (int) HttpStatusCode.BadGateway) {
208-
return null;
209-
}
161+
using var res = await GetResponseByUrlAsync(origin, token).ConfigureAwait(false);
210162

211-
str = await res.GetStringAsync().ConfigureAwait(false);
163+
if (res.StatusCode == (int) HttpStatusCode.BadGateway) {
164+
return null;
212165
}
213166

167+
str = await res.GetStringAsync().ConfigureAwait(false);
168+
214169
var document = await parser.ParseDocumentAsync(str, token).ConfigureAwait(false);
215170

216171
return document;
@@ -234,12 +189,38 @@ private async Task<IFlurlResponse> GetResponseByUrlAsync(Url origin, Cancellatio
234189
{
235190
var res = await Client.Request(origin)
236191
.AllowAnyHttpStatus()
237-
.WithCookies(out var cj)
192+
.WithCookies(Jar)
238193
.WithTimeout(Timeout)
239-
.GetAsync(cancellationToken: token).ConfigureAwait(false);
194+
.GetAsync(cancellationToken: token)
195+
.ConfigureAwait(false);
240196
return res;
241197
}
242198

199+
public async ValueTask<bool> ApplyCookiesAsync(ICookiesSource source, CancellationToken ct)
200+
{
201+
var cookies = await source.GetOrLoadCookiesAsync(ct).ConfigureAwait(false);
202+
203+
foreach (var bck in cookies) {
204+
var ck = bck.AsCookie();
205+
206+
if (ck.Domain.Contains("ascii2d")) {
207+
Jar.AddOrReplace(new FlurlCookie(ck.Name, ck.Value, BaseUrl));
208+
}
209+
}
210+
211+
212+
return true;
213+
}
214+
215+
public ValueTask<bool> ApplyConfigAsync(SearchConfig cfg, CancellationToken ct = default)
216+
{
217+
if (cfg.FlareSolverr) {
218+
m_fsClient = new FlareSolverrClient(cfg.FlareSolverrApiUrl);
219+
}
220+
221+
return ValueTask.FromResult(m_fsClient is not null);
222+
}
223+
243224
}
244225

245226
public class Ascii2DItem : SearchResultItem, IParseableSource<INode, Ascii2DItem>
@@ -279,14 +260,14 @@ public static Ascii2DItem ParseSource(INode nx, SearchResult r)
279260
sri.Format = data[1];
280261

281262
string size = data[2];
282-
string title1 = (n as IHtmlElement).FirstChild.TryGetAttribute("Title");
263+
string title1 = (n as IHtmlElement)?.FirstChild.TryGetAttribute("Title");
283264

284265
if (info.Length >= 3) {
285266
var node2 = info[2];
286267
var desc = info.Last().FirstChild;
287268
var ns = desc.NextSibling;
288269

289-
if (node2.ChildNodes.Length >= 2 && node2.ChildNodes[1].ChildNodes.Length >= 2) {
270+
if (node2.ChildNodes is [_, { ChildNodes.Length: >= 2 }, ..]) {
290271
var node2Sub = node2.ChildNodes[1];
291272

292273
if (node2Sub.ChildNodes.Length >= 8) {

SmartImage.Lib/Engines/Search/EHentaiEngine.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace SmartImage.Lib.Engines.Search;
2121
/// <see cref="SearchEngineOptions.EHentai" />
2222
/// </summary>
2323
/// <remarks>Handles both ExHentai and E-Hentai</remarks>
24-
public sealed class EHentaiEngine : WebSearchEngine<EhResult, IList<INode>>, INotifyPropertyChanged, ICookiesReceiver,ISearchConfigReceiver
24+
public sealed class EHentaiEngine : WebSearchEngine<EhResult, IList<INode>>, INotifyPropertyChanged, ICookiesReceiver, ISearchConfigReceiver
2525
{
2626

2727
public override SearchEngineOptions EngineOption => SearchEngineOptions.EHentai;
@@ -92,7 +92,7 @@ protected override async Task<IDocument> GetSourceAsync(SearchResult sr, SearchQ
9292
string fileName;
9393
string filePath = null;
9494

95-
if (query.Source.HasFilePath) {
95+
if (query.Source.HasLocalFilePath) {
9696
filePath = query.Source.LocalFilePath;
9797
fileName = Path.GetFileName(filePath);
9898

@@ -182,22 +182,14 @@ protected override ValueTask<IList<INode>> ParseIntermediateAsync(IDocument src)
182182

183183
if (array.Count != 0) {
184184
array = array[1..];
185-
186185
}
187186

188187
return ValueTask.FromResult((IList<INode>) array);
189188
}
190189

191190
protected override ValueTask<IEnumerable<EhResult>> ParseItemsAsync(IList<INode> source, SearchResult r)
192191
{
193-
var buf = new List<EhResult>(source.Count);
194-
195-
foreach (INode node in source) {
196-
var eh = EhResult.ParseSource(node, r);
197-
buf.Add(eh);
198-
}
199-
200-
return ValueTask.FromResult<IEnumerable<EhResult>>(buf);
192+
return ValueTask.FromResult(source.Select(node => EhResult.ParseSource(node, r)));
201193
}
202194

203195
/*
@@ -271,8 +263,7 @@ public async Task<bool> LoginAsync(string username, string password)
271263
{ new StringContent("Login!"), "ipb_login_submit" }
272264
};
273265

274-
var response = await EHentaiIndex
275-
.SetQueryParams(new
266+
var response = await EHentaiIndex.SetQueryParams(new
276267
{
277268
act = "Login",
278269
CODE = 01

SmartImage.Lib/Engines/Search/FluffleEngine.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
using SixLabors.ImageSharp.Formats.Png;
1515
using SixLabors.ImageSharp.Processing;
1616
using SmartImage.Lib.Engines.Results;
17-
using SmartImage.Lib.Model;
1817
using SmartImage.Lib.Utilities;
1918

2019
namespace SmartImage.Lib.Engines.Search;
2120

22-
public class FluffleEngine : BaseSearchEngine, IEndpoint, IDisposable
21+
public class FluffleEngine : BaseSearchEngine, IDisposable
2322
{
2423
public override SearchEngineOptions EngineOption => SearchEngineOptions.Fluffle;
2524

SmartImage.Lib/Engines/Search/GoogleLensEngine.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,12 @@
1515
using SmartImage.Lib.Cookies;
1616
using SmartImage.Lib.Engines.Results;
1717
using SmartImage.Lib.Images.Uni;
18-
using SmartImage.Lib.Model;
1918

2019
// ReSharper disable UnusedMember.Local
2120
#pragma warning disable IDE0051
2221
namespace SmartImage.Lib.Engines.Search;
2322

24-
public class GoogleLensEngine : WebSearchEngine<GoogleLensItem, IList<INode>>, IEndpoint, ICookiesReceiver
23+
public class GoogleLensEngine : WebSearchEngine<GoogleLensItem, IList<INode>>, ICookiesReceiver
2524
{
2625

2726
// TODO: WIP

0 commit comments

Comments
 (0)