Skip to content

Commit c20a640

Browse files
committed
Fix SauceNao API usage; config dialog tweaks
1 parent 396fb1d commit c20a640

File tree

3 files changed

+131
-115
lines changed

3 files changed

+131
-115
lines changed

SmartImage 3/Mode/Shell/ShellMode.Dialog.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ Eh username/password
356356
Y = Pos.Y(lbEhUsername),
357357
Width = WIDTH1 * 2,
358358
Height = 1,
359+
Text = Config.EhUsername
359360
};
360361

361362
tfEhUsername.TextChanging += args =>
@@ -370,7 +371,8 @@ Eh username/password
370371
X = Pos.X(lbEhUsername),
371372
Y = Pos.Bottom(lbEhUsername),
372373
CanFocus = false,
373-
ColorScheme = UI.Cs_Lbl1
374+
ColorScheme = UI.Cs_Lbl1,
375+
374376
};
375377

376378
TextField tfEhPassword = new()
@@ -379,6 +381,8 @@ Eh username/password
379381
Y = Pos.Y(lbEhPassword),
380382
Width = WIDTH1 * 2,
381383
Height = 1,
384+
Text = Config.EhPassword
385+
382386
};
383387

384388
tfEhPassword.TextChanging += args =>
@@ -451,6 +455,7 @@ void OnAction(ListView lv, Action<SearchEngineOptions> f)
451455
Y = Pos.Y(lbSauceNaoKey),
452456
Width = WIDTH1 * 2,
453457
Height = 1,
458+
Text = Config.SauceNaoKey
454459
};
455460

456461
tfSauceNaoKey.TextChanging += txt =>

SmartImage 3/Utilities/ConsoleUtil.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ internal static void SetConsoleMode()
5151
{
5252
// Clipboard.Open();
5353

54-
Console.InputEncoding = Console.OutputEncoding = Encoding.UTF8;
54+
// Console.InputEncoding = Console.OutputEncoding = Encoding.UTF8;
55+
Console.InputEncoding = Console.OutputEncoding = Encoding.Unicode;
56+
5557
Native.GetConsoleMode(StdIn, out ConsoleModes lpMode);
5658

5759
_oldMode = lpMode;

SmartImage.Lib 3/Engines/Impl/Search/SauceNaoEngine.cs

Lines changed: 122 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using SmartImage.Lib.Model;
1414
using SmartImage.Lib.Results;
1515
using static Kantan.Diagnostics.LogCategories;
16+
using static SmartImage.Lib.Engines.Impl.Search.SauceNaoEngine.Strings;
1617
using JsonArray = System.Json.JsonArray;
1718
using JsonObject = System.Json.JsonObject;
1819

@@ -31,9 +32,15 @@ namespace SmartImage.Lib.Engines.Impl.Search;
3132

3233
public sealed class SauceNaoEngine : BaseSearchEngine, IClientSearchEngine, IConfig
3334
{
34-
private static readonly string[] Syn_Artists = { "Creator(s):", "Creator:", "Member:", "Artist:", "Author:" };
35-
private static readonly string[] Syn_Characters = { "Characters:" };
36-
private static readonly string[] Syn_Material = { "Material:", "Source:" };
35+
internal static class Strings
36+
{
37+
public const string Twitter = "Twitter:";
38+
public const string TweetID = "Tweet ID:";
39+
40+
public static readonly string[] Syn_Artists = { "Creator(s):", "Creator:", "Member:", "Artist:", "Author:" };
41+
public static readonly string[] Syn_Characters = { "Characters:" };
42+
public static readonly string[] Syn_Material = { "Material:", "Source:" };
43+
}
3744

3845
private const string BASE_URL = "https://saucenao.com/";
3946

@@ -182,131 +189,135 @@ private async Task<IEnumerable<SauceNaoDataResult>> GetWebResultsAsync(SearchQue
182189

183190
var results = doc.Body.SelectNodes("//div[@class='result']");
184191

185-
static SauceNaoDataResult Parse(INode result)
186-
{
187-
if (result == null) {
188-
return null;
189-
}
192+
return results.Select(Parse).ToList();
193+
}
190194

191-
const string HIDDEN_ID_VAL = "result-hidden-notification";
195+
private static SauceNaoDataResult Parse(INode result)
196+
{
197+
// TODO: OPTIMIZE
192198

193-
if (result.TryGetAttribute(Serialization.Atr_id) == HIDDEN_ID_VAL) {
194-
return null;
195-
}
199+
if (result == null) {
200+
return null;
201+
}
196202

197-
var resulttablecontent = result.FirstChild
198-
.FirstChild
199-
.FirstChild
200-
.ChildNodes[1];
203+
const string HIDDEN_ID_VAL = "result-hidden-notification";
201204

202-
var resultmatchinfo = resulttablecontent.FirstChild;
203-
var resultsimilarityinfo = resultmatchinfo.FirstChild;
205+
if (result.TryGetAttribute(Serialization.Atr_id) == HIDDEN_ID_VAL) {
206+
return null;
207+
}
204208

205-
// Contains links
206-
var resultmiscinfo = resultmatchinfo.ChildNodes[1];
207-
// var resultcontent = resulttablecontent.ChildNodes[1];
208-
// var resultcontentcolumn = resultcontent.ChildNodes[1];
209-
var resultcontent = ((IElement) result).GetElementsByClassName("resultcontent")[0];
209+
var resulttablecontent = result.FirstChild
210+
.FirstChild
211+
.FirstChild
212+
.ChildNodes[1];
210213

211-
IHtmlCollection<IElement> resultcontentcolumn_rg = null;
214+
var resultmatchinfo = resulttablecontent.FirstChild;
215+
var resultsimilarityinfo = resultmatchinfo.FirstChild;
212216

213-
if (result is IElement { } elem) {
214-
resultcontentcolumn_rg = elem.QuerySelectorAll(Serialization.S_SauceNao_ResultContentColumn);
217+
// Contains links
218+
var resultmiscinfo = resultmatchinfo.ChildNodes[1];
219+
// var resultcontent = resulttablecontent.ChildNodes[1];
220+
// var resultcontentcolumn = resultcontent.ChildNodes[1];
221+
var resultcontent = ((IElement) result).GetElementsByClassName("resultcontent")[0];
215222

216-
}
217-
// var resulttitle = resultcontent.ChildNodes[0];
223+
IHtmlCollection<IElement> resultcontentcolumn_rg = null;
218224

219-
var links = new List<string>();
225+
if (result is IElement { } elem) {
226+
resultcontentcolumn_rg = elem.QuerySelectorAll(Serialization.S_SauceNao_ResultContentColumn);
220227

221-
if (resulttablecontent is IElement { } e) {
222-
var links1 = e.QuerySelectorAll(Serialization.Tag_a)
223-
.Select(x => x.GetAttribute(Serialization.Atr_href));
224-
links.AddRange(links1);
225-
}
228+
}
229+
// var resulttitle = resultcontent.ChildNodes[0];
226230

227-
var element = resultcontentcolumn_rg.Select(c => c.ChildNodes)
228-
.SelectMany(c => c.GetElementsByTagName(Serialization.Tag_a)
229-
.Select(x => x.GetAttribute(Serialization.Atr_href)))
230-
.Where(e => e != null);
231+
var links = new List<string>();
231232

232-
if (element.Any()) {
233-
links.AddRange(element);
234-
}
233+
if (resulttablecontent is IElement { } e) {
234+
var links1 = e.QuerySelectorAll(Serialization.Tag_a)
235+
.Select(x => x.GetAttribute(Serialization.Atr_href));
236+
links.AddRange(links1);
237+
}
235238

236-
if (resultmiscinfo != null) {
237-
links.Add(resultmiscinfo.ChildNodes.GetElementsByTagName(Serialization.Tag_a)
238-
.FirstOrDefault(x => x.GetAttribute(Serialization.Atr_href) != null)?
239-
.GetAttribute(Serialization.Atr_href));
240-
}
239+
var element = resultcontentcolumn_rg.Select(c => c.ChildNodes)
240+
.SelectMany(c => c.GetElementsByTagName(Serialization.Tag_a)
241+
.Select(x => x.GetAttribute(Serialization.Atr_href)))
242+
.Where(ec => ec != null);
241243

242-
// //div[contains(@class, 'resulttitle')]
243-
// //div/node()[self::strong]
244+
if (element.Any()) {
245+
links.AddRange(element);
246+
}
244247

245-
INode resulttitle = resultcontent.ChildNodes[0];
246-
string rti = resulttitle?.TextContent;
248+
if (resultmiscinfo != null) {
249+
links.Add(resultmiscinfo.ChildNodes.GetElementsByTagName(Serialization.Tag_a)
250+
.FirstOrDefault(x => x.GetAttribute(Serialization.Atr_href) != null)?
251+
.GetAttribute(Serialization.Atr_href));
252+
}
247253

248-
// INode resultcontentcolumn1 = resultcontent.ChildNodes[1];
249-
string rcci = resultcontentcolumn_rg.FuncJoin(e => e.TextContent, ",");
254+
// //div[contains(@class, 'resulttitle')]
255+
// //div/node()[self::strong]
250256

251-
// string material1 = rcci.SubstringAfter(material);
252-
string material1 = rcci.SubstringAfter(Syn_Material.First());
257+
INode resulttitle = resultcontent.ChildNodes[0];
258+
string rti = resulttitle?.TextContent;
253259

254-
// string creator1 = rcci;
255-
string creator1 = rcci;
256-
string characters1 = null;
260+
// INode resultcontentcolumn1 = resultcontent.ChildNodes[1];
261+
string rcci = resultcontentcolumn_rg.FuncJoin(e => e.TextContent, ",");
257262

258-
foreach (var s in Syn_Artists) {
259-
if (rti.StartsWith(s)) {
260-
rti = rti.SubstringAfter(s).Trim(' ');
261-
}
262-
}
263+
// string material1 = rcci.SubstringAfter(material);
264+
string material1 = rcci.SubstringAfter(Syn_Material.First());
263265

264-
var nodes = resultcontentcolumn_rg.SelectMany(e => e.ChildNodes)
265-
.Where(c => c is not (IElement { TagName: "BR" }
266-
or IElement { NodeName: "SPAN" }))
267-
.ToArray();
266+
// string creator1 = rcci;
267+
string creator1 = rcci;
268+
string characters1 = null;
268269

269-
float similarity = float.Parse(resultsimilarityinfo.TextContent.Replace("%", string.Empty));
270+
foreach (var s in Syn_Artists) {
271+
if (rti.StartsWith(s)) {
272+
rti = rti.SubstringAfter(s).Trim(' ');
273+
}
274+
}
270275

271-
var dataResult = new SauceNaoDataResult
272-
{
273-
Urls = links.Distinct().ToArray(),
274-
Similarity = similarity,
275-
// Creator = creator1,
276-
Title = rti,
277-
Material = material1
276+
var nodes = resultcontentcolumn_rg.SelectMany(e => e.ChildNodes)
277+
.Where(c => c is not (IElement { TagName: "BR" }
278+
or IElement { NodeName: "SPAN" }))
279+
.ToArray();
278280

279-
};
281+
float similarity = float.Parse(resultsimilarityinfo.TextContent.Replace("%", string.Empty));
282+
283+
var sndr = new SauceNaoDataResult
284+
{
285+
Urls = links.Distinct().ToArray(),
286+
Similarity = similarity,
287+
// Creator = creator1,
288+
Title = rti,
289+
Material = material1
280290

281-
for (int i = 0; i < nodes.Length; i++) {
282-
var node = nodes[i];
283-
var s = node.TextContent;
291+
};
284292

285-
if (s.StartsWith(Syn_Material[0])) {
286-
dataResult.Source = nodes[++i].TextContent.Trim(' ');
287-
continue;
288-
}
293+
for (int i = 0; i < nodes.Length; i++) {
294+
var node = nodes[i];
295+
var s = node.TextContent;
289296

290-
if (s.StartsWith(Syn_Material[1])) {
291-
dataResult.Material = nodes[++i].TextContent.Trim(' ');
292-
continue;
293-
}
297+
if (s.StartsWith(Syn_Material[0])) {
298+
sndr.Source = nodes[++i].TextContent.Trim(' ');
299+
continue;
300+
}
294301

295-
if (Syn_Characters.Any(s.StartsWith)) {
296-
dataResult.Character = nodes[++i].TextContent.Trim(' ');
297-
continue;
298-
}
302+
if (s.StartsWith(Syn_Material[1])) {
303+
sndr.Material = nodes[++i].TextContent.Trim(' ');
304+
continue;
305+
}
299306

300-
if (Syn_Artists.Any(s.StartsWith)) {
301-
dataResult.Creator = nodes[++i].TextContent.Trim(' ');
302-
}
307+
if (Syn_Characters.Any(s.StartsWith) || Syn_Artists.Any(s.StartsWith)) {
308+
sndr.Character = nodes[++i].TextContent.Trim(' ');
309+
continue;
303310
}
304311

305-
return dataResult;
312+
if (s.StartsWith(Twitter)) {
313+
sndr.Creator = nodes[++i].TextContent.Trim(' ');
314+
// var idx = Array.IndexOf(sndr.Urls, nodes[i].TryGetAttribute(Serialization.Atr_href));
315+
continue;
316+
}
306317

307318
}
308319

309-
return results.Select(Parse).ToList();
320+
return sndr;
310321
}
311322

312323
private async Task<IEnumerable<SauceNaoDataResult>> GetAPIResultsAsync(SearchQuery url)
@@ -323,8 +334,8 @@ private async Task<IEnumerable<SauceNaoDataResult>> GetAPIResultsAsync(SearchQue
323334
{ "db", dbIndex },
324335
{ "output_type", "2" },
325336
{ "api_key", Authentication },
326-
{ "url", url.ToString() },
327-
{ "numres", numRes }
337+
{ "url", url.Upload },
338+
// { "numres", numRes }
328339
};
329340

330341
var content = new FormUrlEncodedContent(values);
@@ -436,18 +447,16 @@ public SearchResultItem Convert(SearchResult r)
436447
var idxStr = Index.ToString();
437448
string siteName = Index != 0 ? idxStr : null;
438449

439-
var site = Strings.NormalizeNull(siteName);
440-
var title = Strings.NormalizeNull(WebsiteTitle);
450+
var site = Kantan.Text.Strings.NormalizeNull(siteName);
451+
var title = Kantan.Text.Strings.NormalizeNull(WebsiteTitle);
441452

442453
var sb = new StringBuilder();
443454

444-
if (site is { })
445-
{
455+
if (site is { }) {
446456
sb.Append(site);
447457
}
448458

449-
if (title is { })
450-
{
459+
if (title is { }) {
451460
sb.Append($" [{title}]");
452461
}
453462

@@ -458,25 +467,25 @@ public SearchResultItem Convert(SearchResult r)
458467
Url u = s;
459468
return u.Host == "gelbooru" || u.Host == "danbooru";
460469
}).ToArray();*/
461-
462-
var urls = Urls.Distinct().Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
470+
471+
string[] urls = (Urls != null) ? Urls.Distinct().Where(s => !string.IsNullOrWhiteSpace(s)).ToArray() : Array.Empty<string>();
472+
463473
string[] meta = Array.Empty<string>();
464474

465-
if ((urls.Length >= 2))
466-
{
467-
meta = urls[1..].Where(u => !((Url)u).QueryParams.Contains("lookup_type")).ToArray();
475+
if ((urls.Length >= 2)) {
476+
meta = urls[1..].Where(u => !((Url) u).QueryParams.Contains("lookup_type")).ToArray();
468477
}
469478

470479
var imageResult = new SearchResultItem(r)
471480
{
472481
Url = urls.FirstOrDefault(),
473482
Similarity = Math.Round(Similarity, 2),
474-
Description = Strings.NormalizeNull(idxStr),
475-
Artist = Strings.NormalizeNull(Creator),
476-
Source = Strings.NormalizeNull(Material),
477-
Character = Strings.NormalizeNull(Character),
483+
Description = Kantan.Text.Strings.NormalizeNull(idxStr),
484+
Artist = Kantan.Text.Strings.NormalizeNull(Creator),
485+
Source = Kantan.Text.Strings.NormalizeNull(Material),
486+
Character = Kantan.Text.Strings.NormalizeNull(Character),
478487
Site = site,
479-
Title = Strings.NormalizeNull(Title),
488+
Title = Kantan.Text.Strings.NormalizeNull(Title),
480489
Metadata = meta,
481490
};
482491

0 commit comments

Comments
 (0)