Skip to content

Commit 9df45f1

Browse files
committed
Add fluffle.xyz support (#55)
1 parent 0689799 commit 9df45f1

File tree

8 files changed

+212
-11
lines changed

8 files changed

+212
-11
lines changed

SmartImage.Lib 3/Engines/BaseSearchEngine.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
global using Url = Flurl.Url;
1+
global using R1 = SmartImage.Lib.Resources;
2+
global using Url = Flurl.Url;
23
using System.Diagnostics;
34
using System.Drawing;
45
using System.Json;
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Text.Json;
6+
using System.Text.Json.Serialization;
7+
using System.Threading.Tasks;
8+
using Flurl.Http;
9+
using JetBrains.Annotations;
10+
using SmartImage.Lib.Model;
11+
using SmartImage.Lib.Results;
12+
13+
namespace SmartImage.Lib.Engines.Impl.Search;
14+
15+
public class FluffleEngine : BaseSearchEngine, IDisposable
16+
{
17+
18+
public const string URL_ENDPOINT = "https://api.fluffle.xyz/v1/";
19+
public const string URL_BASE = "https://fluffle.xyz/";
20+
21+
public FluffleEngine() : base(URL_BASE, URL_ENDPOINT)
22+
{
23+
MaxSize = 4_194_304; // MiB
24+
}
25+
26+
protected override bool VerifyQuery(SearchQuery q)
27+
{
28+
return base.VerifyQuery(q);
29+
}
30+
31+
protected override SearchResultStatus Verify(SearchQuery q)
32+
{
33+
return base.Verify(q);
34+
}
35+
36+
public override async Task<SearchResult> GetResultAsync(SearchQuery query, CancellationToken token = default)
37+
{
38+
var br = await base.GetResultAsync(query, token);
39+
40+
var s = $"{R1.Name}/{SearchClient.Asm.GetName().Version} (by {R1.Author} on GitHub)";
41+
42+
var sr = await Client.Request(EndpointUrl, "search")
43+
.WithHeaders(new
44+
{
45+
User_Agent = s
46+
})
47+
.WithTimeout(Timeout)
48+
.PostMultipartAsync(c =>
49+
{
50+
c.AddFile("file", query.Uni.Stream, "file");
51+
c.AddString("includeNsfw", true.ToString());
52+
c.AddString("limit", 32.ToString());
53+
54+
// c.AddString("platforms", null)
55+
// c.AddString("createLink", false)
56+
}, cancellationToken: token);
57+
58+
var obj = await sr.GetJsonAsync<FluffleResponse>();
59+
60+
foreach (FluffleResult result in obj.Results) {
61+
var item = result.Convert(br, out var c);
62+
br.Results.Add(item);
63+
}
64+
65+
return br;
66+
}
67+
68+
protected override async ValueTask<Url> GetRawUrlAsync(SearchQuery query)
69+
{
70+
return await base.GetRawUrlAsync(query);
71+
}
72+
73+
public override SearchEngineOptions EngineOption => SearchEngineOptions.Fluffle;
74+
75+
public override void Dispose()
76+
{
77+
}
78+
79+
}
80+
81+
public class FluffleResultCredit
82+
{
83+
[JsonPropertyName("id")]
84+
public int Id { get; set; }
85+
86+
[JsonPropertyName("name")]
87+
public string Name { get; set; }
88+
}
89+
90+
public class FluffleResult : IResultConvertable
91+
{
92+
[JsonPropertyName("id")]
93+
public int Id { get; set; }
94+
95+
[JsonPropertyName("score")]
96+
public double Score { get; set; }
97+
98+
[JsonPropertyName("match")]
99+
public string Match { get; set; }
100+
101+
[JsonPropertyName("platform")]
102+
public string Platform { get; set; }
103+
104+
[JsonPropertyName("location")]
105+
public string Location { get; set; }
106+
107+
[JsonPropertyName("isSfw")]
108+
public bool IsSfw { get; set; }
109+
110+
[JsonPropertyName("thumbnail")]
111+
public FluffleResultThumbnail Thumbnail { get; set; }
112+
113+
[JsonPropertyName("credits")]
114+
public List<FluffleResultCredit> Credits { get; set; }
115+
116+
public SearchResultItem Convert(SearchResult sr, out SearchResultItem[] children)
117+
{
118+
children = [];
119+
120+
var sri = new SearchResultItem(sr)
121+
{
122+
Artist = Credits.FirstOrDefault()?.Name,
123+
Url = Location,
124+
Similarity = Score * 100.0d,
125+
Metadata = this,
126+
Thumbnail = Thumbnail?.Location,
127+
Site = Platform
128+
};
129+
return sri;
130+
}
131+
132+
}
133+
134+
public class FluffleResponse
135+
{
136+
[JsonPropertyName("id")]
137+
public string Id { get; set; }
138+
139+
[JsonPropertyName("stats")]
140+
public FluffleResultStats Stats { get; set; }
141+
142+
[JsonPropertyName("results")]
143+
public List<FluffleResult> Results { get; set; }
144+
}
145+
146+
public class FluffleResultStats
147+
{
148+
[JsonPropertyName("count")]
149+
public int Count { get; set; }
150+
151+
[JsonPropertyName("elapsedMilliseconds")]
152+
public int ElapsedMilliseconds { get; set; }
153+
}
154+
155+
public class FluffleResultThumbnail
156+
{
157+
[JsonPropertyName("width")]
158+
public int Width { get; set; }
159+
160+
[JsonPropertyName("centerX")]
161+
public int CenterX { get; set; }
162+
163+
[JsonPropertyName("height")]
164+
public int Height { get; set; }
165+
166+
[JsonPropertyName("centerY")]
167+
public int CenterY { get; set; }
168+
169+
[JsonPropertyName("location")]
170+
public string Location { get; set; }
171+
}
172+

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,16 @@ public SearchResultItem Convert(SearchResult sr, out SearchResultItem[] children
222222
$"[{TimeSpan.FromSeconds(from):g} - {TimeSpan.FromSeconds(to):g}]",
223223
};
224224

225-
result.Metadata.video = video;
226-
result.Metadata.image = image;
225+
// result.Metadata.video = video;
226+
// result.Metadata.image = image;
227227

228228
if (result.Similarity < FILTER_THRESHOLD) {
229229
/*result.OtherMetadata.Add("Note", $"Result may be inaccurate " +
230230
$"({result.Similarity.Value / 100:P} " +
231231
$"< {FILTER_THRESHOLD / 100:P})");*/
232232
//todo
233233

234-
result.Metadata.Warning = $"Similarity below threshold {FILTER_THRESHOLD:P}";
234+
// result.Metadata.Warning = $"Similarity below threshold {FILTER_THRESHOLD:P}";
235235
}
236236

237237
return result;

SmartImage.Lib 3/Engines/SearchEngineOptions.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace SmartImage.Lib.Engines;
1111
[Flags]
1212
public enum SearchEngineOptions
1313
{
14+
1415
/// <summary>
1516
/// No engines
1617
/// </summary>
@@ -86,13 +87,22 @@ public enum SearchEngineOptions
8687
/// </summary>
8788
ArchiveMoe = 1 << 13,
8889

89-
Iqdb3D = 1<<14,
90+
/// <summary>
91+
/// <see cref="Iqdb3DEngine"/>
92+
/// </summary>
93+
Iqdb3D = 1 << 14,
94+
95+
/// <summary>
96+
/// <see cref="FluffleEngine"/>
97+
/// </summary>
98+
Fluffle = 1 << 15,
9099

91100
/// <summary>
92101
/// All engines
93102
/// </summary>
94-
All = SauceNao | ImgOps | GoogleImages | TinEye | Iqdb | TraceMoe | KarmaDecay | Yandex | Bing |
95-
Ascii2D | RepostSleuth | EHentai | ArchiveMoe | Iqdb3D,
103+
All = SauceNao | ImgOps | GoogleImages | TinEye | Iqdb | TraceMoe | KarmaDecay | Yandex | Bing |
104+
Ascii2D | RepostSleuth | EHentai | ArchiveMoe | Iqdb3D | Fluffle,
96105

97106
Artwork = SauceNao | Iqdb | Ascii2D | EHentai,
107+
98108
}

SmartImage.Lib 3/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

SmartImage.Lib 3/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,7 @@
183183
<data name="S_ReadCookies" xml:space="preserve">
184184
<value>Read cookies</value>
185185
</data>
186+
<data name="Author2" xml:space="preserve">
187+
<value>Decimation</value>
188+
</data>
186189
</root>

SmartImage.Lib 3/Results/SearchResultItem.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public sealed record SearchResultItem : IDisposable, IComparable<SearchResultIte
9292
/// <summary>
9393
/// Additional metadata.
9494
/// </summary>
95-
public dynamic Metadata { get; internal set; }
95+
public object Metadata { get; internal set; }
9696

9797
public int Score { get; private set; }
9898

@@ -129,7 +129,7 @@ public override int GetHashCode()
129129
internal SearchResultItem(SearchResult r)
130130
{
131131
Root = r;
132-
Metadata = new ExpandoObject();
132+
Metadata = null;
133133
m_isScored = false;
134134
Uni = null;
135135
Parent = null;

SmartImage.Lib 3/SearchClient.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.Net;
66
using System.Net.NetworkInformation;
7+
using System.Reflection;
78
using System.Runtime.CompilerServices;
89
using System.Text.Json;
910
using System.Threading.Channels;
@@ -44,6 +45,8 @@ public sealed class SearchClient : IDisposable
4445

4546
private static readonly ILogger Logger = LogUtil.Factory.CreateLogger(nameof(SearchClient));
4647

48+
internal static readonly Assembly Asm;
49+
4750
public SearchClient(SearchConfig cfg)
4851
{
4952
Config = cfg;
@@ -52,7 +55,11 @@ public SearchClient(SearchConfig cfg)
5255
LoadEngines();
5356
}
5457

55-
static SearchClient() { }
58+
static SearchClient()
59+
{
60+
Asm = Assembly.GetCallingAssembly();
61+
62+
}
5663

5764
[ModuleInitializer]
5865
public static void Init()
@@ -73,7 +80,6 @@ public static void Init()
7380
});*/
7481

7582
Logger.LogInformation("Init");
76-
7783
}
7884

7985
public delegate void ResultCompleteCallback(object sender, SearchResult e);

0 commit comments

Comments
 (0)