diff options
Diffstat (limited to 'Source/Assistant')
-rw-r--r-- | Source/Assistant/HttpClientUtil.cs | 74 | ||||
-rw-r--r-- | Source/Assistant/IProduct.cs | 9 | ||||
-rw-r--r-- | Source/Assistant/SkuAssist.cs | 102 | ||||
-rw-r--r-- | Source/Assistant/StoreResponse.cs | 21 |
4 files changed, 206 insertions, 0 deletions
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<string> GetContentByUriAsync(Uri uri) + { + ServicePointManager.SecurityProtocol = + SecurityProtocolType.Tls12 | + SecurityProtocolType.Tls11 | + SecurityProtocolType.Tls; + + return await _httpClient.GetStringAsync(uri); + } + + public async static Task<IDocument> ContentToDocAsync(Task<string> 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 new file mode 100644 index 0000000..d5db286 --- /dev/null +++ b/Source/Assistant/IProduct.cs @@ -0,0 +1,9 @@ +namespace Rehau.Sku.Assist +{ + interface IProduct + { + string Id { get; } + string Name { get; } + string Price { get; } + } +} diff --git a/Source/Assistant/SkuAssist.cs b/Source/Assistant/SkuAssist.cs new file mode 100644 index 0000000..69c1a81 --- /dev/null +++ b/Source/Assistant/SkuAssist.cs @@ -0,0 +1,102 @@ +using AngleSharp.Dom; +using ExcelDna.Integration; +using Newtonsoft.Json; +using System; +using System.Linq; +using System.Runtime.Caching; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace Rehau.Sku.Assist +{ + public enum ResponseOrder + { + NoSettings, + Relevance, + Name, + Price, + Series + } + + public enum ProductField + { + Name, + Id, + Price + } + + static class SkuAssist + { + public static async Task<IProduct> GetProduct(string request) + { + Uri uri = request.ConvertToUri(ResponseOrder.NoSettings); + + Task<string> contentTask = Task.Run(() => HttpClientUtil.GetContentByUriAsync(uri)); + Task<IDocument> documentTask = await contentTask.ContinueWith(content => HttpClientUtil.ContentToDocAsync(content)); + + return GetProduct(documentTask.Result); + } + + public static IProduct GetProduct(IDocument d) + { + string script = d.Scripts + .Where(s => s.InnerHtml.Contains("dataLayer")) + .First() + .InnerHtml; + + string json = script + .Substring(script.IndexOf("push(") + 5) + .TrimEnd(new[] { ')', ';', '\n', ' ' }); + + StoreResponce storeResponse = JsonConvert.DeserializeObject<StoreResponce>(json); + IProduct product = storeResponse + .Ecommerce + .Impressions + .Where(p => Regex.IsMatch(p.Id, @"\d{11}", RegexOptions.None)) + .FirstOrDefault(); + + return product; + } + + public static object GetProduct(string request, ProductField field) + { + IProduct product; + + if (MemoryCache.Default.Contains(request)) + { + product = MemoryCache.Default[request] as IProduct; + } + + else + { + object result = ExcelAsyncUtil.Run("RauName", new[] { request }, + delegate + { + Task<IProduct> p = Task.Run(() => GetProduct(request)); + return p.Result; + }); + + if (result == null) + return "Не найдено"; + + if (result.Equals(ExcelError.ExcelErrorNA)) + return "Загрузка..."; + + product = result as IProduct; + MemoryCache.Default.Add(request, product, DateTime.Now.AddMinutes(10)); + } + + switch (field) + { + case ProductField.Name: + return product.Name; + case ProductField.Id: + return product.Id; + case ProductField.Price: + return product.Price; + default: + return ExcelError.ExcelErrorValue; + } + } + } +}
\ No newline at end of file diff --git a/Source/Assistant/StoreResponse.cs b/Source/Assistant/StoreResponse.cs new file mode 100644 index 0000000..78fe846 --- /dev/null +++ b/Source/Assistant/StoreResponse.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; + +namespace Rehau.Sku.Assist +{ + public class StoreResponce + { + public Ecommerce Ecommerce { get; set; } + } + + public class Ecommerce + { + public List<Product> Impressions { get; set; } + } + + public class Product : IProduct + { + public string Id { get; set; } + public string Name { get; set; } + public string Price { get; set; } + } +}
\ No newline at end of file |