Justin 1 жил өмнө
parent
commit
6d087eefbb

+ 3 - 1
StationProbe/Database.cs

@@ -8,7 +8,9 @@ namespace StationProbe
 
         public Database()
         {
-            _db = new SQLiteConnection("d:\\database.db");
+            var drives = DriveInfo.GetDrives();
+            var largestDriver = drives.OrderByDescending(x=>x.TotalFreeSpace).First();
+            _db = new SQLiteConnection($"{largestDriver.Name}database.db");
             _db.CreateTable<Image>();
             _db.CreateTable<Exam>();
             _db.CreateTable<BatchTask>();

+ 92 - 0
StationProbe/DingTalk.cs

@@ -0,0 +1,92 @@
+using System.Text;
+using System.Text.Json.Serialization;
+
+namespace StationProbe
+{
+    internal class DingTalk
+    {
+        internal class AcceccTokenResult
+        {
+            [JsonPropertyName("errcode")]
+            public int ErrorCode { get; set; }
+
+            [JsonPropertyName("errmsg")]
+            public string ErrorMsg { get; set; } = string.Empty;
+
+            [JsonPropertyName("access_token")]
+            public string AccessToken { get; set; } = string.Empty;
+
+            [JsonPropertyName("expires_in")]
+            public int ExpiresIn {  get; set; }
+        }
+
+        internal class MessageResult
+        {
+            [JsonPropertyName("errcode")]
+            public int ErrorCode { get; set; }
+
+            [JsonPropertyName("errmsg")]
+            public string ErrorMsg { get; set; } = string.Empty;
+
+            [JsonPropertyName("task_id")]
+            public int TaskId {  get; set; }
+
+            [JsonPropertyName("request_id")]
+            public string RequestId { get; set; } = string.Empty;
+        }
+
+        private readonly static HttpClient _client;
+
+        static DingTalk()
+        {
+            _client = new HttpClient();
+        }
+
+        public static async Task SendMessageAsync(string msg)
+        {
+            var response = await _client.GetAsync("https://oapi.dingtalk.com/gettoken?appkey=dinglvrfy5p9zq79ojaj&appsecret=7Tcy-xRj8m3jVM9cNZo62XlbFaxfONgRE0LKImUrka4DgEOt16RN9TJh9cZR63Vl");
+            var contentStream = await response.Content.ReadAsStreamAsync();
+            var tokenResult = System.Text.Json.JsonSerializer.Deserialize<AcceccTokenResult>(contentStream);
+            if (tokenResult != null)
+            {
+                if (tokenResult.ErrorCode == 0)
+                {
+                    var text = new Dictionary<string, object>();
+                    text["content"] = msg;
+
+                    var message = new Dictionary<string, object>();
+                    message["msgtype"] = "text";
+                    message["text"] = text;
+
+                    var args = new Dictionary<string, object>();
+                    args["agent_id"] = "1485668405";
+                    args["userid_list"] = "1403411622464238794";
+                    args["msg"] = message;
+
+                    await using (var ms = new MemoryStream())
+                    {
+                        await System.Text.Json.JsonSerializer.SerializeAsync(ms, args);
+                        var data = ms.ToArray();
+                        var str = Encoding.UTF8.GetString(data);
+                        var content = new StringContent(str, Encoding.UTF8);
+                        var url = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=" + tokenResult.AccessToken;
+                        response = await _client.PostAsync(url, content);
+                        contentStream = await response.Content.ReadAsStreamAsync();
+                        var messageResult = System.Text.Json.JsonSerializer.Deserialize<MessageResult>(contentStream);
+                        if(messageResult != null)
+                        {
+                            if(messageResult.ErrorCode != 0)
+                            {
+                                throw new InvalidOperationException(messageResult.ErrorMsg);
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    throw new InvalidOperationException(tokenResult.ErrorMsg);
+                }
+            }       
+        }
+    }
+}

+ 145 - 25
StationProbe/ProbeTask.cs

@@ -1,11 +1,4 @@
 using PuppeteerSharp;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Xml.Linq;
 
 namespace StationProbe
 {
@@ -38,11 +31,45 @@ namespace StationProbe
 
     internal abstract class ProbeTask
     {
+        private static string _debugFolder = string.Empty;
         protected readonly Database _db;
+
+        protected ScreenshotOptions _snapshotOpts = new ScreenshotOptions() {Type = ScreenshotType.Jpeg };
+        public static bool DebugMode { get; set; }
+
+
         public ProbeTask(Database db)
         {
             _db = db;
         }
+
+        public static void InitDebugFolder()
+        {
+            var drives = DriveInfo.GetDrives();
+            var largestDriver = drives.OrderByDescending(x => x.TotalFreeSpace).First();
+            var debugFolder = largestDriver.Name + "debug";
+            if (!Directory.Exists(debugFolder))
+            {
+                Directory.CreateDirectory(debugFolder);
+            }
+            var i = 1;
+            while (Directory.Exists(Path.Combine(debugFolder, i.ToString("D6"))))
+            {
+                i++;
+            }
+            _debugFolder = Path.Combine(debugFolder, i.ToString("D6"));
+            Directory.CreateDirectory(_debugFolder);
+        }
+
+        public void SaveDebugSnapshot(string name, byte[] imageData)
+        {
+            if (Directory.Exists(_debugFolder))
+            {
+                var file = Path.Combine(_debugFolder, name);
+                File.WriteAllBytes(file, imageData);
+            }
+        }
+
         public abstract Task<ElementCollection> ExecuteAsync(ElementCollection inputs);
     }
 
@@ -57,24 +84,55 @@ namespace StationProbe
 
         public override async Task<ElementCollection> ExecuteAsync(ElementCollection inputs)
         {
-            var input = inputs[ElementType.Page].As<IPage>();
-            if (input != null)
+            var page = inputs[ElementType.Page].As<IPage>();
+            if (page != null)
             {
-                await input.GoToAsync(_loginUrl);
+                await page.GoToAsync(_loginUrl);
+                await page.WaitForNetworkIdleAsync();
+
+                if(DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "100000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+
                 //username
-                await input.WaitForSelectorAsync("input[_bl_13]");
-                await input.FocusAsync("input[_bl_13]");
-                await input.Keyboard.TypeAsync("justin.xing");
+                await page.WaitForSelectorAsync("input[_bl_13]");
+                await page.FocusAsync("input[_bl_13]");
+                await page.Keyboard.TypeAsync("justin.xing");
+
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "200000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+
                 //password
-                await input.WaitForSelectorAsync("input[_bl_14]");
-                await input.FocusAsync("input[_bl_14]");
-                await input.Keyboard.TypeAsync("123456");
+                await page.WaitForSelectorAsync("input[_bl_14]");
+                await page.FocusAsync("input[_bl_14]");
+                await page.Keyboard.TypeAsync("123456");
+
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "300000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+
                 //login
-                var button = await input.WaitForSelectorAsync("button[_bl_15]");
+                var button = await page.WaitForSelectorAsync("button[_bl_15]");
                 await button.ClickAsync();
+                await page.WaitForNavigationAsync();
+                await page.WaitForNetworkIdleAsync();
 
-                await input.WaitForNavigationAsync();
-                await input.WaitForNetworkIdleAsync();
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "400000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
             }
             return inputs;
         }
@@ -89,11 +147,18 @@ namespace StationProbe
         public override async Task<ElementCollection> ExecuteAsync(ElementCollection inputs)
         {
             Logger.WriteLine("Finding menu...");
-            var input = inputs[ElementType.Page].As<IPage>();
-            if (input != null)
+            var page = inputs[ElementType.Page].As<IPage>();
+            if (page != null)
             {
-                var frame = await input.WaitForFrameAsync("");
+                var frame = await page.WaitForFrameAsync("");
                 inputs.AddObject(ElementType.Frame, frame);
+
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "500000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
             }
             return inputs;
         }
@@ -120,9 +185,40 @@ namespace StationProbe
             var frame = inputs[ElementType.Frame].As<IFrame>();
             if(page!= null && frame != null) 
             {
+                //show filter dialog
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "600000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+
+                //input start
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "700000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+
+                //input end
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "800000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+
                 await frame.WaitForSelectorAsync("input[_bl_13]");
                 await frame.FocusAsync("input[_bl_13]");
                 await page.Keyboard.TypeAsync("justin.xing");
+
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "900000000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
             }
             return inputs;
         }
@@ -138,7 +234,17 @@ namespace StationProbe
 
         public override async Task<ElementCollection> ExecuteAsync(ElementCollection inputs)
         {
-           
+            var page = inputs[ElementType.Page].As<IPage>();
+            var frame = inputs[ElementType.Frame].As<IFrame>();
+            if (page != null && frame != null)
+            {
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "9" + _page.ToString("D5") +"000.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+            }
             return inputs;
         }
     }
@@ -163,9 +269,17 @@ namespace StationProbe
             var page = inputs[ElementType.Page].As<IPage>();
             var frame = inputs[ElementType.Frame].As<IFrame>();
             if (page != null && frame != null)
-            {
+            {   //Enter exam
+
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "9" + _pageIndex.ToString("D5") + _examIndexInPage.ToString("D3") +".jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
+
                 var exmaId = Guid.NewGuid().ToString("N");
-                //Enter exam
+                
                 //Get patient info
                 var patientName = "";
                 var patientSex = "";
@@ -210,6 +324,12 @@ namespace StationProbe
                 _db.AddExam(exam);
                 //Back to page.
                 await page.GoBackAsync();
+                if (DebugMode)
+                {
+                    var imageData = await page.ScreenshotDataAsync(_snapshotOpts);
+                    var fileName = "9" + _pageIndex.ToString("D5") + "999.jpg";
+                    SaveDebugSnapshot(fileName, imageData);
+                }
             }
             return inputs;
         }

+ 21 - 15
StationProbe/Program.cs

@@ -2,6 +2,7 @@
 using PuppeteerSharp;
 using StationProbe;
 
+
 if (args.Length == 0)
 {
     Console.WriteLine("Use one of 'create','run','list' commands to start this application.");
@@ -37,29 +38,34 @@ else
             {
                 try
                 {
-                    await using (var browser = (Browser)await Puppeteer.LaunchAsync(new LaunchOptions
+                    ProbeTask.InitDebugFolder();
+                    await using var browser = (Browser)await Puppeteer.LaunchAsync(new LaunchOptions
                     {
                         Headless = true
-                    }))
+                    });
+                    await using var page = await browser.NewPageAsync();
+                    await page.SetViewportAsync(new ViewPortOptions
                     {
-                        await using (var page = await browser.NewPageAsync())
-                        {
-                            await page.SetViewportAsync(new ViewPortOptions
-                            {
-                                Width = 1920,
-                                Height = 1080
-                            });
-                            var superImageTask = new SuperImageTask(batchTask, 15);
-                            await superImageTask.RunAsync(page);
-                            error = false;
-                        }
-
-                    }
+                        Width = 1920,
+                        Height = 1080
+                    });
+                    var superImageTask = new SuperImageTask(batchTask, 15);
+                    await superImageTask.RunAsync(page);
+                    error = false;
                 }
                 catch (Exception ex)
                 {
                     Logger.WriteLine($"Run super image task error:{ex}");
                     error = true;
+                    try
+                    {
+                        await DingTalk.SendMessageAsync($"Run super image task error, will restart in 10s.");
+                    }
+                    catch(Exception dx)
+                    {
+                        Logger.WriteLine($"Send dingtalk message error:{dx.Message}");
+                    }
+                    await Task.Delay(10000);
                 }
             }
         }

+ 18 - 1
StationProbe/SuperImageTask.cs

@@ -33,6 +33,7 @@ namespace StationProbe
                 Logger.WriteLine($"Run LoginTask failed:{ex}");
                 throw;
             }
+            await Task.Delay(1000);
             Logger.WriteLine("Start menu task...");
             try
             {
@@ -43,6 +44,7 @@ namespace StationProbe
                 Logger.WriteLine($"Run MenuTask failed:{ex}");
                 throw;
             }
+            await Task.Delay(1000);
             Logger.WriteLine($"Start filter task(start:{_batchTask.Start:yyyy-MM-dd}, end:{_batchTask.End:yyyy-MM-dd})...");
             try
             {
@@ -62,7 +64,7 @@ namespace StationProbe
                 Logger.WriteLine($"Run FilterTask failed:{ex}");
                 throw;
             }
-
+            await Task.Delay(1000);
             var lastExam = _db.GetLastExam(_batchTask.Id);
             if (lastExam != null)
             {
@@ -76,6 +78,7 @@ namespace StationProbe
                 }
             }
             Logger.WriteLine($"Start from page: {_pageIndex}, exam index: {_examIndexInPage}");
+            int processedExams = 0;
             while (_pageIndex < _batchTask.PageCount)
             {
                 Logger.WriteLine($"Start page task (page:{_pageIndex})");
@@ -90,6 +93,20 @@ namespace StationProbe
                         try
                         {
                             outputs = await new ExamTask(_db,_batchTask.Id, _pageIndex, _examIndex ,_examIndexInPage).ExecuteAsync(outputs);
+                            processedExams++;
+                            if(processedExams % 150 == 0)
+                            {
+                                //Notify per 10 pages.
+                                try
+                                {
+                                    await DingTalk.SendMessageAsync($"{processedExams} exams processed.");
+                                }
+                                catch (Exception dx)
+                                {
+                                    Logger.WriteLine($"Send dingtalk message error:{dx.Message}");
+                                }
+                            }
+                            await Task.Delay(1000);
                         }
                         catch (Exception ex)
                         {