From 79b90a38007a6ac85afe426a4303be23b6aa037c Mon Sep 17 00:00:00 2001 From: aiqinxuancai Date: Thu, 28 Oct 2021 11:10:44 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChromeTest/App.xaml | 9 + ChromeTest/App.xaml.cs | 17 + ChromeTest/AssemblyInfo.cs | 10 + ChromeTest/ChromeTest.csproj | 13 + ChromeTest/MainWindow.xaml | 12 + ChromeTest/MainWindow.xaml.cs | 28 ++ EvernoteToNotionChrome.sln | 6 + EvernoteToNotionChrome/App.xaml.cs | 6 +- .../EvernoteToNotionChrome.csproj | 4 +- EvernoteToNotionChrome/MainWindow.xaml | 4 +- EvernoteToNotionChrome/MainWindow.xaml.cs | 15 + EvernoteToNotionChrome/Service/HtmlManager.cs | 59 ++- .../Service/UploadManager.cs | 26 + EvernoteToNotionChrome/Utils/HRESULT.cs | 107 ++++ .../Utils/StringExtensions.cs | 134 +++++ EvernoteToNotionChrome/Utils/Win32Api.cs | 459 ++++++++++++++++++ EvernoteToNotionChrome/Utils/Win32Drap.cs | 45 ++ 17 files changed, 937 insertions(+), 17 deletions(-) create mode 100644 ChromeTest/App.xaml create mode 100644 ChromeTest/App.xaml.cs create mode 100644 ChromeTest/AssemblyInfo.cs create mode 100644 ChromeTest/ChromeTest.csproj create mode 100644 ChromeTest/MainWindow.xaml create mode 100644 ChromeTest/MainWindow.xaml.cs create mode 100644 EvernoteToNotionChrome/Utils/HRESULT.cs create mode 100644 EvernoteToNotionChrome/Utils/StringExtensions.cs create mode 100644 EvernoteToNotionChrome/Utils/Win32Api.cs create mode 100644 EvernoteToNotionChrome/Utils/Win32Drap.cs diff --git a/ChromeTest/App.xaml b/ChromeTest/App.xaml new file mode 100644 index 0000000..a73cdd8 --- /dev/null +++ b/ChromeTest/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/ChromeTest/App.xaml.cs b/ChromeTest/App.xaml.cs new file mode 100644 index 0000000..d916a3a --- /dev/null +++ b/ChromeTest/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace ChromeTest +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/ChromeTest/AssemblyInfo.cs b/ChromeTest/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/ChromeTest/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/ChromeTest/ChromeTest.csproj b/ChromeTest/ChromeTest.csproj new file mode 100644 index 0000000..25e6a50 --- /dev/null +++ b/ChromeTest/ChromeTest.csproj @@ -0,0 +1,13 @@ + + + + WinExe + net5.0-windows + true + + + + + + + diff --git a/ChromeTest/MainWindow.xaml b/ChromeTest/MainWindow.xaml new file mode 100644 index 0000000..023bdfb --- /dev/null +++ b/ChromeTest/MainWindow.xaml @@ -0,0 +1,12 @@ + + + + + diff --git a/ChromeTest/MainWindow.xaml.cs b/ChromeTest/MainWindow.xaml.cs new file mode 100644 index 0000000..5fc9b18 --- /dev/null +++ b/ChromeTest/MainWindow.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace ChromeTest +{ + /// + /// Interaction logic for MainWindow.xaml + /// + public partial class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + } +} diff --git a/EvernoteToNotionChrome.sln b/EvernoteToNotionChrome.sln index 706949d..2d85625 100644 --- a/EvernoteToNotionChrome.sln +++ b/EvernoteToNotionChrome.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EvernoteToNotionChrome", "E EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EvernoteToNotion", "EvernoteToNotion\EvernoteToNotion.csproj", "{B31F147A-02D1-4300-A67F-65C0DB7EC1F2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChromeTest", "ChromeTest\ChromeTest.csproj", "{376D4A9F-6AA8-4A6E-B038-5DC33F7AC6A9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {B31F147A-02D1-4300-A67F-65C0DB7EC1F2}.Debug|Any CPU.Build.0 = Debug|Any CPU {B31F147A-02D1-4300-A67F-65C0DB7EC1F2}.Release|Any CPU.ActiveCfg = Release|Any CPU {B31F147A-02D1-4300-A67F-65C0DB7EC1F2}.Release|Any CPU.Build.0 = Release|Any CPU + {376D4A9F-6AA8-4A6E-B038-5DC33F7AC6A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {376D4A9F-6AA8-4A6E-B038-5DC33F7AC6A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {376D4A9F-6AA8-4A6E-B038-5DC33F7AC6A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {376D4A9F-6AA8-4A6E-B038-5DC33F7AC6A9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/EvernoteToNotionChrome/App.xaml.cs b/EvernoteToNotionChrome/App.xaml.cs index bf9d9d8..d0056c9 100644 --- a/EvernoteToNotionChrome/App.xaml.cs +++ b/EvernoteToNotionChrome/App.xaml.cs @@ -66,9 +66,9 @@ private static void InitializeCefSharp() // Set BrowserSubProcessPath based on app bitness at runtime - setting.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, - Environment.Is64BitProcess ? "x64" : "x86", - "CefSharp.BrowserSubprocess.exe"); + //setting.BrowserSubprocessPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, + // Environment.Is64BitProcess ? "x64" : "x86", + // "CefSharp.BrowserSubprocess.exe"); if (!Cef.Initialize(setting, performDependencyCheck: false, browserProcessHandler: null)) { diff --git a/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj b/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj index 564d339..f9d1f4d 100644 --- a/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj +++ b/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj @@ -20,9 +20,7 @@ AnyCPU - - 86.0.241 - + diff --git a/EvernoteToNotionChrome/MainWindow.xaml b/EvernoteToNotionChrome/MainWindow.xaml index 24f18eb..14bb2fa 100644 --- a/EvernoteToNotionChrome/MainWindow.xaml +++ b/EvernoteToNotionChrome/MainWindow.xaml @@ -21,11 +21,13 @@ - + + + diff --git a/EvernoteToNotionChrome/MainWindow.xaml.cs b/EvernoteToNotionChrome/MainWindow.xaml.cs index f728d59..b2a9185 100644 --- a/EvernoteToNotionChrome/MainWindow.xaml.cs +++ b/EvernoteToNotionChrome/MainWindow.xaml.cs @@ -1,4 +1,5 @@ using CefSharp; +using CefSharp.Internals; using EvernoteToNotionChrome.Service; using EvernoteToNotionChrome.Utils; using MahApps.Metro.Controls; @@ -22,6 +23,9 @@ using System.Windows.Navigation; using System.Windows.Shapes; + + + namespace EvernoteToNotionChrome { /// @@ -42,6 +46,8 @@ public MainWindow() browserSettings.JavascriptAccessClipboard = CefSharp.CefState.Enabled; browserSettings.JavascriptDomPaste = CefSharp.CefState.Enabled; Browser.BrowserSettings = browserSettings; + + } private void Window_Loaded(object sender, RoutedEventArgs e) @@ -52,6 +58,8 @@ private void Window_Loaded(object sender, RoutedEventArgs e) Browser.RequestHandler = new OxoRequestHandler(); Browser.Address = "https://notion.so/"; + + var screenInfo = ((IRenderWebBrowser)Browser).GetScreenInfo(); GlobalNotification.Default.Register(GlobalNotification.NotificationOutputLogInfo, this, (msg) => { Debug.WriteLine(msg.Source); @@ -74,6 +82,13 @@ await Task.Run(() => { ButtonStart.IsEnabled = true; } + private async void ButtonTest_Click(object sender, RoutedEventArgs e) + { + await UploadManager.UploadFile(@"C:\Users\aiqin\Documents\Tencent Files\76835052\FileRecv\tinified (5).zip"); + } + + + private void Browser_Loaded(object sender, RoutedEventArgs e) { diff --git a/EvernoteToNotionChrome/Service/HtmlManager.cs b/EvernoteToNotionChrome/Service/HtmlManager.cs index 7c212a6..f501a5e 100644 --- a/EvernoteToNotionChrome/Service/HtmlManager.cs +++ b/EvernoteToNotionChrome/Service/HtmlManager.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; + namespace EvernoteToNotionChrome.Service { public class HtmlManager @@ -35,6 +37,9 @@ public static void UploadHtmlData(string filePath) List imageList = new List(); + List fileList = new List(); + + //处理img标签 var nodes = doc.DocumentNode.SelectNodes("//img"); if (nodes == null) @@ -55,19 +60,57 @@ public static void UploadHtmlData(string filePath) GlobalNotification.Default.Post(GlobalNotification.NotificationOutputLogInfo, $"处理IMAGE标签:{src.Value}" ); - if (!src.Value.Contains("en_todo")) + if (link.ParentNode.Name == "a") + { + Debug.WriteLine("上级node是a标签,文件类型,不按照图片处理"); + HtmlNode parentNode = link.ParentNode; + string href = parentNode.Attributes["href"].Value; //文件路径 + fileList.Add(href); + } + else if (!src.Value.Contains("en_todo")) { + //读取图片尺寸并替换到image标签,让notion识别宽高 + var fullFilePath = path + @"\" + src.Value.Replace(@"/", @"\"); + Size imageSize = GetImageSize(fullFilePath); + link.SetAttributeValue("style", $"width: {imageSize.Width}px; height: {imageSize.Height}px;"); + + //如果上级是a标签,则不处理,后续按照a标签处理 imageList.Add(src.Value); } else { ConversionTodoList(link, path, src.Value); - } } - //读取图片,上传 - var docString = doc.DocumentNode.OuterHtml; + //上传所有图片并替换到html文件中 + var docString = UploadAllImage(imageList, path, doc.DocumentNode.OuterHtml); + + docString = UploadAllImage(fileList, path, docString); + + + Debug.WriteLine(doc.DocumentNode.OuterHtml); + + File.WriteAllText(savePath, doc.DocumentNode.OuterHtml); + + } + + static Size GetImageSize(string path) + { + Image image = Bitmap.FromFile(path); + return image.Size; + } + + + /// + /// 上传 + /// + /// + /// + /// + private static string UploadAllImage(List imageList, string path, string doc) + { + var docString = doc; foreach (string file in imageList) { if (file.StartsWith("file:") || file.StartsWith("http:") || file.StartsWith("https:")) @@ -93,16 +136,12 @@ public static void UploadHtmlData(string filePath) } } - - Debug.WriteLine(docString); - - File.WriteAllText(savePath, docString); - + return docString; } - static void ConversionTodoList(HtmlNode node, string basePath, string path) + private static void ConversionTodoList(HtmlNode node, string basePath, string path) { var parentNode = node.ParentNode; diff --git a/EvernoteToNotionChrome/Service/UploadManager.cs b/EvernoteToNotionChrome/Service/UploadManager.cs index 7f4573e..b35212d 100644 --- a/EvernoteToNotionChrome/Service/UploadManager.cs +++ b/EvernoteToNotionChrome/Service/UploadManager.cs @@ -1,17 +1,23 @@ using CefSharp; +using CefSharp.Internals; +using EvernoteToNotionChrome.Utils; using System; using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; +using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; namespace EvernoteToNotionChrome.Service { + public class UploadManager { public static bool IsUploading { set; get; } @@ -31,8 +37,28 @@ public static async Task UploadFile(string filePath) Clipboard.SetImage(bSource); MainWindow.SingleInstance.Browser.Paste(); } + catch (NotSupportedException ex) + { + //filePath不是图片 + Debug.WriteLine(ex); + StringCollection list = new (); + list.Add(filePath); + Debug.WriteLine("设置文件到剪贴板"); + //Clipboard.SetFileDropList(list); + //MainWindow.SingleInstance.Browser.Paste(); + //Core.DragData.Create() + //IDragData dragData = DragData.Create(); + //dragData.FileName = filePath; + //dragData.IsFile = true; + + //MainWindow.SingleInstance.Browser.GetBrowserHost().GetWindowHandle() + Win32Drap.SendFileDrop(new WindowInteropHelper(MainWindow.SingleInstance).Handle, filePath, 550, 400); + + //((IRenderWebBrowser)MainWindow.SingleInstance.Browser).StartDragging(dragData, CefSharp.Enums.DragOperationsMask.Move, 550, 400); + } catch (System.Exception ex) { + Debug.WriteLine(ex); hasError = true; } }); diff --git a/EvernoteToNotionChrome/Utils/HRESULT.cs b/EvernoteToNotionChrome/Utils/HRESULT.cs new file mode 100644 index 0000000..961d3f9 --- /dev/null +++ b/EvernoteToNotionChrome/Utils/HRESULT.cs @@ -0,0 +1,107 @@ +using System; +using System.Runtime.InteropServices; +// ReSharper disable InconsistentNaming + +namespace EvernoteToNotionChrome.Utils +{ + /// Wrapper for HRESULT status codes. + [StructLayout(LayoutKind.Explicit)] + public readonly struct HRESULT + { + [FieldOffset(0)] + readonly uint _value; + + // NOTE: These public static field declarations are automatically + // picked up by ToString through reflection. + /// S_OK + public static readonly HRESULT S_OK = new HRESULT(0x00000000); + /// S_FALSE + public static readonly HRESULT S_FALSE = new HRESULT(0x00000001); + /// E_NOTIMPL + public static readonly HRESULT E_NOTIMPL = new HRESULT(0x80004001); + /// E_NOINTERFACE + public static readonly HRESULT E_NOINTERFACE = new HRESULT(0x80004002); + /// E_POINTER + public static readonly HRESULT E_POINTER = new HRESULT(0x80004003); + /// E_ABORT + public static readonly HRESULT E_ABORT = new HRESULT(0x80004004); + /// E_FAIL + public static readonly HRESULT E_FAIL = new HRESULT(0x80004005); + /// E_UNEXPECTED + public static readonly HRESULT E_UNEXPECTED = new HRESULT(0x8000FFFF); + /// DISP_E_MEMBERNOTFOUND + public static readonly HRESULT DISP_E_MEMBERNOTFOUND = new HRESULT(0x80020003); + /// DISP_E_TYPEMISMATCH + public static readonly HRESULT DISP_E_TYPEMISMATCH = new HRESULT(0x80020005); + /// DISP_E_UNKNOWNNAME + public static readonly HRESULT DISP_E_UNKNOWNNAME = new HRESULT(0x80020006); + /// DISP_E_EXCEPTION + public static readonly HRESULT DISP_E_EXCEPTION = new HRESULT(0x80020009); + /// DISP_E_OVERFLOW + public static readonly HRESULT DISP_E_OVERFLOW = new HRESULT(0x8002000A); + /// DISP_E_BADINDEX + public static readonly HRESULT DISP_E_BADINDEX = new HRESULT(0x8002000B); + /// DISP_E_BADPARAMCOUNT + public static readonly HRESULT DISP_E_BADPARAMCOUNT = new HRESULT(0x8002000E); + /// DISP_E_PARAMNOTOPTIONAL + public static readonly HRESULT DISP_E_PARAMNOTOPTIONAL = new HRESULT(0x8002000F); + /// SCRIPT_E_REPORTED + public static readonly HRESULT SCRIPT_E_REPORTED = new HRESULT(0x80020101); + /// STG_E_INVALIDFUNCTION + public static readonly HRESULT STG_E_INVALIDFUNCTION = new HRESULT(0x80030001); + /// DESTS_E_NO_MATCHING_ASSOC_HANDLER. + /// + /// Win7 error code for Jump Lists. There is no associated handler for the given item registered by the specified application. + /// + public static readonly HRESULT DESTS_E_NO_MATCHING_ASSOC_HANDLER = new HRESULT(0x80040F03); + /// E_ACCESSDENIED + public static readonly HRESULT E_ACCESSDENIED = new HRESULT(0x80070005); + /// E_OUTOFMEMORY + public static readonly HRESULT E_OUTOFMEMORY = new HRESULT(0x8007000E); + /// E_INVALIDARG + public static readonly HRESULT E_INVALIDARG = new HRESULT(0x80070057); + /// COR_E_OBJECTDISPOSED + public static readonly HRESULT COR_E_OBJECTDISPOSED = new HRESULT(0x80131622); + /// WC_E_GREATERTHAN + public static readonly HRESULT WC_E_GREATERTHAN = new HRESULT(0xC00CEE23); + /// WC_E_SYNTAX + public static readonly HRESULT WC_E_SYNTAX = new HRESULT(0xC00CEE2D); + + //-------------------------------------------------------------------------------------------------- + + public HRESULT(uint i) + { + _value = i; + } + + //-------------------------------------------------------------------------------------------------- + + public override bool Equals(object obj) + { + try + { + return ((HRESULT)obj)._value == _value; + } + catch (InvalidCastException) + { + return false; + } + } + + public override int GetHashCode() + { + return _value.GetHashCode(); + } + public static bool operator ==(HRESULT errLeft, HRESULT errRight) + { + return errLeft._value == errRight._value; + } + + public static bool operator !=(HRESULT errLeft, HRESULT errRight) + { + return !(errLeft == errRight); + } + + //-------------------------------------------------------------------------------------------------- + } +} \ No newline at end of file diff --git a/EvernoteToNotionChrome/Utils/StringExtensions.cs b/EvernoteToNotionChrome/Utils/StringExtensions.cs new file mode 100644 index 0000000..6001530 --- /dev/null +++ b/EvernoteToNotionChrome/Utils/StringExtensions.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace EvernoteToNotionChrome.Utils +{ + public static class StringExtensions + { + public static string ToMixedCase(this string value) + { + if (string.IsNullOrEmpty(value)) return value; + + var len = value.Length; + var newValue = new char[len]; + var ToUpperCase = true; + + for (var i = 0; i < len; ++i) + { + var c0 = value[i]; + if (!Char.IsLetter(c0)) + { + newValue[i] = c0; + ToUpperCase = true; + continue; + } + + var c0isUpper = Char.IsUpper(c0); + if (c0isUpper && !ToUpperCase) + { + c0 = Char.ToLower(c0); + } + else if (!c0isUpper && ToUpperCase) + { + c0 = Char.ToUpper(c0); + } + + newValue[i] = c0; + ToUpperCase = false; + } + + return new string(newValue); + } + + //-------------------------------------------------------------------------------------------------- + + public static bool IsNullOrWhiteSpace(this string value) + { + return String.IsNullOrWhiteSpace(value); + } + + //-------------------------------------------------------------------------------------------------- + + public static bool IsEmpty(this string value) + { + return String.IsNullOrEmpty(value); + } + + //-------------------------------------------------------------------------------------------------- + + public static bool IsNullOrEmpty(this string value) + { + return String.IsNullOrEmpty(value); + } + + //-------------------------------------------------------------------------------------------------- + + public static string FromUtf8Bytes(this byte[] bytes) + { + return bytes == null ? null + : Encoding.UTF8.GetString(bytes, 0, bytes.Length); + } + + //-------------------------------------------------------------------------------------------------- + + public static byte[] ToUtf8Bytes(this string value) + { + return Encoding.UTF8.GetBytes(value); + } + + //-------------------------------------------------------------------------------------------------- + + public static int CompareIgnoreCase(this string strA, string strB) + { + return String.Compare(strA, strB, StringComparison.InvariantCultureIgnoreCase); + } + + //-------------------------------------------------------------------------------------------------- + + public static string Join(this List parts, string separator) + { + return String.Join(separator, parts.ToArray()); + } + + //-------------------------------------------------------------------------------------------------- + + public static string TrimPrefixes(this string fromString, params string[] prefixes) + { + if (string.IsNullOrEmpty(fromString)) + return fromString; + + foreach (var prefix in prefixes) + { + if (fromString.StartsWith(prefix)) + return fromString.Substring(prefix.Length); + } + + return fromString; + } + + //-------------------------------------------------------------------------------------------------- + + public static string ToIdentifier(this string fromString) + { + string toString = ""; + for (int i = 0; i < fromString.Length; i++) + { + char c = fromString[i]; + + if (char.IsLetter(c) + || char.IsDigit(c) && toString.Length > 0 + || c == '_') + { + toString += c; + } + } + + return toString.IsNullOrEmpty() ? "_" : toString; + } + } +} \ No newline at end of file diff --git a/EvernoteToNotionChrome/Utils/Win32Api.cs b/EvernoteToNotionChrome/Utils/Win32Api.cs new file mode 100644 index 0000000..9099d90 --- /dev/null +++ b/EvernoteToNotionChrome/Utils/Win32Api.cs @@ -0,0 +1,459 @@ +// ReSharper disable InconsistentNaming + +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace EvernoteToNotionChrome.Utils +{ + public static class Win32Api + { + #region Constants + + public const int + CS_OWNDC = 0x0020; + + //-------------------------------------------------------------------------------------------------- + + public const uint + WS_DISABLED = 0x08000000, + WS_VISIBLE = 0x10000000, + WS_CHILD = 0x40000000, + WS_POPUP = 0x80000000; + + //-------------------------------------------------------------------------------------------------- + + public const int + SW_SHOWNORMAL = 1, + SW_SHOWMINIMIZED = 2; + + //-------------------------------------------------------------------------------------------------- + + public const int + WM_SETFOCUS = 0x0007, + WM_PAINT = 0x000f, + WM_ENABLE = 0x000a, + WM_SHOWWINDOW = 0x0018, + WM_KEYDOWN = 0x0100, + WM_MOUSEMOVE = 0x0200, + WM_LBUTTONDOWN = 0x0201, + WM_LBUTTONUP = 0x0202, + WM_RBUTTONDOWN = 0x0204, + WM_RBUTTONUP = 0x0205, + WM_MBUTTONDOWN = 0x0207, + WM_MBUTTONUP = 0x0208, + WM_MOUSEWHEEL = 0x020a, + WM_MOUSELEAVE = 0x02a3, + WM_NCHITTEST = 0x0084, + WM_DROPFILES = 0x0233; + + //-------------------------------------------------------------------------------------------------- + + public const int + HTNOWHERE = 0, + HTTRANSPARENT = -1; + + //-------------------------------------------------------------------------------------------------- + + public const int + GMEM_FIXED = 0x0000, + GMEM_SHARE = 0x2000, + GWL_WNDPROC = -4, + GWL_HWNDPARENT = -8, + GWL_STYLE = -16, + GWL_EXSTYLE = -20, + GWL_ID = -12; + + + //-------------------------------------------------------------------------------------------------- + + [Flags] + public enum RedrawWindowFlags : uint + { + Invalidate = 0x1, + InternalPaint = 0x2, + Erase = 0x4, + Validate = 0x8, + NoInternalPaint = 0x10, + NoErase = 0x20, + NoChildren = 0x40, + AllChildren = 0x80, + UpdateNow = 0x100, + EraseNow = 0x200, + Frame = 0x400, + NoFrame = 0x800 + } + + //-------------------------------------------------------------------------------------------------- + + [Flags] + public enum MINIDUMP_TYPE : uint + { + MiniDumpNormal = 0x00000000, + MiniDumpWithDataSegs = 0x00000001, + MiniDumpWithFullMemory = 0x00000002, + MiniDumpWithHandleData = 0x00000004, + MiniDumpFilterMemory = 0x00000008, + MiniDumpScanMemory = 0x00000010, + MiniDumpWithUnloadedModules = 0x00000020, + MiniDumpWithIndirectlyReferencedMemory = 0x00000040, + MiniDumpFilterModulePaths = 0x00000080, + MiniDumpWithProcessThreadData = 0x00000100, + MiniDumpWithPrivateReadWriteMemory = 0x00000200, + MiniDumpWithoutOptionalData = 0x00000400, + MiniDumpWithFullMemoryInfo = 0x00000800, + MiniDumpWithThreadInfo = 0x00001000, + MiniDumpWithCodeSegs = 0x00002000, + MiniDumpWithoutManagedState = 0x00004000, + }; + + //-------------------------------------------------------------------------------------------------- + + public const uint SECURITY_DESCRIPTOR_REVISION = 1; + + //-------------------------------------------------------------------------------------------------- + + /// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/synchronization_object_security_and_access_rights.asp + [Flags] + public enum SyncObjectAccess : uint + { + DELETE = 0x00010000, + READ_CONTROL = 0x00020000, + WRITE_DAC = 0x00040000, + WRITE_OWNER = 0x00080000, + SYNCHRONIZE = 0x00100000, + EVENT_ALL_ACCESS = 0x001F0003, + EVENT_MODIFY_STATE = 0x00000002, + MUTEX_ALL_ACCESS = 0x001F0001, + MUTEX_MODIFY_STATE = 0x00000001, + SEMAPHORE_ALL_ACCESS = 0x001F0003, + SEMAPHORE_MODIFY_STATE = 0x00000002, + TIMER_ALL_ACCESS = 0x001F0003, + TIMER_MODIFY_STATE = 0x00000002, + TIMER_QUERY_STATE = 0x00000001 + } + + //-------------------------------------------------------------------------------------------------- + + [Flags] + public enum HtmlHelpCommand : uint + { + HH_DISPLAY_TOPIC = 0, + HH_DISPLAY_TOC = 1, + HH_DISPLAY_INDEX = 2, + HH_DISPLAY_SEARCH = 3, + HH_DISPLAY_TEXT_POPUP = 0x000E, + HH_HELP_CONTEXT = 0x000F, + HH_CLOSE_ALL = 0x0012 + } + + //-------------------------------------------------------------------------------------------------- + + [Flags] + public enum Stgm : uint + { + STGM_READ = 0x0, + STGM_WRITE = 0x1, + STGM_READWRITE = 0x2, + STGM_SHARE_DENY_NONE = 0x40, + STGM_SHARE_DENY_READ = 0x30, + STGM_SHARE_DENY_WRITE = 0x20, + STGM_SHARE_EXCLUSIVE = 0x10, + STGM_PRIORITY = 0x40000, + STGM_CREATE = 0x1000, + STGM_CONVERT = 0x20000, + STGM_FAILIFTHERE = 0x0, + STGM_DIRECT = 0x0, + STGM_TRANSACTED = 0x10000, + STGM_NOSCRATCH = 0x100000, + STGM_NOSNAPSHOT = 0x200000, + STGM_SIMPLE = 0x8000000, + STGM_DIRECT_SWMR = 0x400000, + STGM_DELETEONRELEASE = 0x4000000 + } + + //-------------------------------------------------------------------------------------------------- + + public enum MapVirtualKeyMapTypes + { + MAPVK_VK_TO_VSC = 0x00, + MAPVK_VSC_TO_VK = 0x01, + MAPVK_VK_TO_CHAR = 0x02, + MAPVK_VSC_TO_VK_EX = 0x03, + MAPVK_VK_TO_VSC_EX = 0x04 + } + + //-------------------------------------------------------------------------------------------------- + + #endregion + + #region Structures + + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int x; + public int y; + + public POINT(int x, int y) + { + this.x = x; + this.y = y; + } + } + + //-------------------------------------------------------------------------------------------------- + + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + + public RECT(int left, int top, int right, int bottom) + { + Left = left; + Top = top; + Right = right; + Bottom = bottom; + } + } + + //-------------------------------------------------------------------------------------------------- + + [StructLayout(LayoutKind.Sequential)] + public struct WINDOWPLACEMENT + { + public int length; + public int flags; + public int showCmd; + public POINT minPosition; + public POINT maxPosition; + public RECT normalPosition; + } + + //-------------------------------------------------------------------------------------------------- + + [StructLayout(LayoutKind.Sequential)] + public struct DROPFILES + { + public int pFiles; + public POINT pt; + public bool fNC; + public bool fWide; + } + + //-------------------------------------------------------------------------------------------------- + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct MINIDUMP_EXCEPTION_INFORMATION + { + public uint ThreadId; + public IntPtr ExceptionPointers; + public int ClientPointers; + } + + //-------------------------------------------------------------------------------------------------- + + [StructLayout(LayoutKind.Sequential)] + public struct SECURITY_DESCRIPTOR + { + public byte revision; + public byte size; + public short control; + public IntPtr owner; + public IntPtr group; + public IntPtr sacl; + public IntPtr dacl; + } + + //-------------------------------------------------------------------------------------------------- + + [StructLayout(LayoutKind.Sequential)] + public struct SECURITY_ATTRIBUTES + { + public int nLength; + public IntPtr lpSecurityDescriptor; + public bool bInheritHandle; + } + + //-------------------------------------------------------------------------------------------------- + + #endregion + + #region Methods + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr GlobalLock(IntPtr Handle); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern int GlobalUnlock(IntPtr Handle); + + [DllImport("kernel32.dll")] + public static extern IntPtr GetCurrentProcess(); + + [DllImport("kernel32.dll")] + public static extern uint GetCurrentProcessId(); + + [DllImport("kernel32.dll")] + public static extern uint GetCurrentThreadId(); + + [DllImport("kernel32.dll")] + public static extern IntPtr CreateMutex(ref SECURITY_ATTRIBUTES lpMutexAttributes, bool bInitialOwner, string lpName); + + [DllImport("kernel32.dll")] + public static extern IntPtr OpenMutex(uint dwDesiredAccess, bool bInheritHandle, string lpName); + + [DllImport("kernel32.dll")] + public static extern bool ReleaseMutex(IntPtr hMutex); + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPWStr)] string lpFileName); + + [DllImport("kernel32.dll")] + public static extern bool FreeLibrary(IntPtr hLibModule); + + [DllImport("kernel32.dll", CharSet = CharSet.Ansi)] + public static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string lpProcName); + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + public static extern bool SetDllDirectory(string lpPathName); + + //-------------------------------------------------------------------------------------------------- + + [DllImport("user32.dll")] + public static extern bool EnableWindow(HandleRef hWnd, bool bEnable); + + //SetWindowLong won't work correctly for 64-bit: we should use SetWindowLongPtr instead. On + //32-bit, SetWindowLongPtr is just #defined as SetWindowLong. SetWindowLong really should + //take/return int instead of IntPtr/HandleRef, but since we're running this only for 32-bit + //it'll be OK. + public static IntPtr SetWindowLong(HandleRef hWnd, int nIndex, HandleRef dwNewLong) + { + if (IntPtr.Size == 4) + { + return SetWindowLongPtr32(hWnd, nIndex, dwNewLong); + } + return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); + } + + [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SetWindowLong")] + public static extern IntPtr SetWindowLongPtr32(HandleRef hWnd, int nIndex, HandleRef dwNewLong); + + [DllImport("user32.dll", CharSet = CharSet.Auto, EntryPoint = "SetWindowLongPtr")] + public static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, HandleRef dwNewLong); + + [DllImport("user32.dll")] + public static extern IntPtr SetParent(HandleRef hWnd, HandleRef hWndParent); + + [DllImport("user32.dll")] + public static extern bool GetWindowPlacement(HandleRef hWnd, out WINDOWPLACEMENT lpwndpl); + + [DllImport("user32.dll")] + public static extern bool SetWindowPlacement(HandleRef hWnd, [In] ref WINDOWPLACEMENT lpwndpl); + + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + public static extern bool SetForegroundWindow(HandleRef hWnd); + + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr SetFocus(HandleRef hWnd); + + [DllImport("user32.dll", SetLastError = true)] + public static extern int SetWindowRgn(HandleRef hWnd, IntPtr hRgn, bool bRedraw); + + [DllImport("user32.dll")] + public static extern bool InvalidateRect(HandleRef hWnd, IntPtr lpRect, bool bErase); + + [DllImport("user32.dll")] + public static extern bool UpdateWindow(HandleRef hWnd); + + [DllImport("user32.dll")] + public static extern bool RedrawWindow(HandleRef hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll")] + public static extern uint MapVirtualKey(uint uCode, MapVirtualKeyMapTypes uMapType); + + [DllImport("user32.dll")] + public static extern uint MapVirtualKeyEx(uint uCode, MapVirtualKeyMapTypes uMapType, IntPtr dwhkl); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + public static extern short VkKeyScan(char ch); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + public static extern short VkKeyScanEx(char ch, IntPtr dwhkl); + + [DllImport("user32.dll")] + public static extern int ToAscii(uint uVirtKey, uint uScanCode, byte[] lpKeyState, [Out] StringBuilder lpChar, uint uFlags); + + [DllImport("user32.dll")] + public static extern int ToAsciiEx(uint uVirtKey, uint uScanCode, byte[] lpKeyState, [Out] StringBuilder lpChar, uint uFlags, IntPtr hkl); + + [DllImport("user32.dll")] + public static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, + int cchBuff, uint wFlags); + + [DllImport("user32.dll")] + public static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)] StringBuilder pwszBuff, + int cchBuff, uint wFlags, IntPtr dwhkl); + + [DllImport("user32.dll")] + public static extern bool GetKeyboardState(byte[] lpKeyState); + + //-------------------------------------------------------------------------------------------------- + + [DllImport("gdi32.dll", SetLastError = true)] + public static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); + + //-------------------------------------------------------------------------------------------------- + + [DllImport("shell32.dll")] + public static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept); + + [DllImport("shell32.dll")] + public static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out] StringBuilder filename, uint cch); + + [DllImport("shell32.dll")] + public static extern void DragFinish(IntPtr hDrop); + + [DllImport("shell32.dll", PreserveSig = false)] + public static extern void SetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] string AppID); + + [DllImport("shell32.dll")] + public static extern HRESULT GetCurrentProcessExplicitAppUserModelID([MarshalAs(UnmanagedType.LPWStr)] out string AppID); + + //-------------------------------------------------------------------------------------------------- + + [DllImport("advapi32.dll", SetLastError = true)] + public static extern bool InitializeSecurityDescriptor(out SECURITY_DESCRIPTOR SecurityDescriptor, uint dwRevision); + + [DllImport("advapi32.dll", SetLastError = true)] + public static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool daclPresent, IntPtr dacl, bool daclDefaulted); + + //-------------------------------------------------------------------------------------------------- + + [DllImport("dbghelp.dll")] + public static extern bool MiniDumpWriteDump(IntPtr hProcess, uint ProcessId, IntPtr hFile, MINIDUMP_TYPE DumpType, + ref MINIDUMP_EXCEPTION_INFORMATION ExceptionParam, IntPtr UserStreamParam, IntPtr CallackParam); + + //-------------------------------------------------------------------------------------------------- + + [DllImport("hhctrl.ocx", CharSet = CharSet.Auto)] + public static extern int HtmlHelp(HandleRef hwndCaller, [MarshalAs(UnmanagedType.LPTStr)] string pszFile, HtmlHelpCommand uCommand, string dwData); + + //-------------------------------------------------------------------------------------------------- + + [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)] + public static extern void SHCreateStreamOnFileEx(string fileName, Stgm grfmode, uint dwAttributes, bool fCreate, + System.Runtime.InteropServices.ComTypes.IStream streamNull, ref System.Runtime.InteropServices.ComTypes.IStream stream); + + #endregion + } +} \ No newline at end of file diff --git a/EvernoteToNotionChrome/Utils/Win32Drap.cs b/EvernoteToNotionChrome/Utils/Win32Drap.cs new file mode 100644 index 0000000..c8033e1 --- /dev/null +++ b/EvernoteToNotionChrome/Utils/Win32Drap.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Input; + +namespace EvernoteToNotionChrome.Utils +{ + public class Win32Drap + { + public static bool SendFileDrop(IntPtr hwnd,string path, int x, int y) + { + //var point = Window.BoundingRectangle.Center(); + //Mouse.Position = point; + + var dropfiles = new Win32Api.DROPFILES(); + var sizeOfDropfiles = Marshal.SizeOf(); + dropfiles.pFiles = sizeOfDropfiles; + dropfiles.pt.x = x;//(int)point.X; + dropfiles.pt.y = y;// (int)point.Y; + dropfiles.fNC = true; + dropfiles.fWide = false; + + var hmem = Marshal.AllocHGlobal(sizeOfDropfiles + path.Length + 2); + var hmemPtr = Win32Api.GlobalLock(hmem); + var ptr = hmemPtr; + + Marshal.StructureToPtr(dropfiles, ptr, false); + ptr += sizeOfDropfiles; + var pathBytes = path.ToUtf8Bytes(); + Marshal.Copy(pathBytes, 0, ptr, pathBytes.Length); + ptr += path.Length; + Marshal.WriteInt16(ptr, 0); // double 0 to terminate file list + Win32Api.GlobalUnlock(hmemPtr); + + var success = Win32Api.PostMessage(hwnd, Win32Api.WM_DROPFILES, hmem, IntPtr.Zero); + if (!success) + Marshal.FreeHGlobal(hmem); + return success; + } + } +} From bff45ca16ea7d5459f15534eb7c59b0aed62b973 Mon Sep 17 00:00:00 2001 From: aiqinxuancai Date: Thu, 18 Nov 2021 14:25:07 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=AD=A3notion=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E7=9A=84=E6=97=A0=E6=B3=95=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=20=E4=BF=AE=E6=AD=A3=E9=83=A8=E5=88=86=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E6=AD=A3=E7=A1=AE=E8=AF=BB=E5=8F=96=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EvernoteToNotionChrome.csproj | 1 + EvernoteToNotionChrome/MainWindow.xaml | 59 +- EvernoteToNotionChrome/MainWindow.xaml.cs | 10 +- EvernoteToNotionChrome/Service/HtmlManager.cs | 123 +++- .../Service/UploadManager.cs | 51 +- EvernoteToNotionChrome/Style/AQButton.xaml | 565 ++++++++++++++++++ 6 files changed, 752 insertions(+), 57 deletions(-) create mode 100644 EvernoteToNotionChrome/Style/AQButton.xaml diff --git a/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj b/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj index f9d1f4d..976741c 100644 --- a/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj +++ b/EvernoteToNotionChrome/EvernoteToNotionChrome.csproj @@ -26,6 +26,7 @@ 12.0.3 + \ No newline at end of file diff --git a/EvernoteToNotionChrome/MainWindow.xaml b/EvernoteToNotionChrome/MainWindow.xaml index 14bb2fa..a2d4c81 100644 --- a/EvernoteToNotionChrome/MainWindow.xaml +++ b/EvernoteToNotionChrome/MainWindow.xaml @@ -6,32 +6,61 @@ xmlns:local="clr-namespace:EvernoteToNotionChrome" xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf" xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" mc:Ignorable="d" - Title="EvernoteToNotionChrome" Height="720" Width="1080" Loaded="Window_Loaded" AllowDrop="True"> + Title="EvernoteToNotionChrome" Height="720" Width="1080" Loaded="Window_Loaded" AllowDrop="True" + x:Name="Self"> + + + + + + + + + + + + - + + - + - - - - - - - - - - - + + + + + + + - + + + + + + + + + + + + + + diff --git a/EvernoteToNotionChrome/MainWindow.xaml.cs b/EvernoteToNotionChrome/MainWindow.xaml.cs index b2a9185..7d4e85d 100644 --- a/EvernoteToNotionChrome/MainWindow.xaml.cs +++ b/EvernoteToNotionChrome/MainWindow.xaml.cs @@ -33,13 +33,19 @@ namespace EvernoteToNotionChrome /// public partial class MainWindow : MetroWindow { - public static MainWindow SingleInstance { set; get; } + public static MainWindow Instance { set; get; } + + public bool Overwrite { set; get; } = false; public MainWindow() { - SingleInstance = this; + Instance = this; + + InitializeComponent(); + OverwriteCheckBox.DataContext = this; + BrowserSettings browserSettings = new BrowserSettings(); browserSettings.Javascript = CefSharp.CefState.Enabled; diff --git a/EvernoteToNotionChrome/Service/HtmlManager.cs b/EvernoteToNotionChrome/Service/HtmlManager.cs index f501a5e..1b40d48 100644 --- a/EvernoteToNotionChrome/Service/HtmlManager.cs +++ b/EvernoteToNotionChrome/Service/HtmlManager.cs @@ -23,33 +23,52 @@ public static void UploadHtmlData(string filePath) var path = Path.GetDirectoryName(filePath); var savePath = path + @"\Replace\" + Path.GetFileName(filePath); - if (File.Exists(savePath)) + if (!MainWindow.Instance.Overwrite && File.Exists(savePath)) { //已经存在 不继续处理 return; } - if (!Directory.Exists(path + @"\Replace\")) { Directory.CreateDirectory(path + @"\Replace\"); } - List imageList = new List(); - - List fileList = new List(); - //处理img标签 var nodes = doc.DocumentNode.SelectNodes("//img"); - if (nodes == null) { File.WriteAllText(path + @"\Replace\" + Path.GetFileName(filePath), File.ReadAllText(filePath)); return; } - + GlobalNotification.Default.Post(GlobalNotification.NotificationOutputLogInfo, $"处理HTML:{filePath}"); + Debug.WriteLine($"开始路径{filePath}"); + Debug.WriteLine($"找到图片{nodes.Count}个"); + + List imageList = GetDocAllImageLabel(path, nodes); + List fileList = GetDocAllFileLabel(nodes); + FixTodoListNode(path, nodes); + + //上传所有图片并替换到html文件中 + var docString = UploadAllImage(imageList, path, doc.DocumentNode.OuterHtml); + + //a标签判定为文件类型,不上传 + //docString = UploadAllImage(fileList, path, docString); + + File.WriteAllText(savePath, docString); + + } + + /// + /// 获取全部 + /// + /// + /// + private static List GetDocAllImageLabel(string path, HtmlNodeCollection nodes) + { + List imageList = new List(); foreach (HtmlNode link in nodes) { HtmlAttribute src = link.Attributes["src"]; @@ -58,16 +77,15 @@ public static void UploadHtmlData(string filePath) continue; } - GlobalNotification.Default.Post(GlobalNotification.NotificationOutputLogInfo, $"处理IMAGE标签:{src.Value}" ); - - if (link.ParentNode.Name == "a") + if (link.ParentNode.Name == "a") //上级node是a标签,文件类型,不按照图片处理; { - Debug.WriteLine("上级node是a标签,文件类型,不按照图片处理"); - HtmlNode parentNode = link.ParentNode; - string href = parentNode.Attributes["href"].Value; //文件路径 - fileList.Add(href); + continue; } - else if (!src.Value.Contains("en_todo")) + else if (src.Value.Contains("en_todo")) + { + continue; + } + else { //读取图片尺寸并替换到image标签,让notion识别宽高 var fullFilePath = path + @"\" + src.Value.Replace(@"/", @"\"); @@ -77,22 +95,60 @@ public static void UploadHtmlData(string filePath) //如果上级是a标签,则不处理,后续按照a标签处理 imageList.Add(src.Value); } - else - { - ConversionTodoList(link, path, src.Value); - } } + return imageList; + } - //上传所有图片并替换到html文件中 - var docString = UploadAllImage(imageList, path, doc.DocumentNode.OuterHtml); - - docString = UploadAllImage(fileList, path, docString); - + /// + /// 获取全部文件 + /// + /// + /// + private static List GetDocAllFileLabel(HtmlNodeCollection nodes) + { + List fileList = new List(); + foreach (HtmlNode link in nodes) + { + HtmlAttribute src = link.Attributes["src"]; + if (src == null) + { + continue; + } - Debug.WriteLine(doc.DocumentNode.OuterHtml); + if (link.ParentNode.Name == "a") //上级node是a标签,文件类型,不按照图片处理; + { + HtmlNode parentNode = link.ParentNode; + string href = parentNode.Attributes["href"].Value; //文件路径 + fileList.Add(href); + } + } + return fileList; + } - File.WriteAllText(savePath, doc.DocumentNode.OuterHtml); + /// + /// 修复todolist + /// + /// + /// + private static void FixTodoListNode(string path, HtmlNodeCollection nodes) + { + foreach (HtmlNode link in nodes) + { + HtmlAttribute src = link.Attributes["src"]; + if (src == null) + { + continue; + } + if (link.ParentNode.Name == "a") + { + continue; + } + else if (src.Value.Contains("en_todo")) + { + ConversionTodoList(link, path, src.Value); + } + } } static Size GetImageSize(string path) @@ -127,12 +183,20 @@ private static string UploadAllImage(List imageList, string path, string { continue; //失败 } - result = result.Substring(0, result.IndexOf("?Content-Type=")); - Debug.WriteLine(docString); + //result = result.Substring(0, result.IndexOf("?Content-Type=")); + var index = result.IndexOf("?Content-Type="); + if (index == -1) + { + index = result.IndexOf("?X-Amz"); + } + + result = result.Substring(0, index); + Debug.WriteLine("最后上传地址:" + result); //替换 if (!string.IsNullOrEmpty(result)) { docString = docString.Replace(file, result); + Debug.WriteLine("替换地址:" + file + " -> " + result); } } @@ -143,7 +207,6 @@ private static string UploadAllImage(List imageList, string path, string private static void ConversionTodoList(HtmlNode node, string basePath, string path) { - var parentNode = node.ParentNode; var fullFilePath = basePath + @"\" + path.Replace(@"/", @"\"); node.ParentNode.RemoveChild(node, false); //<-- keepGrandChildren diff --git a/EvernoteToNotionChrome/Service/UploadManager.cs b/EvernoteToNotionChrome/Service/UploadManager.cs index b35212d..9339afb 100644 --- a/EvernoteToNotionChrome/Service/UploadManager.cs +++ b/EvernoteToNotionChrome/Service/UploadManager.cs @@ -5,15 +5,18 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; -using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; -using System.Windows.Interop; -using System.Windows.Media; + +using System.Numerics; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; using System.Windows.Media.Imaging; +using System.IO; namespace EvernoteToNotionChrome.Service { @@ -30,29 +33,39 @@ public static async Task UploadFile(string filePath) LastUploadFileUrl = ""; bool hasError = false; - MainWindow.SingleInstance.Dispatcher.Invoke(() => { + + Debug.WriteLine($"开始上传{filePath}"); + + MainWindow.Instance.Dispatcher.Invoke(() => { try { - BitmapSource bSource = new BitmapImage(new Uri(filePath)); - Clipboard.SetImage(bSource); - MainWindow.SingleInstance.Browser.Paste(); + using (Image image =Image.Load(filePath)) //使用imagesharp减少错误 + { + MemoryStream memoryStream = new MemoryStream(); + image.SaveAsPng(memoryStream); + BitmapSource bSource = BitmapToBitmapImage(new System.Drawing.Bitmap(memoryStream)); + Clipboard.SetImage(bSource); + MainWindow.Instance.Browser.Paste(); + } } catch (NotSupportedException ex) { //filePath不是图片 - Debug.WriteLine(ex); + //Debug.WriteLine(ex); + Debug.WriteLine("此文件不是图片"); StringCollection list = new (); list.Add(filePath); - Debug.WriteLine("设置文件到剪贴板"); + //Clipboard.SetFileDropList(list); //MainWindow.SingleInstance.Browser.Paste(); + //Core.DragData.Create() //IDragData dragData = DragData.Create(); //dragData.FileName = filePath; //dragData.IsFile = true; //MainWindow.SingleInstance.Browser.GetBrowserHost().GetWindowHandle() - Win32Drap.SendFileDrop(new WindowInteropHelper(MainWindow.SingleInstance).Handle, filePath, 550, 400); + //Win32Drap.SendFileDrop(new WindowInteropHelper(MainWindow.SingleInstance).Handle, filePath, 550, 400); //((IRenderWebBrowser)MainWindow.SingleInstance.Browser).StartDragging(dragData, CefSharp.Enums.DragOperationsMask.Move, 550, 400); } @@ -82,6 +95,24 @@ await Task.Run(() => return LastUploadFileUrl; } + // Bitmap --> BitmapImage + public static BitmapImage BitmapToBitmapImage(System.Drawing.Bitmap bitmap) + { + using (MemoryStream stream = new MemoryStream()) + { + bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png); + stream.Position = 0; + BitmapImage result = new BitmapImage(); + result.BeginInit(); + // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed." + // Force the bitmap to load right now so we can dispose the stream. + result.CacheOption = BitmapCacheOption.OnLoad; + result.StreamSource = stream; + result.EndInit(); + result.Freeze(); + return result; + } + } public static void PutSuccess(string url) { diff --git a/EvernoteToNotionChrome/Style/AQButton.xaml b/EvernoteToNotionChrome/Style/AQButton.xaml new file mode 100644 index 0000000..af9a42f --- /dev/null +++ b/EvernoteToNotionChrome/Style/AQButton.xaml @@ -0,0 +1,565 @@ + + + #EEFFFFFF + #00000000 + #FF2d8cf0 + + + + + + + #EE17233d + + + + + #FF2d8cf0 + #C82d8cf0 + #DC2d8cf0 + #662d8cf0 + + + + + + + + + + + + + #FFE6E6E6 + #C8E6E6E6 + #DCCCCCCC + #66E6E6E6 + + + + + + + + + + + + #FFed4014 + #C8ed4014 + #DCed4014 + #66ed4014 + + + + + + + + + + + #FF19be6b + #C819be6b + #DC19be6b + #6619be6b + + + + + + + + + + + #FFff9900 + #C8ff9900 + #DCff9900 + #66ff9900 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file