diff --git a/Rehau.Sku.Assist-AddIn-packed.xll b/Rehau.Sku.Assist-AddIn-packed.xll
deleted file mode 100644
index aea355f..0000000
Binary files a/Rehau.Sku.Assist-AddIn-packed.xll and /dev/null differ
diff --git a/Rehau.Sku.Assist.csproj b/Rehau.Sku.Assist.csproj
index 6667639..cc83173 100644
--- a/Rehau.Sku.Assist.csproj
+++ b/Rehau.Sku.Assist.csproj
@@ -85,6 +85,7 @@
+
diff --git a/Source/Assistant/HttpClientUtil.cs b/Source/Assistant/HttpClientUtil.cs
new file mode 100644
index 0000000..f9c144b
--- /dev/null
+++ b/Source/Assistant/HttpClientUtil.cs
@@ -0,0 +1,74 @@
+using AngleSharp;
+using AngleSharp.Dom;
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Text;
+
+namespace Rehau.Sku.Assist
+{
+ static class HttpClientUtil
+ {
+ private static HttpClient _httpClient = AddIn.httpClient;
+
+ public async static Task GetContentByUriAsync(Uri uri)
+ {
+ ServicePointManager.SecurityProtocol =
+ SecurityProtocolType.Tls12 |
+ SecurityProtocolType.Tls11 |
+ SecurityProtocolType.Tls;
+
+ return await _httpClient.GetStringAsync(uri);
+ }
+
+ public async static Task ContentToDocAsync(Task content)
+ {
+ IConfiguration config = Configuration.Default;
+ IBrowsingContext context = BrowsingContext.New(config);
+
+ return await context.OpenAsync(req => req.Content(content.Result));
+ }
+
+ public static Uri ConvertToUri(this string request, ResponseOrder order)
+ {
+ UriBuilder baseUri = new UriBuilder("https", "shop-rehau.ru");
+
+ baseUri.Path = "/catalogsearch/result/index/";
+ string cleanedRequest = request._CleanRequest();
+
+ switch (order)
+ {
+ case ResponseOrder.Relevance:
+ baseUri.Query = "dir=asc&order=relevance&q=" + cleanedRequest;
+ break;
+ case ResponseOrder.Name:
+ baseUri.Query = "dir=asc&order=name&q=" + cleanedRequest;
+ break;
+ case ResponseOrder.Price:
+ baseUri.Query = "dir=asc&order=price&q=" + cleanedRequest;
+ break;
+ case ResponseOrder.Series:
+ baseUri.Query = "dir=asc&order=sch_product_series&q=" + cleanedRequest;
+ break;
+ case ResponseOrder.NoSettings:
+ baseUri.Query = "q=" + cleanedRequest;
+ break;
+ default:
+ throw new ArgumentException();
+ }
+
+ return baseUri.Uri;
+ }
+
+ private static string _CleanRequest(this string input)
+ {
+ return new StringBuilder(input)
+ .Replace("+", " plus ")
+ .Replace("РХ", "")
+ .Replace("º", " ")
+ .Replace(".", " ")
+ .ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Assistant/IProduct.cs b/Source/Assistant/IProduct.cs
index aca3ff5..de0eccf 100644
--- a/Source/Assistant/IProduct.cs
+++ b/Source/Assistant/IProduct.cs
@@ -1,9 +1,11 @@
-namespace Rehau.Sku.Assist
+using System;
+
+namespace Rehau.Sku.Assist
{
interface IProduct
{
string Sku { get; }
string Name { get; }
- string Uri { get; }
+ Uri Uri { get; }
}
}
diff --git a/Source/Assistant/Product.cs b/Source/Assistant/Product.cs
index 17a7065..22905af 100644
--- a/Source/Assistant/Product.cs
+++ b/Source/Assistant/Product.cs
@@ -1,11 +1,12 @@
-namespace Rehau.Sku.Assist
+using System;
+
+namespace Rehau.Sku.Assist
{
public class Product : IProduct
{
public string Sku { get; }
public string Name { get; }
-
- public string Uri => throw new System.NotImplementedException();
+ public Uri Uri { get; }
public Product(string sku, string name)
{
@@ -13,6 +14,13 @@
Name = name;
}
+ public Product(string sku, string name, string uri)
+ {
+ Sku = sku;
+ Name = name;
+ Uri = new Uri(uri);
+ }
+
public override string ToString()
{
return $"{this.Name} ({this.Sku})";
diff --git a/Source/Assistant/SkuAssist.cs b/Source/Assistant/SkuAssist.cs
index 152dbbb..121bc88 100644
--- a/Source/Assistant/SkuAssist.cs
+++ b/Source/Assistant/SkuAssist.cs
@@ -1,80 +1,62 @@
-using AngleSharp;
-using AngleSharp.Dom;
+using AngleSharp.Dom;
+using AngleSharp.Html.Dom;
using System;
using System.Linq;
-using System.Net;
-using System.Net.Http;
using System.Threading.Tasks;
+using System.Text.RegularExpressions;
namespace Rehau.Sku.Assist
{
+ public enum ResponseOrder
+ {
+ NoSettings,
+ Relevance,
+ Name,
+ Price,
+ Series
+ }
+
static class SkuAssist
{
- private static HttpClient _httpClient;
- private enum ResponseOrder
+ public static async Task GetProduct(string request)
{
- NoSettings,
- Relevance,
- Name,
- Price,
- Series
- }
- private static void _EnsureHttpClientRunning()
- {
- if (_httpClient == null)
- _httpClient = new HttpClient();
+ Uri uri = request.ConvertToUri(ResponseOrder.NoSettings);
+
+ Task contentTask = Task.Run(() => HttpClientUtil.GetContentByUriAsync(uri));
+ Task documentTask = await contentTask.ContinueWith(content => HttpClientUtil.ContentToDocAsync(content));
+
+ IProduct product = await documentTask.ContinueWith(doc => SkuAssist.GetFirstProduct(doc.Result));
+ return product;
}
- public async static Task GetContent(string request)
+ public static IProduct GetFirstProduct(IDocument doc)
{
- Uri uri = _ConvertToUri(request, ResponseOrder.NoSettings);
- _EnsureHttpClientRunning();
- ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
-
- return await _httpClient.GetStringAsync(uri);
- }
-
- public async static Task GetDocument(Task source)
- {
- IConfiguration config = Configuration.Default;
- IBrowsingContext context = BrowsingContext.New(config);
-
- return await context.OpenAsync(req => req.Content(source.Result));
- }
-
- public static IProduct GetProductFromDocument(IDocument document)
- {
- return document
+ return doc
.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(e => Regex.IsMatch(e.Children[0].TextContent, @"\d{11}", RegexOptions.None))
+ .Select(e =>
+ new Product(e.Children[0].TextContent,
+ e.Children[1].TextContent.Trim(new[] { '\n', ' ' })))
.FirstOrDefault();
}
- private static Uri _ConvertToUri(this string request, ResponseOrder order)
+ public static Uri GetFirstResultLink(IDocument doc)
{
- string cleanedRequest = request._CleanRequest();
- switch (order)
- {
- case ResponseOrder.Relevance:
- return new Uri("https://shop-rehau.ru/catalogsearch/result/index/?dir=asc&order=relevance&q=" + cleanedRequest);
- case ResponseOrder.Name:
- return new Uri("https://shop-rehau.ru/catalogsearch/result/index/?dir=asc&order=name&q=" + cleanedRequest);
- case ResponseOrder.Price:
- return new Uri("https://shop-rehau.ru/catalogsearch/result/index/?dir=asc&order=price&q=" + cleanedRequest);
- case ResponseOrder.Series:
- return new Uri("https://shop-rehau.ru/catalogsearch/result/index/?dir=asc&order=sch_product_series&q=" + cleanedRequest);
- case ResponseOrder.NoSettings:
- return new Uri("https://shop-rehau.ru/catalogsearch/result/?q=" + cleanedRequest);
- default:
- throw new ArgumentException();
- }
+ var link = new Uri(doc
+ .Links
+ .Where(e => e.ClassName == "product-item__title-link js-name")
+ .Select(l => ((IHtmlAnchorElement)l).Href)
+ .FirstOrDefault());
+ return link;
}
- private static string _CleanRequest(this string input)
+
+ public static string GetFistResultImageLink(IDocument doc)
{
- return input.Replace("+", " plus ");
+ var imageSource = doc.Images
+ .Where(x => x.ClassName == "product-item__image")
+ .FirstOrDefault();
+ return imageSource != null ? imageSource.Source : "Нет ссылки";
}
}
-}
-
-
+}
\ No newline at end of file
diff --git a/Source/ExcelDNA/AddIn.cs b/Source/ExcelDNA/AddIn.cs
index dd99667..0505e5b 100644
--- a/Source/ExcelDNA/AddIn.cs
+++ b/Source/ExcelDNA/AddIn.cs
@@ -1,13 +1,17 @@
using ExcelDna.Integration;
using ExcelDna.Registration;
+using System.Net.Http;
namespace Rehau.Sku.Assist
{
public class AddIn : IExcelAddIn
{
+ public static HttpClient httpClient;
+
public void AutoOpen()
{
RegisterFunctions();
+ httpClient = new HttpClient();
}
public void AutoClose()
diff --git a/Source/ExcelDNA/Functions.cs b/Source/ExcelDNA/Functions.cs
index a282e3e..db882c5 100644
--- a/Source/ExcelDNA/Functions.cs
+++ b/Source/ExcelDNA/Functions.cs
@@ -1,19 +1,36 @@
-using AngleSharp.Dom;
-using ExcelDna.Integration;
-using System.Net.Http;
+using ExcelDna.Integration;
using System.Threading.Tasks;
+using System.Runtime.Caching;
namespace Rehau.Sku.Assist
{
public class Functions
{
[ExcelFunction]
- public static async Task RAUNAME(string request)
+ public static object RAUNAME(string request)
{
- Task contentTask = Task.Run(() => SkuAssist.GetContent(request));
- Task documentTask = await contentTask.ContinueWith(content => SkuAssist.GetDocument(content));
- IProduct product = await documentTask.ContinueWith(doc => SkuAssist.GetProductFromDocument(doc.Result));
- return product != null ? product.ToString() : "Не найдено";
+ if (MemoryCache.Default.Contains(request))
+ return MemoryCache.Default[request].ToString();
+
+ else
+ {
+ object result = ExcelAsyncUtil.Run("Rauname", new[] { request },
+ delegate
+ {
+ Task product = Task.Run(() => SkuAssist.GetProduct(request));
+ return product.Result;
+ });
+
+ if (Equals(result, ExcelError.ExcelErrorNA))
+ {
+ return "Загрузка...";
+ }
+ else
+ {
+ MemoryCache.Default.Add(request, result, System.DateTime.Now.AddMinutes(10));
+ return result == null ? "Не найдено" : result.ToString();
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/Tests/SkuAssistTests.cs b/Tests/SkuAssistTests.cs
index fc47c41..d70ac1c 100644
--- a/Tests/SkuAssistTests.cs
+++ b/Tests/SkuAssistTests.cs
@@ -2,14 +2,14 @@
namespace Rehau.Sku.Assist.Tests
{
- [TestFixture]
- public class SkuAssistTests
- {
- [Test]
- public async void BaseTest()
- {
- var result = await Functions.RAUNAME("160001");
- Assert.AreEqual("Надвижная гильза REHAU RAUTITAN РХ (11600011001)", result);
- }
- }
+ //[TestFixture]
+ //public class SkuAssistTests
+ //{
+ // [Test]
+ // public async void BaseTest()
+ // {
+ // var result = await Functions.RAUNAME("160001");
+ // Assert.AreEqual("Надвижная гильза REHAU RAUTITAN РХ (11600011001)", result);
+ // }
+ //}
}