From 318a67616fae07d303018afb66c4963c7a44d711 Mon Sep 17 00:00:00 2001 From: Read Date: Fri, 15 Jan 2021 20:53:46 -0600 Subject: [PATCH] Additional result info, SauceNao rework --- SmartImage/Engines/Other/IqdbEngine.cs | 19 ++- SmartImage/Engines/Other/YandexEngine.cs | 8 + .../Engines/SauceNao/SauceNaoDataResult.cs | 35 +---- SmartImage/Engines/SauceNao/SauceNaoEngine.cs | 141 ++++++++++-------- SmartImage/Engines/TraceMoe/TraceMoeEngine.cs | 4 +- SmartImage/Searching/FullSearchResult.cs | 43 ++++-- SmartImage/Searching/ISearchResult.cs | 10 ++ 7 files changed, 151 insertions(+), 109 deletions(-) diff --git a/SmartImage/Engines/Other/IqdbEngine.cs b/SmartImage/Engines/Other/IqdbEngine.cs index 6977ef5e..39144475 100644 --- a/SmartImage/Engines/Other/IqdbEngine.cs +++ b/SmartImage/Engines/Other/IqdbEngine.cs @@ -30,7 +30,7 @@ private struct IqdbResult : ISearchResult public string? Caption { get; set; } - public string Source { get; } + public string? Source { get; set; } public int? Width { get; set; } @@ -38,17 +38,23 @@ private struct IqdbResult : ISearchResult public string Url { get; set; } - public float? Similarity { get; set; } + public float? Similarity { get; set; } + public string? Artist { get; set; } + public string? Characters { get; set; } + public string? SiteName { get; set; } - public IqdbResult(string caption, string source, string url, int width, int height, float? similarity) + public IqdbResult(string siteName, string source, string url, int width, int height, float? similarity) { - Caption = caption; + SiteName = siteName; Url = url; Source = source; Width = width; Height = height; Similarity = similarity; Filter = false; // set later + Artist = null; + Characters = null; + Caption = null; } } @@ -105,7 +111,7 @@ private IqdbResult ParseResult(HtmlNodeCollection tr) } - var i = new IqdbResult(caption.InnerText, src.InnerText, url, w, h, sim); + var i = new IqdbResult(src.InnerText, null, url, w, h, sim); i.Filter = i.Similarity < FilterThreshold; return i; } @@ -153,7 +159,8 @@ public override FullSearchResult GetResult(string url) sr.Url = best.Url; sr.Similarity = best.Similarity; sr.Filter = best.Filter; - + sr.Source = best.Source; + sr.SiteName = best.SiteName; sr.AddExtendedResults(images.ToArray()); diff --git a/SmartImage/Engines/Other/YandexEngine.cs b/SmartImage/Engines/Other/YandexEngine.cs index bdafc340..ccf2513b 100644 --- a/SmartImage/Engines/Other/YandexEngine.cs +++ b/SmartImage/Engines/Other/YandexEngine.cs @@ -34,6 +34,10 @@ private struct YandexResult : ISearchResult public string Url { get; set; } + public string? Artist { get; set; } + public string? Source { get; set; } + public string? Characters { get; set; } + public string? SiteName { get; set; } internal YandexResult(int width, int height, string url) { @@ -43,6 +47,10 @@ internal YandexResult(int width, int height, string url) Caption = null; Similarity = null; Filter = false; + Artist = null; + Source = null; + Characters = null; + SiteName=null; } public override string ToString() diff --git a/SmartImage/Engines/SauceNao/SauceNaoDataResult.cs b/SmartImage/Engines/SauceNao/SauceNaoDataResult.cs index c93dac83..0850617c 100644 --- a/SmartImage/Engines/SauceNao/SauceNaoDataResult.cs +++ b/SmartImage/Engines/SauceNao/SauceNaoDataResult.cs @@ -5,65 +5,36 @@ namespace SmartImage.Engines.SauceNao { - [DataContract] public class SauceNaoDataResult { /// /// The url(s) where the source is from. Multiple will be returned if the exact same image is found in multiple places /// - [DataMember(Name = "ext_urls")] - public string[] Url { get; internal set; } + public string[] Urls { get; internal set; } /// /// The search index of the image /// - [DataMember(Name = "index_id")] public SauceNaoSiteIndex Index { get; internal set; } /// /// How similar is the image to the one provided (Percentage)? /// - [DataMember(Name = "similarity")] public float Similarity { get; internal set; } - /// - /// A link to the thumbnail of the image - /// - [DataMember(Name = "thumbnail")] - public string Thumbnail { get; internal set; } - - /// - /// The name of the website it came from - /// - [IgnoreDataMember] - public string WebsiteName { get; internal set; } - - /// - /// How explicit is the image? - /// - [IgnoreDataMember] - public float Rating { get; internal set; } - - [IgnoreDataMember] public string WebsiteTitle { get; set; } - [IgnoreDataMember] public string Character { get; internal set; } - [IgnoreDataMember] - public string Material { get; internal set; } - [IgnoreDataMember] - public string Creator { get; internal set; } - public override string ToString() { - string firstUrl = Url != null ? Url[0] : "-"; + string firstUrl = Urls != null ? Urls[0] : "-"; - return String.Format("{0} ({1}, {2})", firstUrl, Similarity, Index); + return $"{firstUrl} ({Similarity}, {Index})"; } } } \ No newline at end of file diff --git a/SmartImage/Engines/SauceNao/SauceNaoEngine.cs b/SmartImage/Engines/SauceNao/SauceNaoEngine.cs index 77e3c6ac..7816d4c8 100644 --- a/SmartImage/Engines/SauceNao/SauceNaoEngine.cs +++ b/SmartImage/Engines/SauceNao/SauceNaoEngine.cs @@ -51,9 +51,13 @@ private struct SauceNaoSimpleResult : ISearchResult public float? Similarity { get; set; } public int? Width { get; set; } public int? Height { get; set; } + public string? Artist { get; set; } + public string? Source { get; set; } + public string? Characters { get; set; } + public string? SiteName { get; set; } - - public SauceNaoSimpleResult(string? title, string url, float? similarity) + public SauceNaoSimpleResult(string? title, string url, float? similarity, string? artist, string? source, + string? characters, string? siteName) { Caption = title; Url = url; @@ -61,12 +65,15 @@ public SauceNaoSimpleResult(string? title, string url, float? similarity) Width = null; Height = null; Filter = false; //set later - + Artist = artist; + Source = source; + Characters = characters; + SiteName = siteName; } public override string ToString() { - return $"{Caption} {Url} {Similarity}"; + return $"{Url} {Similarity}"; } } @@ -91,14 +98,16 @@ private ISearchResult[] ConvertResults(SauceNaoDataResult[] results) var rg = new List(); foreach (var sn in results) { - if (sn.Url != null) { - var url = sn.Url.FirstOrDefault(u => u != null); - var x = new SauceNaoSimpleResult(sn.WebsiteTitle, url, sn.Similarity); + if (sn.Urls != null) { + var url = sn.Urls.FirstOrDefault(u => u != null); + var name = sn.Index.ToString(); + + var x = new SauceNaoSimpleResult(sn.WebsiteTitle, url, + sn.Similarity, sn.Creator, sn.Material, sn.Character,name); + x.Filter = x.Similarity < FilterThreshold; - - x.Caption = AddCaption(sn); rg.Add(x); } } @@ -106,30 +115,6 @@ private ISearchResult[] ConvertResults(SauceNaoDataResult[] results) return rg.ToArray(); } - private static string? AddCaption(SauceNaoDataResult x) - { - var sb = new StringBuilder(); - - if (x.Character != null) - { - sb.Append($"Characters: {x.Character}"); - } - if (x.Creator != null) - { - sb.Append($" Creator: {x.Creator}"); - } - if (x.Material != null) - { - sb.Append($" Material: {x.Material}"); - } - - if (sb.Length == 0) { - return null; - } - - return sb.ToString(); - } - public override FullSearchResult GetResult(string url) { @@ -138,17 +123,19 @@ public override FullSearchResult GetResult(string url) try { var orig = GetResults(url); - // todo - aggregate all info for primary result - - var character = orig.FirstOrDefault(o => o.Character != null)?.Character; - var creator = orig.FirstOrDefault(o => o.Creator != null)?.Creator; - var material = orig.FirstOrDefault(o => o.Material != null)?.Material; + if (orig == null) { + return result; + } - // todo - bad practice - var dummy = new SauceNaoDataResult() {Character = character, Creator = creator, Material = material}; + // todo - aggregate all info for primary result - result.Caption = AddCaption(dummy); + var character = orig.FirstOrDefault(o => o.Character != null)?.Character; + var creator = orig.FirstOrDefault(o => o.Creator != null)?.Creator; + var material = orig.FirstOrDefault(o => o.Material != null)?.Material; + result.Characters = character; + result.Artist = creator; + result.Source = material; var extended = ConvertResults(orig); @@ -162,7 +149,6 @@ public override FullSearchResult GetResult(string url) // Copy result.Url = best.Url; result.Similarity = best.Similarity; - result.Filter = best.Filter; @@ -185,7 +171,7 @@ public override FullSearchResult GetResult(string url) } - private SauceNaoDataResult[] GetResults(string url) + private SauceNaoDataResult[]? GetResults(string url) { var req = new RestRequest(); @@ -203,7 +189,7 @@ private SauceNaoDataResult[] GetResults(string url) } - private static SauceNaoDataResult[] ReadResults(string js) + private static SauceNaoDataResult[]? ReadResults(string js) { // todo: rewrite this using Newtonsoft @@ -224,30 +210,32 @@ private static SauceNaoDataResult[] ReadResults(string js) } string json = jsonArray.ToString(); - var jsoncpy = json; - - json = json.Insert(json.Length - 1, "}").Insert(0, "{\"results\":"); - - using var stream = - JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), - XmlDictionaryReaderQuotas.Max); + var jsonCpy = json; + // json = json.Insert(json.Length - 1, "}").Insert(0, "{\"results\":"); + // + // using var stream = + // JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), + // XmlDictionaryReaderQuotas.Max); + // + // + // var serializer = new DataContractJsonSerializer(typeof(SauceNaoDataResponse)); + // var result = serializer.ReadObject(stream) as SauceNaoDataResponse; - var serializer = new DataContractJsonSerializer(typeof(SauceNaoDataResponse)); - var result = serializer.ReadObject(stream) as SauceNaoDataResponse; + var buffer = new List(); // todo - crappy solution - - var res2 = JsonArray.Parse(jsoncpy); + + var res2 = JsonArray.Parse(jsonCpy); Debug.WriteLine(res2.Count); - stream.Dispose(); + //stream.Dispose(); - if (result is null) - return null; + //if (result is null) + // return null; - for (int index = 0; index < result.Results.Length; index++) { + /*for (int index = 0; index < result.Results.Length; index++) { var t = result.Results[index]; var t2 = res2[index]; t.WebsiteTitle = Strings.SplitPascalCase(t.Index.ToString()); @@ -258,7 +246,40 @@ private static SauceNaoDataResult[] ReadResults(string js) t.Material = t2.ContainsKey("material") ? t2["material"].ToString() : null; } - return result.Results; + return result.Results;*/ + + for (int i = 0; i < res2.Count; i++) { + var t2 = res2[i]; + + var s = float.Parse(t2["similarity"]); + string[] strings; + + if (t2.ContainsKey("ext_urls")) { + strings = (t2["ext_urls"] as JsonArray).Select(j => j.ToString()).ToArray(); + } + else { + strings = null; + } + + + var sauceNaoSiteIndex = (SauceNaoSiteIndex) int.Parse(t2["index_id"].ToString()); + + var t = new SauceNaoDataResult + { + Urls = strings, + Similarity = s, + Index = sauceNaoSiteIndex, + Creator = t2.ContainsKey("creator") ? t2["creator"].ToString().CleanString() : null, + Character = t2.ContainsKey("characters") ? t2["characters"].ToString().CleanString() : null, + Material = t2.ContainsKey("material") ? t2["material"].ToString().CleanString() : null, + }; + + + buffer.Add(t); + } + + return buffer.ToArray(); + } return null; diff --git a/SmartImage/Engines/TraceMoe/TraceMoeEngine.cs b/SmartImage/Engines/TraceMoe/TraceMoeEngine.cs index 709ac2d1..2793a6c8 100644 --- a/SmartImage/Engines/TraceMoe/TraceMoeEngine.cs +++ b/SmartImage/Engines/TraceMoe/TraceMoeEngine.cs @@ -48,7 +48,7 @@ private ISearchResult[] ConvertResults(TraceMoeRootObject obj) results[i] = new FullSearchResult(this, malUrl, sim) { - Caption = doc.title_english + Source = doc.title_english }; } @@ -80,7 +80,7 @@ public override FullSearchResult GetResult(string url) var best = results[0]; r = new FullSearchResult(this, best.Url, best.Similarity); - r.Caption = best.Caption; + r.Source = best.Source; r.Filter = r.Similarity < FilterThreshold; diff --git a/SmartImage/Searching/FullSearchResult.cs b/SmartImage/Searching/FullSearchResult.cs index ad8f2046..f1840c41 100644 --- a/SmartImage/Searching/FullSearchResult.cs +++ b/SmartImage/Searching/FullSearchResult.cs @@ -143,6 +143,10 @@ public override NConsoleFunction ComboFunction public bool Filter { get; set; } + public string? Artist { get; set; } + public string? Source { get; set; } + public string? Characters { get; set; } + public string? SiteName { get; set; } public void AddExtendedResults(ISearchResult[] bestImages) { @@ -186,18 +190,25 @@ public override string ToString() sb.Append($"\tResult: {Url}\n"); } - if (RawUrl != null) { - sb.Append($"\tRaw: {RawUrl}\n"); - } - - if (Caption != null) { - sb.Append($"\tCaption: {Caption}\n"); - } + + + AddKVSB(sb, RawUrl, "Raw"); - if (Similarity.HasValue) { + if (Similarity.HasValue) + { sb.Append($"\tSimilarity: {Similarity / 100:P}\n"); } + AddKVSB(sb,Artist,nameof(Artist)); + AddKVSB(sb, Characters, nameof(Characters)); + AddKVSB(sb, Source, nameof(Source)); + AddKVSB(sb, Caption, nameof(Caption)); + AddKVSB(sb, SiteName, "Site"); + //todo + + + + if (Width.HasValue && Height.HasValue) { sb.Append($"\tResolution: {Width}x{Height}\n"); } @@ -209,6 +220,16 @@ public override string ToString() return sb.ToString(); } + private static void AddKVSB(StringBuilder sb, string? a, string n) + { + //todo: util + + if (a != null) + { + sb.Append($"\t{n}: {a}\n"); + } + } + private IList FromExtendedResult(IReadOnlyList results) { var rg = new FullSearchResult[results.Count]; @@ -221,7 +242,11 @@ private IList FromExtendedResult(IReadOnlyList { Width = result.Width, Height = result.Height, - Caption = result.Caption + Caption = result.Caption, + Artist = result.Artist, + Source = result.Source, + Characters = result.Characters, + SiteName = result.SiteName, }; rg[i] = sr; diff --git a/SmartImage/Searching/ISearchResult.cs b/SmartImage/Searching/ISearchResult.cs index 543a3899..abcd50c9 100644 --- a/SmartImage/Searching/ISearchResult.cs +++ b/SmartImage/Searching/ISearchResult.cs @@ -39,12 +39,22 @@ public interface ISearchResult public string? Caption { get; set; } + + public string? Artist { get; set; } + + public string? Source { get; set; } + + public string? Characters { get; set; } + + public string? SiteName { get; set; } + /// /// Filter this result if is used /// public bool Filter { get; set; } + }