Skip to content

Commit 81b1143

Browse files
committed
Add Pomf engine
1 parent 5b0ddd2 commit 81b1143

File tree

15 files changed

+454
-371
lines changed

15 files changed

+454
-371
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using System.Json;
2+
using Kantan.Net;
3+
using Newtonsoft.Json.Linq;
4+
5+
// ReSharper disable PossibleNullReferenceException
6+
7+
// ReSharper disable UnusedMember.Global
8+
9+
namespace SmartImage.Lib.Clients;
10+
11+
public sealed class AnilistClient : IDisposable
12+
{
13+
private readonly GraphQLClient m_client;
14+
15+
public AnilistClient()
16+
{
17+
m_client = new GraphQLClient("https://graphql.anilist.co");
18+
}
19+
20+
public async Task<string> GetTitleAsync(int anilistId)
21+
{
22+
/*
23+
* https://anilist.gitbook.io/anilist-apiv2-docs/overview/graphql
24+
* https://anilist.gitbook.io/anilist-apiv2-docs/overview/graphql/getting-started
25+
* https://graphql.org/learn/queries/
26+
*/
27+
28+
const string GRAPH_QUERY = @"query ($id: Int) { # Define which variables will be used in the query (id)
29+
Media(id: $id, type: ANIME) { # Insert our variables into the query arguments (id) (type: ANIME is hard-coded in the query)
30+
id
31+
title {
32+
romaji
33+
english
34+
native
35+
}
36+
}
37+
}";
38+
39+
var response = await m_client.ExecuteAsync(GRAPH_QUERY, new
40+
{
41+
query = GRAPH_QUERY,
42+
id = anilistId
43+
});
44+
45+
return response["data"]["Media"]["title"]["english"];
46+
}
47+
48+
#region IDisposable
49+
50+
public void Dispose()
51+
{
52+
m_client.Dispose();
53+
}
54+
55+
#endregion
56+
}
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Diagnostics.CodeAnalysis;
5+
using System.Json;
6+
using System.Linq;
7+
using System.Runtime.CompilerServices;
8+
using System.Security.Authentication;
9+
using System.Security.Cryptography;
10+
using System.Security.Policy;
11+
using System.Text;
12+
using System.Text.Json;
13+
using System.Text.Json.Nodes;
14+
using System.Text.Json.Serialization;
15+
using System.Threading.Tasks;
16+
using Flurl.Http;
17+
using Novus.Streams;
18+
using SmartImage.Lib.Engines;
19+
using JsonObject = System.Json.JsonObject;
20+
using JsonValue = System.Json.JsonValue;
21+
22+
namespace SmartImage.Lib.Clients;
23+
24+
public class HydrusClient : IEndpoint, INotifyPropertyChanged
25+
{
26+
private const string HDR_HYDRUS_KEY = "Hydrus-Client-API-Access-Key";
27+
private const string GET_FILES_THUMBNAIL = "/get_files/thumbnail";
28+
private const string GET_FILES_FILE = "/get_files/file";
29+
30+
public FlurlClient Client { get; }
31+
32+
public HydrusClient(string endpoint, string key)
33+
{
34+
EndpointUrl = endpoint;
35+
Key = key;
36+
37+
Client = new FlurlClient(EndpointUrl)
38+
{
39+
Headers =
40+
{
41+
{ HDR_HYDRUS_KEY, key }
42+
}
43+
};
44+
45+
PropertyChanged += (sender, args) =>
46+
{
47+
switch (args.PropertyName)
48+
{
49+
case nameof(Key):
50+
Client.Headers.AddOrReplace(HDR_HYDRUS_KEY, Key);
51+
break;
52+
case nameof(EndpointUrl):
53+
Client.BaseUrl = EndpointUrl;
54+
break;
55+
}
56+
57+
};
58+
}
59+
60+
public HydrusClient() : this(null, null) { }
61+
62+
public bool IsValid => EndpointUrl != null && Key != null;
63+
64+
public async Task<JsonValue> GetFileHashesAsync(string hash, string hashType = "sha256")
65+
{
66+
67+
using var res = await Client.Request("/get_files/file_hashes")
68+
.SetQueryParam("hash", hash)
69+
.SetQueryParam("source_hash_type", hashType)
70+
.SetQueryParam("desired_hash_type", hashType)
71+
.GetAsync();
72+
73+
var b = await res.GetStreamAsync();
74+
var j = JsonValue.Load(b);
75+
return j;
76+
77+
}
78+
79+
public async Task<JsonValue> GetFileMetadataAsync(string hash)
80+
{
81+
82+
using var res = await Client.Request("/get_files/file_metadata")
83+
.SetQueryParam("hash", hash)
84+
.GetAsync();
85+
86+
var b = await res.GetStreamAsync();
87+
var j = JsonValue.Load(b);
88+
return j;
89+
}
90+
91+
public async Task<JsonValue> GetFileRelationshipsAsync(string hash)
92+
{
93+
using var res = await Client.Request("/manage_file_relationships/get_file_relationships")
94+
.SetQueryParam("hash", hash)
95+
.GetAsync();
96+
97+
var b = await res.GetStreamAsync();
98+
var j = JsonValue.Load(b);
99+
100+
return j;
101+
}
102+
103+
public async Task<IFlurlResponse> GetFileAsync(string hash)
104+
{
105+
var res = await Client.Request(GET_FILES_FILE)
106+
.SetQueryParam("hash", hash)
107+
.GetAsync();
108+
109+
return res;
110+
}
111+
public async Task<IFlurlResponse> GetFileAsync(int id)
112+
{
113+
var res = await Client.Request(GET_FILES_FILE)
114+
.SetQueryParam("file_id", id)
115+
.GetAsync();
116+
117+
return res;
118+
}
119+
public async Task<IFlurlResponse> GetFileThumbnailAsync(string hash)
120+
{
121+
var res = await Client.Request(GET_FILES_THUMBNAIL)
122+
.SetQueryParam("hash", hash)
123+
.GetAsync();
124+
125+
return res;
126+
}
127+
128+
public async Task<IFlurlResponse> GetFileThumbnailAsync(int id)
129+
{
130+
var res = await Client.Request(GET_FILES_THUMBNAIL)
131+
.SetQueryParam("file_id", id)
132+
.GetAsync();
133+
134+
return res;
135+
}
136+
137+
private string m_key;
138+
139+
public string Key
140+
{
141+
get => m_key;
142+
set
143+
{
144+
if (value == m_key) return;
145+
m_key = value;
146+
OnPropertyChanged();
147+
OnPropertyChanged(nameof(IsValid));
148+
}
149+
}
150+
151+
private string m_endpointUrl;
152+
153+
public string EndpointUrl
154+
{
155+
get => m_endpointUrl;
156+
set
157+
{
158+
if (value == m_endpointUrl) return;
159+
m_endpointUrl = value;
160+
OnPropertyChanged();
161+
OnPropertyChanged(nameof(IsValid));
162+
}
163+
}
164+
165+
public void Dispose()
166+
{
167+
Client.Dispose();
168+
}
169+
170+
public event PropertyChangedEventHandler PropertyChanged;
171+
172+
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
173+
{
174+
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
175+
}
176+
177+
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
178+
{
179+
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
180+
field = value;
181+
OnPropertyChanged(propertyName);
182+
return true;
183+
}
184+
}
185+
186+
public partial class FileRelationship
187+
{
188+
[JsonPropertyName("0")]
189+
public string[] PotentialDuplicates { get; set; }
190+
191+
[JsonPropertyName("1")]
192+
public string[] FalsePositives { get; set; }
193+
194+
[JsonPropertyName("3")]
195+
public string[] Alternates { get; set; }
196+
197+
[JsonPropertyName("8")]
198+
public string[] Duplicates { get; set; }
199+
200+
[JsonPropertyName("is_king")]
201+
public bool IsKing { get; set; }
202+
203+
[JsonPropertyName("king")]
204+
public string King { get; set; }
205+
206+
[JsonPropertyName("king_is_local")]
207+
public bool KingIsLocal { get; set; }
208+
209+
[JsonPropertyName("king_is_on_file_domain")]
210+
public bool KingIsOnFileDomain { get; set; }
211+
212+
public static Dictionary<string, FileRelationship> Deserialize(JsonValue v)
213+
{
214+
var vs = ((JsonObject)v)["file_relationships"];
215+
216+
var re = JsonSerializer.Deserialize<Dictionary<string, FileRelationship>>(vs.ToString());
217+
218+
return re;
219+
}
220+
}

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

Lines changed: 0 additions & 56 deletions
This file was deleted.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Kantan.Collections;
88
using Kantan.Text;
99
using Newtonsoft.Json;
10+
using SmartImage.Lib.Clients;
1011
using SmartImage.Lib.Model;
1112
using SmartImage.Lib.Results;
1213

0 commit comments

Comments
 (0)