Skip to content

Commit 23368f2

Browse files
committed
Filtering
1 parent 10170f1 commit 23368f2

15 files changed

+70
-50
lines changed

SmartImage/Core/SearchConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using SmartImage.Engines;
99
using SmartImage.Engines.Imgur;
1010
using SmartImage.Engines.SauceNao;
11+
using SmartImage.Searching;
1112
using SmartImage.Utilities;
1213

1314
#pragma warning disable HAA0502, HAA0302, HAA0505, HAA0601, HAA0301, HAA0501, HAA0101, HAA0102, RCS1036
@@ -82,6 +83,7 @@ private SearchConfig()
8283

8384
/// <summary>
8485
/// Does not open results from priority engines if the result similarity (if available) is below a certain threshold.
86+
/// <see cref="ISearchResult.Filter"/> is <c>true</c> if <see cref="ISearchEngine.FilterThreshold"/> is less than <see cref="ISearchResult.Similarity"/>
8587
/// </summary>
8688
[field: ConfigComponent("filter_results", "--filter-results", true, true)]
8789
public bool FilterResults { get; set; }

SmartImage/Engines/BasicSearchEngine.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ protected BasicSearchEngine(string baseUrl)
2020

2121
public abstract Color Color { get; }
2222

23+
24+
public virtual float? FilterThreshold => null;
25+
2326
public virtual FullSearchResult GetResult(string url)
2427
{
2528
string rawUrl = GetRawResultUrl(url);

SmartImage/Engines/ISearchEngine.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ public interface ISearchEngine
1212
public FullSearchResult GetResult(string url);
1313

1414
public Color Color { get; }
15+
16+
public float? FilterThreshold { get; }
1517
}
1618
}

SmartImage/Engines/Imgur/ImgurClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public string Upload(string path)
5050
var response = client.Execute(request);
5151

5252
var des = new JsonDeserializer();
53-
return des.Deserialize<ImgurResponse<ImgurImage>>(response).Data.Link;
53+
return des.Deserialize<ImgurDataResponse<ImgurImage>>(response).Data.Link;
5454
}
5555
}
5656
}

SmartImage/Engines/Imgur/ImgurResponse.cs renamed to SmartImage/Engines/Imgur/ImgurDataResponse.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace SmartImage.Engines.Imgur
44
{
55
[UsedImplicitly(ImplicitUseTargetFlags.WithMembers)]
6-
internal sealed class ImgurResponse<T>
6+
internal sealed class ImgurDataResponse<T>
77
{
88
public T Data { get; set; }
99

SmartImage/Engines/Other/IqdbEngine.cs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ public IqdbEngine() : base("https://iqdb.org/?url=") { }
2222

2323
public override SearchEngineOptions Engine => SearchEngineOptions.Iqdb;
2424

25+
public override float? FilterThreshold => 70.00F;
26+
2527
private struct IqdbResult : ISearchResult
2628
{
27-
public bool? Filter { get; set; }
29+
public bool Filter { get; set; }
30+
2831
public string? Caption { get; set; }
2932

3033
public string Source { get; }
@@ -45,36 +48,38 @@ public IqdbResult(string caption, string source, string url, int width, int heig
4548
Width = width;
4649
Height = height;
4750
Similarity = similarity;
48-
Filter = null;
51+
Filter = false; // set later
4952
}
5053

5154
public override string ToString()
5255
{
5356
return
54-
$"{nameof(Caption)}: {Caption}, {nameof(Source)}: {Source}, {nameof(Width)}: {Width}, {nameof(Height)}: {Height}, {nameof(Url)}: {Url}, {nameof(Similarity)}: {Similarity}";
57+
$"{nameof(Caption)}: {Caption}, {nameof(Source)}: " +
58+
$"{Source}, {nameof(Width)}: {Width}, {nameof(Height)}: " +
59+
$"{Height}, {nameof(Url)}: {Url}, {nameof(Similarity)}: {Similarity}";
5560
}
5661
}
5762

58-
private static IqdbResult ParseResult(HtmlNodeCollection tr)
63+
private IqdbResult ParseResult(HtmlNodeCollection tr)
5964
{
6065
var caption = tr[0];
61-
var img = tr[1];
62-
var src = tr[2];
66+
var img = tr[1];
67+
var src = tr[2];
6368

6469
string url = null!;
6570

6671
var urlNode = img.FirstChild.FirstChild;
6772

6873
if (urlNode.Name != "img") {
69-
var origUrl= urlNode.Attributes["href"].Value;
74+
var origUrl = urlNode.Attributes["href"].Value;
7075

7176
Debug.WriteLine(origUrl);
72-
77+
7378
// Links must begin with http:// in order to work with "start"
7479
if (origUrl.StartsWith("//")) {
7580
origUrl = "http:" + origUrl;
7681
}
77-
82+
7883

7984
url = origUrl;
8085
}
@@ -83,7 +88,7 @@ private static IqdbResult ParseResult(HtmlNodeCollection tr)
8388

8489
if (tr.Count >= 4) {
8590
var res = tr[3];
86-
var wh = res.InnerText.Split("×");
91+
var wh = res.InnerText.Split("×");
8792

8893
var wStr = wh[0].SelectOnlyDigits();
8994
w = int.Parse(wStr);
@@ -98,7 +103,7 @@ private static IqdbResult ParseResult(HtmlNodeCollection tr)
98103

99104
if (tr.Count >= 5) {
100105
var simNode = tr[4];
101-
var simStr = simNode.InnerText.Split('%')[0];
106+
var simStr = simNode.InnerText.Split('%')[0];
102107
sim = float.Parse(simStr);
103108
}
104109
else {
@@ -107,7 +112,7 @@ private static IqdbResult ParseResult(HtmlNodeCollection tr)
107112

108113

109114
var i = new IqdbResult(caption.InnerText, src.InnerText, url, w, h, sim);
110-
115+
i.Filter = i.Similarity < FilterThreshold;
111116
return i;
112117
}
113118

@@ -116,20 +121,20 @@ public override FullSearchResult GetResult(string url)
116121
var sr = base.GetResult(url);
117122

118123
try {
119-
124+
120125
var html = Network.GetSimpleResponse(sr.RawUrl);
121126

122127
//Network.WriteResponse(html);
123128

124129
var doc = new HtmlDocument();
125130
doc.LoadHtml(html.Content);
126-
131+
127132

128133
//var tables = doc.DocumentNode.SelectNodes("//table");
129134

130135
// Don't select other results
131136

132-
var pages = doc.DocumentNode.SelectSingleNode("//div[@id='pages']");
137+
var pages = doc.DocumentNode.SelectSingleNode("//div[@id='pages']");
133138
var tables = pages.SelectNodes("div/table");
134139

135140
// No relevant results?
@@ -155,8 +160,9 @@ public override FullSearchResult GetResult(string url)
155160
images.RemoveAt(0);
156161

157162
var best = images[0];
158-
sr.Url = best.Url;
163+
sr.Url = best.Url;
159164
sr.Similarity = best.Similarity;
165+
sr.Filter = best.Filter;
160166

161167
sr.AddExtendedResults(images.ToArray());
162168

SmartImage/Engines/Other/YandexEngine.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public YandexEngine() : base("https://yandex.com/images/search?rpt=imageview&url
2323

2424
private struct YandexResult : ISearchResult
2525
{
26-
public bool? Filter { get; set; }
26+
public bool Filter { get; set; }
2727
public float? Similarity { get; set; }
2828

2929
public int? Width { get; set; }
@@ -42,7 +42,7 @@ internal YandexResult(int width, int height, string url)
4242
Url = url;
4343
Caption = null;
4444
Similarity = null;
45-
Filter = null;
45+
Filter = false;
4646
}
4747

4848
public override string ToString()

SmartImage/Engines/SauceNao/SauceNaoResponse.cs renamed to SmartImage/Engines/SauceNao/SauceNaoDataResponse.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
namespace SmartImage.Engines.SauceNao
55
{
66
[DataContract]
7-
public class SauceNaoResponse
7+
public class SauceNaoDataResponse
88
{
99
//ignore
1010
//[DeserializeAs(Name = "header")]
1111
//public object Header { get; set; }
1212

1313
[DataMember(Name = "results")]
14-
public SauceNaoResult[] Results { get; set; }
14+
public SauceNaoDataResult[] Results { get; set; }
1515

1616
public override string ToString()
1717
{

SmartImage/Engines/SauceNao/SauceNaoResult.cs renamed to SmartImage/Engines/SauceNao/SauceNaoDataResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
namespace SmartImage.Engines.SauceNao
55
{
66
[DataContract]
7-
public class SauceNaoResult
7+
public class SauceNaoDataResult
88
{
99
/// <summary>
1010
/// The url(s) where the source is from. Multiple will be returned if the exact same image is found in multiple places

SmartImage/Engines/SauceNao/SauceNaoEngine.cs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,13 @@ public sealed class SauceNaoEngine : BasicSearchEngine
3939
public override SearchEngineOptions Engine => SearchEngineOptions.SauceNao;
4040

4141
public override Color Color => Color.OrangeRed;
42+
43+
public override float? FilterThreshold => 70.00F;
4244

4345
private struct SauceNaoSimpleResult : ISearchResult
4446
{
4547
public string? Caption { get; set; }
46-
public bool? Filter { get; set; }
48+
public bool Filter { get; set; }
4749
public string Url { get; set; }
4850
public float? Similarity { get; set; }
4951
public int? Width { get; set; }
@@ -56,7 +58,7 @@ public SauceNaoSimpleResult(string? title, string url, float? similarity)
5658
Similarity = similarity;
5759
Width = null;
5860
Height = null;
59-
Filter = null;
61+
Filter = false;//set later
6062
}
6163

6264
public override string ToString()
@@ -81,15 +83,16 @@ private SauceNaoEngine(string apiKey) : base(BASIC_RESULT)
8183

8284
public SauceNaoEngine() : this(SearchConfig.Config.SauceNaoAuth) { }
8385

84-
private static ISearchResult[] ConvertResults(SauceNaoResult[] results)
86+
private ISearchResult[] ConvertResults(SauceNaoDataResult[] results)
8587
{
8688
var rg = new List<ISearchResult>();
8789

8890
foreach (var sn in results) {
8991
if (sn.Url != null) {
9092
var url = sn.Url.FirstOrDefault(u => u != null);
91-
92-
rg.Add(new SauceNaoSimpleResult(sn.WebsiteTitle, url, sn.Similarity));
93+
var x = new SauceNaoSimpleResult(sn.WebsiteTitle, url, sn.Similarity);
94+
x.Filter = x.Similarity < FilterThreshold;
95+
rg.Add(x);
9396
}
9497
}
9598

@@ -113,11 +116,12 @@ public override FullSearchResult GetResult(string url)
113116
.Where(e => e.Url != null)
114117
.OrderByDescending(e => e.Similarity)
115118
.First();
116-
119+
120+
// Copy
117121
result.Url = best.Url;
118122
result.Similarity = best.Similarity;
119123
result.Caption = best.Caption;
120-
124+
result.Filter = best.Filter;
121125

122126
result.AddExtendedResults(extended);
123127

@@ -136,7 +140,7 @@ public override FullSearchResult GetResult(string url)
136140
}
137141

138142

139-
private IEnumerable<SauceNaoResult>? GetResults(string url)
143+
private IEnumerable<SauceNaoDataResult>? GetResults(string url)
140144
{
141145

142146
var req = new RestRequest();
@@ -154,7 +158,7 @@ public override FullSearchResult GetResult(string url)
154158
}
155159

156160

157-
private static IEnumerable<SauceNaoResult>? ReadResults(string js)
161+
private static IEnumerable<SauceNaoDataResult>? ReadResults(string js)
158162
{
159163
// todo: rewrite this using Newtonsoft
160164

@@ -180,8 +184,8 @@ public override FullSearchResult GetResult(string url)
180184
using var stream =
181185
JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json),
182186
XmlDictionaryReaderQuotas.Max);
183-
var serializer = new DataContractJsonSerializer(typeof(SauceNaoResponse));
184-
var result = serializer.ReadObject(stream) as SauceNaoResponse;
187+
var serializer = new DataContractJsonSerializer(typeof(SauceNaoDataResponse));
188+
var result = serializer.ReadObject(stream) as SauceNaoDataResponse;
185189
stream.Dispose();
186190

187191
if (result is null)

0 commit comments

Comments
 (0)