From 2290f1b3403640025cbf2522f83f53b5913470c9 Mon Sep 17 00:00:00 2001 From: Sergey Chebotar Date: Thu, 11 Nov 2021 21:13:21 +0300 Subject: [PATCH 01/10] =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B0=D1=81=D0=B8=D0=BD=D1=85=D1=80?= =?UTF-8?q?=D0=BE=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BC=D0=B5=D1=82=D0=BE?= =?UTF-8?q?=D0=B4=D0=B0=20=D1=84=D0=BE=D1=80=D0=BC=D1=83=D0=BB=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Functions.cs | 9 +++++++-- SkuAssist.cs | 33 ++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Functions.cs b/Functions.cs index 999a942..576e03c 100644 --- a/Functions.cs +++ b/Functions.cs @@ -5,10 +5,15 @@ namespace Rehau.Sku.Assist public class Functions : IExcelAddIn { [ExcelFunction(description: "Получение наименования и артикула позиции")] - public static string RAUNAME(string request) + public static object RAUNAME(string request) { SkuAssist.EnsureHttpInitialized(); - return SkuAssist.GetSku(request); + + return ExcelTaskUtil.Run("RAUNAME ASYNC", request, async token => + { + var document = await SkuAssist.GetDocumentAsync(request); + return SkuAssist.GetResultFromDocument(document); + }); } public void AutoClose() diff --git a/SkuAssist.cs b/SkuAssist.cs index b873104..1c0be3b 100644 --- a/SkuAssist.cs +++ b/SkuAssist.cs @@ -18,38 +18,33 @@ namespace Rehau.Sku.Assist } } - public static string GetSku(string request) + public async static Task GetDocumentAsync(string request) { string url = "https://shop-rehau.ru/catalogsearch/result/?q=" + request; - HttpResponseMessage response = GetResponse(url).Result; - var document = GetDocument(response).Result; - var name = document - .All - .Where(e => e.ClassName == "product-item__desc-top") - .Select(e => new { sku = e.Children[0].TextContent, name = e.Children[1].TextContent.Trim(new[] { '\n', ' ' }) }) - .Where(t => !t.sku.Any(c => char.IsLetter(c))) - .FirstOrDefault(); - - return name == null ? "Не найдено" : $"{name.name} ({name.sku})"; - } - - private static async Task GetResponse(string url) - { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; HttpResponseMessage response = await _httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); - return response; - } - private static async Task GetDocument(HttpResponseMessage response) - { + IConfiguration config = Configuration.Default; IBrowsingContext context = BrowsingContext.New(config); string source = await response.Content.ReadAsStringAsync(); return await context.OpenAsync(req => req.Content(source)); } + + public static string GetResultFromDocument(AngleSharp.Dom.IDocument document) + { + var result = document + .All + .Where(e => e.ClassName == "product-item__desc-top") + .Select(e => new { sku = e.Children[0].TextContent, title = e.Children[1].TextContent.Trim(new[] { '\n', ' ' }) }) + .Where(t => !t.sku.Any(c => char.IsLetter(c))) + .FirstOrDefault(); + + return result == null ? "Не найдено" : $"{result.title} ({result.sku})"; + } } } From f5234e956c79d3019e975a4d3550574c92f769e7 Mon Sep 17 00:00:00 2001 From: Sergey Chebotar Date: Sun, 14 Nov 2021 12:27:49 +0300 Subject: [PATCH 02/10] Edit ASync method. Delete unnecessary classes --- SkuAssist.cs => Assistant/SkuAssist.cs | 17 +--- CancellationDisposable.cs | 38 ------- DefaultDisposable.cs | 21 ---- ExcelTaskUtil.cs | 133 ------------------------- Functions.cs | 12 +-- Rehau.Sku.Assist.csproj | 5 +- 6 files changed, 9 insertions(+), 217 deletions(-) rename SkuAssist.cs => Assistant/SkuAssist.cs (76%) delete mode 100644 CancellationDisposable.cs delete mode 100644 DefaultDisposable.cs delete mode 100644 ExcelTaskUtil.cs diff --git a/SkuAssist.cs b/Assistant/SkuAssist.cs similarity index 76% rename from SkuAssist.cs rename to Assistant/SkuAssist.cs index 1c0be3b..1167274 100644 --- a/SkuAssist.cs +++ b/Assistant/SkuAssist.cs @@ -8,25 +8,14 @@ namespace Rehau.Sku.Assist { static class SkuAssist { - static private HttpClient _httpClient; - - public static void EnsureHttpInitialized() + public async static Task GetDocumentAsync(string request, HttpClient httpClient) { - if (_httpClient == null) - { - _httpClient = new HttpClient(); - } - } - - public async static Task GetDocumentAsync(string request) - { - string url = "https://shop-rehau.ru/catalogsearch/result/?q=" + request; + string uri = "https://shop-rehau.ru/catalogsearch/result/?q=" + request; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; - HttpResponseMessage response = await _httpClient.GetAsync(url); + HttpResponseMessage response = await httpClient.GetAsync(uri); response.EnsureSuccessStatusCode(); - IConfiguration config = Configuration.Default; IBrowsingContext context = BrowsingContext.New(config); diff --git a/CancellationDisposable.cs b/CancellationDisposable.cs deleted file mode 100644 index 700a2c2..0000000 --- a/CancellationDisposable.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Threading; - -namespace Rehau.Sku.Assist -{ - sealed class CancellationDisposable : IDisposable - { - - readonly CancellationTokenSource cts; - public CancellationDisposable(CancellationTokenSource cts) - { - if (cts == null) - { - throw new ArgumentNullException("cts"); - } - - this.cts = cts; - } - - public CancellationDisposable() - : this(new CancellationTokenSource()) - { - } - - public CancellationToken Token - { - get { return cts.Token; } - } - - public void Dispose() - { - cts.Cancel(); - } - } - -} - - diff --git a/DefaultDisposable.cs b/DefaultDisposable.cs deleted file mode 100644 index f991181..0000000 --- a/DefaultDisposable.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace Rehau.Sku.Assist -{ - sealed class DefaultDisposable : IDisposable - { - - public static readonly DefaultDisposable Instance = new DefaultDisposable(); - - DefaultDisposable() - { - } - - public void Dispose() - { - } - } - -} - - diff --git a/ExcelTaskUtil.cs b/ExcelTaskUtil.cs deleted file mode 100644 index c7d1b94..0000000 --- a/ExcelTaskUtil.cs +++ /dev/null @@ -1,133 +0,0 @@ -using ExcelDna.Integration; -using System.Threading.Tasks; -using System; -using System.Threading; - -namespace Rehau.Sku.Assist -{ - internal static class ExcelTaskUtil - { - public static object Run(string callerFunctionName, object callerParameters, Func> taskSource) - { - return ExcelAsyncUtil.Observe(callerFunctionName, callerParameters, delegate - { - var cts = new CancellationTokenSource(); - var task = taskSource(cts.Token); - return new ExcelTaskObservable(task, cts); - }); - } - - public static object Run(string callerFunctionName, object callerParameters, Func> taskSource) - { - return ExcelAsyncUtil.Observe(callerFunctionName, callerParameters, delegate - { - var task = taskSource(); - return new ExcelTaskObservable(task); - }); - } - - class ExcelTaskObservable : IExcelObservable - { - readonly Task _task; - readonly CancellationTokenSource _cts; - public ExcelTaskObservable(Task task) - { - _task = task; - } - - public ExcelTaskObservable(Task task, CancellationTokenSource cts) - : this(task) - { - _cts = cts; - } - - public IDisposable Subscribe(IExcelObserver observer) - { - switch (_task.Status) - { - case TaskStatus.RanToCompletion: - observer.OnNext(_task.Result); - observer.OnCompleted(); - break; - case TaskStatus.Faulted: - observer.OnError(_task.Exception.InnerException); - break; - case TaskStatus.Canceled: - observer.OnError(new TaskCanceledException(_task)); - break; - default: - _task.ContinueWith(t => - { - switch (t.Status) - { - case TaskStatus.RanToCompletion: - observer.OnNext(t.Result); - observer.OnCompleted(); - break; - case TaskStatus.Faulted: - observer.OnError(t.Exception.InnerException); - break; - case TaskStatus.Canceled: - observer.OnError(new TaskCanceledException(t)); - break; - } - }); - break; - } - - if (_cts != null) - { - return new CancellationDisposable(_cts); - } - - return DefaultDisposable.Instance; - } - } - - sealed class DefaultDisposable : IDisposable - { - - public static readonly DefaultDisposable Instance = new DefaultDisposable(); - - DefaultDisposable() - { - } - - public void Dispose() - { - } - } - - sealed class CancellationDisposable : IDisposable - { - - readonly CancellationTokenSource cts; - public CancellationDisposable(CancellationTokenSource cts) - { - if (cts == null) - { - throw new ArgumentNullException("cts"); - } - - this.cts = cts; - } - - public CancellationDisposable() - : this(new CancellationTokenSource()) - { - } - - public CancellationToken Token - { - get { return cts.Token; } - } - - public void Dispose() - { - cts.Cancel(); - } - } - - } -} - diff --git a/Functions.cs b/Functions.cs index 576e03c..aefdd87 100644 --- a/Functions.cs +++ b/Functions.cs @@ -1,25 +1,23 @@ using ExcelDna.Integration; +using System.Net.Http; namespace Rehau.Sku.Assist { public class Functions : IExcelAddIn { - [ExcelFunction(description: "Получение наименования и артикула позиции")] + static readonly HttpClient httpClient = new HttpClient(); + public static object RAUNAME(string request) { - SkuAssist.EnsureHttpInitialized(); - - return ExcelTaskUtil.Run("RAUNAME ASYNC", request, async token => + return ExcelAsyncUtil.Run("RAUNAME", request, delegate { - var document = await SkuAssist.GetDocumentAsync(request); + var document = SkuAssist.GetDocumentAsync(request, httpClient).Result; return SkuAssist.GetResultFromDocument(document); }); } public void AutoClose() { - ExcelIntegration.RegisterUnhandledExceptionHandler( - delegate (object ex) { return string.Format("!!!ERROR: {0}", ex.ToString()); }); } public void AutoOpen() diff --git a/Rehau.Sku.Assist.csproj b/Rehau.Sku.Assist.csproj index 37744c7..2fc2307 100644 --- a/Rehau.Sku.Assist.csproj +++ b/Rehau.Sku.Assist.csproj @@ -58,12 +58,9 @@ - - - - + From 0fe8e038af7f33eae824bba263e7c54dea829679 Mon Sep 17 00:00:00 2001 From: Sergey Chebotar Date: Mon, 29 Nov 2021 11:26:25 +0300 Subject: [PATCH 03/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=BA=D1=8D=D1=88=D0=B8=D0=BD=D0=B3=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0,=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=20IProduct?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assistant/IProduct.cs | 9 ++++++++ Assistant/Product.cs | 21 ++++++++++++++++++ Assistant/SkuAssist.cs | 16 ++++++-------- Functions.cs | 48 +++++++++++++++++++++++++++++++---------- Rehau.Sku.Assist.csproj | 23 ++++++++++++++++++++ packages.config | 5 +++++ 6 files changed, 102 insertions(+), 20 deletions(-) create mode 100644 Assistant/IProduct.cs create mode 100644 Assistant/Product.cs diff --git a/Assistant/IProduct.cs b/Assistant/IProduct.cs new file mode 100644 index 0000000..aca3ff5 --- /dev/null +++ b/Assistant/IProduct.cs @@ -0,0 +1,9 @@ +namespace Rehau.Sku.Assist +{ + interface IProduct + { + string Sku { get; } + string Name { get; } + string Uri { get; } + } +} diff --git a/Assistant/Product.cs b/Assistant/Product.cs new file mode 100644 index 0000000..17a7065 --- /dev/null +++ b/Assistant/Product.cs @@ -0,0 +1,21 @@ +namespace Rehau.Sku.Assist +{ + public class Product : IProduct + { + public string Sku { get; } + public string Name { get; } + + public string Uri => throw new System.NotImplementedException(); + + public Product(string sku, string name) + { + Sku = sku; + Name = name; + } + + public override string ToString() + { + return $"{this.Name} ({this.Sku})"; + } + } +} \ No newline at end of file diff --git a/Assistant/SkuAssist.cs b/Assistant/SkuAssist.cs index 1167274..9eb3328 100644 --- a/Assistant/SkuAssist.cs +++ b/Assistant/SkuAssist.cs @@ -1,8 +1,8 @@ -using System.Net.Http; -using System.Threading.Tasks; -using AngleSharp; +using AngleSharp; using System.Linq; using System.Net; +using System.Net.Http; +using System.Threading.Tasks; namespace Rehau.Sku.Assist { @@ -23,16 +23,14 @@ namespace Rehau.Sku.Assist return await context.OpenAsync(req => req.Content(source)); } - public static string GetResultFromDocument(AngleSharp.Dom.IDocument document) + public static IProduct GetProductFromDocument(AngleSharp.Dom.IDocument document) { - var result = document + return document .All .Where(e => e.ClassName == "product-item__desc-top") - .Select(e => new { sku = e.Children[0].TextContent, title = e.Children[1].TextContent.Trim(new[] { '\n', ' ' }) }) - .Where(t => !t.sku.Any(c => char.IsLetter(c))) + .Select(e => new Product(e.Children[0].TextContent, e.Children[1].TextContent.Trim(new[] { '\n', ' ' }))) + // .Where(product => !product.Sku.Any(c => char.IsLetter(c))) .FirstOrDefault(); - - return result == null ? "Не найдено" : $"{result.title} ({result.sku})"; } } } diff --git a/Functions.cs b/Functions.cs index aefdd87..9d3eb28 100644 --- a/Functions.cs +++ b/Functions.cs @@ -1,27 +1,53 @@ using ExcelDna.Integration; +using System.Runtime.Caching; using System.Net.Http; namespace Rehau.Sku.Assist { public class Functions : IExcelAddIn { - static readonly HttpClient httpClient = new HttpClient(); - - public static object RAUNAME(string request) - { - return ExcelAsyncUtil.Run("RAUNAME", request, delegate - { - var document = SkuAssist.GetDocumentAsync(request, httpClient).Result; - return SkuAssist.GetResultFromDocument(document); - }); - } + private static HttpClient _httpClient; + private static ObjectCache _resultCache = MemoryCache.Default; public void AutoClose() { } - public void AutoOpen() { + _httpClient = new HttpClient(); + } + + [ExcelFunction] + public static object RAUNAME(string request) + { + string cachedResult = _resultCache[request] as string; + + if (cachedResult != null) + { + return cachedResult; + } + + else + { + object result = ExcelAsyncUtil.Run("RAUNAME", null, + delegate + { + var document = SkuAssist.GetDocumentAsync(request, _httpClient).Result; + var product = SkuAssist.GetProductFromDocument(document); + return product.ToString(); + }); + + if (result.Equals(ExcelError.ExcelErrorNA)) + { + return "Загрузка..."; + } + + else + { + _resultCache.Add(request, result, System.DateTime.Now.AddMinutes(20)); + return result.ToString(); + } + } } } } \ No newline at end of file diff --git a/Rehau.Sku.Assist.csproj b/Rehau.Sku.Assist.csproj index 2fc2307..29cdb12 100644 --- a/Rehau.Sku.Assist.csproj +++ b/Rehau.Sku.Assist.csproj @@ -38,26 +38,49 @@ packages\ExcelDna.Integration.1.5.0\lib\net452\ExcelDna.Integration.dll + False packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + packages\System.Configuration.ConfigurationManager.6.0.0\lib\net461\System.Configuration.ConfigurationManager.dll + + + + packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + + packages\System.Security.AccessControl.6.0.0\lib\net461\System.Security.AccessControl.dll + + + packages\System.Security.Permissions.6.0.0\lib\net461\System.Security.Permissions.dll + + + packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll + + packages\System.Text.Encoding.CodePages.5.0.0\lib\net461\System.Text.Encoding.CodePages.dll + + + + diff --git a/packages.config b/packages.config index 07a90ac..840c4e8 100644 --- a/packages.config +++ b/packages.config @@ -4,6 +4,11 @@ + + + + + \ No newline at end of file From 3eb118d6db672eb8e27f2b2478b0688141782654 Mon Sep 17 00:00:00 2001 From: Sergey Chebotar Date: Mon, 29 Nov 2021 15:50:24 +0300 Subject: [PATCH 04/10] Async/await ready solution init commit --- AddIn.cs | 24 ++++++++++++++ Assistant/SkuAssist.cs | 65 ++++++++++++++++++++------------------ Functions.cs | 49 ++++------------------------ Rehau.Sku.Assist-AddIn.dna | 2 +- Rehau.Sku.Assist.csproj | 31 ++++-------------- app.config | 15 +++++++++ packages.config | 14 ++------ 7 files changed, 91 insertions(+), 109 deletions(-) create mode 100644 AddIn.cs create mode 100644 app.config diff --git a/AddIn.cs b/AddIn.cs new file mode 100644 index 0000000..dd99667 --- /dev/null +++ b/AddIn.cs @@ -0,0 +1,24 @@ +using ExcelDna.Integration; +using ExcelDna.Registration; + +namespace Rehau.Sku.Assist +{ + public class AddIn : IExcelAddIn + { + public void AutoOpen() + { + RegisterFunctions(); + } + + public void AutoClose() + { + } + + void RegisterFunctions() + { + ExcelRegistration.GetExcelFunctions() + .ProcessAsyncRegistrations(nativeAsyncIfAvailable: false) + .RegisterFunctions(); + } + } +} diff --git a/Assistant/SkuAssist.cs b/Assistant/SkuAssist.cs index 9eb3328..d390a1d 100644 --- a/Assistant/SkuAssist.cs +++ b/Assistant/SkuAssist.cs @@ -1,38 +1,41 @@ -using AngleSharp; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Threading.Tasks; +//using System; +//using AngleSharp; +//using AngleSharp.Dom; +//using System.Linq; +//using System.Net; +//using System.Net.Http; +//using System.Threading.Tasks; -namespace Rehau.Sku.Assist -{ - static class SkuAssist - { - public async static Task GetDocumentAsync(string request, HttpClient httpClient) - { - string uri = "https://shop-rehau.ru/catalogsearch/result/?q=" + request; +//namespace Rehau.Sku.Assist +//{ +// static class SkuAssist +// { +// public async static Task GetContent(string request, HttpClient httpClient) +// { +// string uri = "https://shop-rehau.ru/catalogsearch/result/?q=" + request; +// ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; - HttpResponseMessage response = await httpClient.GetAsync(uri); - response.EnsureSuccessStatusCode(); +// return await httpClient.GetStringAsync(uri); +// } - IConfiguration config = Configuration.Default; - IBrowsingContext context = BrowsingContext.New(config); +// public async static Task GetDocument(string source) +// { +// IConfiguration config = Configuration.Default; +// IBrowsingContext context = BrowsingContext.New(config); - string source = await response.Content.ReadAsStringAsync(); - return await context.OpenAsync(req => req.Content(source)); - } +// return await context.OpenAsync(req => req.Content(source)); +// } - public static IProduct GetProductFromDocument(AngleSharp.Dom.IDocument document) - { - return document - .All - .Where(e => e.ClassName == "product-item__desc-top") - .Select(e => new Product(e.Children[0].TextContent, e.Children[1].TextContent.Trim(new[] { '\n', ' ' }))) - // .Where(product => !product.Sku.Any(c => char.IsLetter(c))) - .FirstOrDefault(); - } - } -} +// public static IProduct GetProductFromDocument(IDocument document) +// { +// return document +// .All +// .Where(e => e.ClassName == "product-item__desc-top") +// .Select(e => new Product(e.Children[0].TextContent, e.Children[1].TextContent.Trim(new[] { '\n', ' ' }))) +// // .Where(product => !product.Sku.Any(c => char.IsLetter(c))) +// .FirstOrDefault(); +// } +// } +//} diff --git a/Functions.cs b/Functions.cs index 9d3eb28..ab6cedf 100644 --- a/Functions.cs +++ b/Functions.cs @@ -1,53 +1,18 @@ -using ExcelDna.Integration; -using System.Runtime.Caching; +using System; +using ExcelDna.Integration; using System.Net.Http; +using System.Threading.Tasks; namespace Rehau.Sku.Assist { - public class Functions : IExcelAddIn + public class Functions { - private static HttpClient _httpClient; - private static ObjectCache _resultCache = MemoryCache.Default; - - public void AutoClose() - { - } - public void AutoOpen() - { - _httpClient = new HttpClient(); - } + private static HttpClient httpClient = new HttpClient(); [ExcelFunction] - public static object RAUNAME(string request) + public static async Task RAUNAME(string request) { - string cachedResult = _resultCache[request] as string; - - if (cachedResult != null) - { - return cachedResult; - } - - else - { - object result = ExcelAsyncUtil.Run("RAUNAME", null, - delegate - { - var document = SkuAssist.GetDocumentAsync(request, _httpClient).Result; - var product = SkuAssist.GetProductFromDocument(document); - return product.ToString(); - }); - - if (result.Equals(ExcelError.ExcelErrorNA)) - { - return "Загрузка..."; - } - - else - { - _resultCache.Add(request, result, System.DateTime.Now.AddMinutes(20)); - return result.ToString(); - } - } + throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/Rehau.Sku.Assist-AddIn.dna b/Rehau.Sku.Assist-AddIn.dna index b7322e9..bdf8847 100644 --- a/Rehau.Sku.Assist-AddIn.dna +++ b/Rehau.Sku.Assist-AddIn.dna @@ -1,6 +1,6 @@ - +