From b4329cb1571abb0f6ec7a57cf8a0f088d5684638 Mon Sep 17 00:00:00 2001 From: Read <decimation001@gmail.com> Date: Fri, 9 Dec 2022 14:27:29 -0600 Subject: [PATCH] Additional clipboard functionality; work on #32 --- SmartImage 3/App/Integration.cs | 29 ++++++++ SmartImage 3/GuiMain.cs | 6 +- SmartImage 3/ImageUtility.cs | 68 +++++++++++++++++++ SmartImage.Lib 3/Engines/BaseSearchEngine.cs | 4 +- .../Engines/Search/Ascii2DEngine.cs | 15 +++- .../Engines/Search/EHentaiEngine.cs | 24 +++---- 6 files changed, 127 insertions(+), 19 deletions(-) diff --git a/SmartImage 3/App/Integration.cs b/SmartImage 3/App/Integration.cs index 301a9ea9..b73f6ef9 100644 --- a/SmartImage 3/App/Integration.cs +++ b/SmartImage 3/App/Integration.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Diagnostics; +using System.Drawing; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; @@ -228,6 +229,23 @@ public static void KeepOnTop(bool add) IsOnTop = add; } + public static bool ReadClipboardImage(out byte[] i) + { + const uint png = (uint)ClipboardFormat.PNG; + + if (Native.IsClipboardFormatAvailable(png)) + { + var data = Native.GetClipboardData(png); + var pngData = ImageUtility.ReadPNG(data); + i = pngData; + return true; + } + else { + i = null; + return false; + } + } + public static bool ReadClipboard(out string str) { Native.OpenClipboard(); @@ -238,6 +256,17 @@ public static bool ReadClipboard(out string str) str = (string) Native.GetClipboard((uint) ClipboardFormat.CF_TEXT); } + if (ReadClipboardImage(out var ms)) { + var s = Path.Combine(Path.GetTempPath(), $"clipboard_{ms.Length}.png"); + if (!File.Exists(s)) { + File.WriteAllBytes(s, ms); + + } + + str = s; + Debug.WriteLine($"read png from clipboard {s}"); + } + Native.CloseClipboard(); // Debug.WriteLine($"Clipboard data: {str}"); diff --git a/SmartImage 3/GuiMain.cs b/SmartImage 3/GuiMain.cs index 0c1aea38..f448ef2e 100644 --- a/SmartImage 3/GuiMain.cs +++ b/SmartImage 3/GuiMain.cs @@ -610,8 +610,10 @@ private bool ClipboardCallback(MainLoop c) * - Input is already ready * - Clipboard history contains it already */ - if (Integration.ReadClipboard(out var str) && - !SearchQuery.IsUriOrFile(Tf_Input.Text.ToString()) && !m_clipboard.Contains(str)) { + if (!SearchQuery.IsUriOrFile(Tf_Input.Text.ToString()) + && Integration.ReadClipboard(out var str) + && !m_clipboard.Contains(str)) { + SetInputText(str); // Lbl_InputOk.Text = UI.Clp; Lbl_InputInfo.Text = R2.Inf_Clipboard; diff --git a/SmartImage 3/ImageUtility.cs b/SmartImage 3/ImageUtility.cs index cd2d08f1..24abb96a 100644 --- a/SmartImage 3/ImageUtility.cs +++ b/SmartImage 3/ImageUtility.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using Flurl.Http; @@ -119,4 +120,71 @@ public double score return default; }*/ + /// <summary> + /// Reads a <c>PNG</c> + /// </summary> + /// <remarks>Specifically designed for Windows Snipping Tool <c>PNG</c> format</remarks> + public static byte[] ReadPNG(nint data) + { + /* + * TODO: optimize + */ + + int i = 0; + byte b; + var rg = new List<byte>(); + + // IEND + ReadOnlySpan<byte> s = stackalloc byte[] + { + 0x49, + 0x45, + 0x4E, + 0x44 + }; + + void Read() + { + try { + b = Marshal.ReadByte(data, i++); + rg.Add(b); + } + catch (AccessViolationException x) { + b = Byte.MaxValue; + } + finally { } + } + + do { + Read(); + + if (b == s[0]) { + Read(); + + if (b == s[1]) { + Read(); + + if (b == s[2]) { + Read(); + + if (b == s[3]) { + var rg2 = new byte[] + { + Marshal.ReadByte(data, i++), + Marshal.ReadByte(data, i++), + Marshal.ReadByte(data, i++), + Marshal.ReadByte(data, i++), + + }; + rg.AddRange(rg2); + break; + } + } + } + } + + } while (true); + + return rg.ToArray(); + } } \ No newline at end of file diff --git a/SmartImage.Lib 3/Engines/BaseSearchEngine.cs b/SmartImage.Lib 3/Engines/BaseSearchEngine.cs index fb03b4e4..b9211193 100644 --- a/SmartImage.Lib 3/Engines/BaseSearchEngine.cs +++ b/SmartImage.Lib 3/Engines/BaseSearchEngine.cs @@ -39,13 +39,13 @@ protected BaseSearchEngine(string baseUrl) static BaseSearchEngine() { - FlurlHttp.Configure(settings => + /*FlurlHttp.Configure(settings => { settings.Redirects.Enabled = true; // default true settings.Redirects.AllowSecureToInsecure = true; // default false settings.Redirects.ForwardAuthorizationHeader = true; // default false settings.Redirects.MaxAutoRedirects = 15; // default 10 (consecutive) - }); + });*/ // Trace.WriteLine($"Configured HTTP", nameof(BaseSearchEngine)); } diff --git a/SmartImage.Lib 3/Engines/Search/Ascii2DEngine.cs b/SmartImage.Lib 3/Engines/Search/Ascii2DEngine.cs index 63c939d8..90beed08 100644 --- a/SmartImage.Lib 3/Engines/Search/Ascii2DEngine.cs +++ b/SmartImage.Lib 3/Engines/Search/Ascii2DEngine.cs @@ -6,6 +6,8 @@ using AngleSharp.Html.Parser; using AngleSharp.XPath; using Flurl.Http; +using Jint; +using Jint.Parser; using Kantan.Net.Utilities; // ReSharper disable CognitiveComplexity @@ -19,7 +21,7 @@ namespace SmartImage.Lib.Engines.Search; public sealed class Ascii2DEngine : BaseSearchEngine, IWebContentEngine { - public Ascii2DEngine() : base("https://ascii2d.net/search/uri/") + public Ascii2DEngine() : base("https://ascii2d.net/search/url/") { Timeout = TimeSpan.FromSeconds(6); MaxSize = 5 * 1000 * 1000; @@ -72,6 +74,14 @@ public async Task<IDocument> GetDocumentAsync(object origin2, SearchQuery query, { new StringContent(origin),"uri" } }; + FlurlHttp.Configure(settings => + { + settings.Redirects.Enabled = true; // default true + settings.Redirects.AllowSecureToInsecure = true; // default false + settings.Redirects.ForwardAuthorizationHeader = true; // default false + settings.Redirects.MaxAutoRedirects = 20; // default 10 (consecutive) + }); + var res = await origin.AllowAnyHttpStatus() .WithCookies(out var cj) .WithTimeout(timeout.Value) @@ -84,8 +94,7 @@ public async Task<IDocument> GetDocumentAsync(object origin2, SearchQuery query, { s.ExceptionHandled = true; })*/ - .PostAsync(data); - + .GetAsync(); var str = await res.GetStringAsync(); var document = await parser.ParseDocumentAsync(str, token.Value); diff --git a/SmartImage.Lib 3/Engines/Search/EHentaiEngine.cs b/SmartImage.Lib 3/Engines/Search/EHentaiEngine.cs index 5a93cd52..6d9788ac 100644 --- a/SmartImage.Lib 3/Engines/Search/EHentaiEngine.cs +++ b/SmartImage.Lib 3/Engines/Search/EHentaiEngine.cs @@ -38,12 +38,12 @@ public EHentaiEngine() : base(EXHENTAI_URI) public override SearchEngineOptions EngineOption => SearchEngineOptions.EHentai; - public string Username { get; set; } - public string Password { get; set; } + public string Username { get; set; } + public string Password { get; set; } private bool m_isLoggedIn; - public bool IsLoggedIn => m_isLoggedIn ; + public bool IsLoggedIn => m_isLoggedIn; public string NodesSelector => "//table/tbody/tr"; @@ -134,15 +134,15 @@ public async Task<IDocument> GetDocumentAsync(object origin, SearchQuery query, return await parser.ParseDocumentAsync(content); } - private async Task GetSessionAsync() + private async Task<IFlurlResponse> GetSessionAsync() { - var res = await EXHENTAI_URI.WithCookies(Cookies) - .WithHeaders(new - { - User_Agent = HttpUtilities.UserAgent - }) - .WithAutoRedirect(true) - .GetAsync(); + return await EXHENTAI_URI.WithCookies(Cookies) + .WithHeaders(new + { + User_Agent = HttpUtilities.UserAgent + }) + .WithAutoRedirect(true) + .GetAsync(); } /* @@ -177,7 +177,7 @@ public async Task LoginAsync() Cookies.AddOrReplace(fc); } - await GetSessionAsync(); + var res2 = await GetSessionAsync(); m_isLoggedIn = true; }