)>}]
شركة التطبيقات المتكاملة لتصميم وبرمجة البرمجيات الخاصة ش.ش.و.
Integrated Applications Programming Company
Home » Code Library » Default (Ia.Statistics.Cl.Model.Dabdoob)

Public general use code classes and xml files that we've compiled and used over the years:

Structure of the dabdoob.com website.

    1: using System;
    2: using System.Collections.Generic;
    3: using System.IO;
    4: using System.Linq;
    5: using System.Reflection;
    6: using System.Xml.Linq;
    7: using System.Text.RegularExpressions;
    8: using OpenQA.Selenium;
    9: using OpenQA.Selenium.Chrome;
   10: using System.Threading;
   11: using Ia.Cl.Models.Google;
   12: using OpenQA.Selenium.Interactions;
   13:  
   14: namespace Ia.Statistics.Cl.Model.Dabdoob
   15: {
   16:     ////////////////////////////////////////////////////////////////////////////
   17:  
   18:     /// <summary publish="true">
   19:     /// Structure of the dabdoob.com website.
   20:     /// </summary>
   21:     /// <remarks> 
   22:     /// Copyright © 2024-2025 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
   23:     ///
   24:     /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
   25:     /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
   26:     ///
   27:     /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
   28:     /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   29:     /// 
   30:     /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
   31:     /// 
   32:     /// Copyright notice: This notice may not be removed or altered from any source distribution.
   33:     /// </remarks> 
   34:     public class Default
   35:     {
   36:         private static XDocument xd;
   37:  
   38:         private static List<Ia.Statistics.Cl.Model.Category> categoryList;
   39:  
   40:         private static List<Ia.Statistics.Cl.Model.Product> productList;
   41:  
   42:         private static List<Ia.Statistics.Cl.Model.Site> dabdoobSiteList = new List<Site>{
   43:             Ia.Statistics.Cl.Model.Site.DabdoobKuwait,
   44:             Ia.Statistics.Cl.Model.Site.DabdoobSaudiArabia,
   45:             Ia.Statistics.Cl.Model.Site.DabdoobEmirates,
   46:             Ia.Statistics.Cl.Model.Site.DabdoobQatar,
   47:             Ia.Statistics.Cl.Model.Site.DabdoobBahrain,
   48:         };
   49:  
   50:         ////////////////////////////////////////////////////////////////////////////
   51:  
   52:         /// <summary>
   53:         /// 
   54:         /// </summary>
   55:         public Default() { }
   56:  
   57:         ////////////////////////////////////////////////////////////////////////////
   58:  
   59:         /// <summary>
   60:         ///
   61:         /// </summary>
   62:         public static string ReadUpdateProductListOfCategorySequentially(Ia.Statistics.Cl.Model.Site site0)
   63:         {
   64:             string s;
   65:  
   66:             var category = Ia.Statistics.Cl.Model.Dabdoob.Default.CategoryList.RandomThenNext();
   67:  
   68:             var site = Ia.Statistics.Cl.Model.Site.SiteFromId(category.SiteId);
   69:  
   70:             var productPriceStockQuantitySoldList = ProductPriceStockListOfCategory(site, category, out string exception);
   71:  
   72:             if (string.IsNullOrEmpty(exception))
   73:             {
   74:                 if (productPriceStockQuantitySoldList.Count > 0)
   75:                 {
   76:                     s = string.Empty;
   77:  
   78:                     foreach (var productPriceStockQuantitySold in productPriceStockQuantitySoldList)
   79:                     {
   80:                         if (!string.IsNullOrEmpty(productPriceStockQuantitySold.Product.Sku))
   81:                         {
   82:                             Ia.Statistics.Cl.Model.Product.Create(productPriceStockQuantitySold.Product);
   83:                             Ia.Statistics.Cl.Model.ProductPriceSpot.Create(productPriceStockQuantitySold.Product, productPriceStockQuantitySold.Price);
   84:                             Ia.Statistics.Cl.Model.ProductStockSpot.Create(productPriceStockQuantitySold.Product, productPriceStockQuantitySold.Stock);
   85:  
   86:                             s += "Product: " + productPriceStockQuantitySold.Product.Name + "; price: " + productPriceStockQuantitySold.Price + "; stock: " + productPriceStockQuantitySold.Stock + ". ";
   87:                         }
   88:                         else
   89:                         {
   90:                             s += "Product: " + productPriceStockQuantitySold.Product.Name + ": SKU is null. ";
   91:                         }
   92:                     }
   93:                 }
   94:                 else s = "Product list is 0. ";
   95:  
   96:                 s = site.Name + ": " + category.Url + ": " + s;
   97:             }
   98:             else s = exception;
   99:  
  100:             return s;
  101:         }
  102:  
  103:         ////////////////////////////////////////////////////////////////////////////
  104:  
  105:         /// <summary>
  106:         ///
  107:         /// </summary>
  108:         public static List<Ia.Statistics.Cl.Model.ProductPriceStockQuantitySold> ProductPriceStockListOfCategory(Ia.Statistics.Cl.Model.Site site, Ia.Statistics.Cl.Model.Category category, out string exception)
  109:         {
  110:             int areaId;
  111:  
  112:             var productPriceStockQuantitySoldList = new List<Ia.Statistics.Cl.Model.ProductPriceStockQuantitySold>();
  113:  
  114:             var options = new ChromeOptions();
  115:  
  116:             var chromeDriverService = ChromeDriverService.CreateDefaultService();
  117:             chromeDriverService.HideCommandPromptWindow = true;
  118:             chromeDriverService.SuppressInitialDiagnosticInformation = true;
  119:  
  120:             options.AddArgument("--headless");
  121:             options.AddArgument("--log-level=3");
  122:             options.AddArgument("--disable-extensions");
  123:             options.AddArgument("--ignore-certificate-errors");
  124:  
  125:             switch (site.Iso)
  126:             {
  127:                 case "KW": areaId = 10; break;
  128:                 case "SA": areaId = 2648; break;
  129:                 case "AE": areaId = 12; break;
  130:                 case "QA": areaId = 6; break;
  131:                 case "BH": areaId = 11; break;
  132:                 default: areaId = 10; break;
  133:             }
  134:  
  135:             using (var chromeDriver = new OpenQA.Selenium.Chrome.ChromeDriver(chromeDriverService, options))
  136:             {
  137:                 chromeDriver.Manage().Timeouts().ImplicitWait = Ia.Statistics.Cl.Model.Default.TimeoutTimeSpan;
  138:  
  139:                 chromeDriver.Navigate().GoToUrl(category.Url);
  140:  
  141:                 chromeDriver.Manage().Cookies.AddCookie(new OpenQA.Selenium.Cookie("DAB_AREA", areaId.ToString(), "", DateTime.UtcNow.AddHours(3).AddYears(1)));
  142:                 chromeDriver.Manage().Cookies.AddCookie(new OpenQA.Selenium.Cookie("DAB_COUNTRY", site.Iso, "", DateTime.UtcNow.AddHours(3).AddYears(1)));
  143:                 chromeDriver.Manage().Cookies.AddCookie(new OpenQA.Selenium.Cookie("accept_cookies", "accepted", "", DateTime.UtcNow.AddHours(3).AddYears(1)));
  144:                 chromeDriver.Manage().Cookies.AddCookie(new OpenQA.Selenium.Cookie("ajs_anonymous_id", "e7a170bb-807b-4546-8caf-b7cec22f20c5", "", DateTime.UtcNow.AddHours(3).AddYears(1)));
  145:  
  146:                 chromeDriver.Navigate().GoToUrl(category.Url); // I will access site again with location cookies
  147:  
  148:                 // maximize the browser
  149:                 // chromeDriver.Manage().Window.Maximize();
  150:  
  151:                 // scroll down the webpage
  152:                 var javaScriptExecutor = ((IJavaScriptExecutor)chromeDriver);
  153:                 javaScriptExecutor.ExecuteScript("window.scrollTo(0, document.body.scrollHeight)");
  154:  
  155:                 // loop through all "Load more" buttons 
  156:  
  157:                 IWebElement loadMoreButton;
  158:  
  159:                 do
  160:                 {
  161:                     try
  162:                     {
  163:                         // <button type="button" ... >Load More</button>
  164:                         //loadMoreButton = chromeDriver.FindElement(By.ClassName(@""), 10);
  165:                         //loadMoreButton = chromeDriver.FindElement(By.XPath("//button[@value='Load More' and @type='button']"), 10);
  166:                         loadMoreButton = chromeDriver.FindElement(By.XPath("//button[text()='Load More']"), 10);
  167:  
  168:                         if (loadMoreButton != null)
  169:                         {
  170:                             Actions actions = new Actions(chromeDriver);
  171:                             actions.MoveToElement(loadMoreButton).Click().Build().Perform();
  172:                             Thread.Sleep(2000);
  173:  
  174:                             // loadMoreButton.Click();
  175:  
  176:                             javaScriptExecutor.ExecuteScript("window.scrollTo(0, document.body.scrollHeight)");
  177:                         }
  178:                         else break;
  179:                     }
  180:                     catch (OpenQA.Selenium.NoSuchElementException e)
  181:                     {
  182:                         break;
  183:                     }
  184:                 }
  185:                 while (loadMoreButton != null);
  186:  
  187:                 var content = chromeDriver.PageSource;
  188:  
  189:                 ProductPriceStockListFromCategoryContent(site, category, content, out productPriceStockQuantitySoldList, out exception);
  190:             }
  191:  
  192:             return productPriceStockQuantitySoldList;
  193:         }
  194:  
  195:         ////////////////////////////////////////////////////////////////////////////
  196:  
  197:         /// <summary>
  198:         ///
  199:         /// </summary>
  200:         public static void ProductPriceStockListFromCategoryContent(Ia.Statistics.Cl.Model.Site site, Ia.Statistics.Cl.Model.Category category, string content, out List<Ia.Statistics.Cl.Model.ProductPriceStockQuantitySold> productPriceStockQuantitySoldList, out string exception)
  201:         {
  202:             productPriceStockQuantitySoldList = new List<Ia.Statistics.Cl.Model.ProductPriceStockQuantitySold>();
  203:  
  204:             //  {"id":85023,"name":"Spartan Mattel Hot Wheels Bicycle - 14 Inch","slug":"spartan-mattel-hot-wheels-bicycle-14-inch-85023","default_sku_id":87837,"skus":[{"id":87837,"name":"Spartan Mattel Hot Wheels Bicycle - 14 Inch","slug":"spartan-mattel-hot-wheels-bicycle-14-inch-87837","price":{"price":34.95,"old_price":null,"vat":false,"raw_price":34.95},"buy_limit":1,"medias":[{"url":"https://dabdoob-cdn-primary.fra1.cdn.digitaloceanspaces.com/media/master/sku/OpsgTd/c536d0ac-982c-4033-9e9e-76a14298b232_IircelT7Z.jpeg","type":"image","blurhash":null}]}],"brand":{"id":156,"name":"Spartan","slug":"spartan-156"},"category":{"id":20,"slug":"ride-on-and-scooters-20","name":"Ride-On And Scooters","color":"#334455","text_color":"#000000"},"subcategory":{"id":120,"name":"Bikes","slug":"bikes-120"}},
  205:             var matchCollection = Regex.Matches(content, @"{""id"":(.+?),""name"":""(.+?)"",""slug"":""(.+?)"",""default_sku_id"":(.+?),""skus"":.+?,""price"":{""price"":(.+?),.+?,""buy_limit"":(.+?),.+?}}", RegexOptions.None, Ia.Statistics.Cl.Model.Default.TimeoutTimeSpan);
  206:  
  207:             foreach (Match match in matchCollection)
  208:             {
  209:                 var product = new Ia.Statistics.Cl.Model.Product();
  210:                 var productPriceStockQuantitySold = new Ia.Statistics.Cl.Model.ProductPriceStockQuantitySold();
  211:  
  212:                 var sku = match.Groups[4].Value; // default_sku_id;
  213:  
  214:                 var name = match.Groups[2].Value; // name
  215:                 name = Ia.Statistics.Cl.Model.Default.NormalizeName(name);
  216:  
  217:                 var url = match.Groups[3].Value; // slug;
  218:  
  219:                 product.Id = Ia.Statistics.Cl.Model.Product.ProductId(site, sku);
  220:                 product.SiteId = site.Id;
  221:                 //product.Category = category;
  222:                 product.Sku = sku;
  223:                 product.Name = name;
  224:                 product.Url = site.BaseUrl + "/product/" + url;
  225:  
  226:                 var price = decimal.TryParse(match.Groups[5].Value, out decimal d) ? d : 0;
  227:  
  228:                 var stock = int.Parse(match.Groups[6].Value); // buy_limit;
  229:                 stock = stock <= Ia.Statistics.Cl.Model.Default.MaximumReasonableStockValue ? stock : Ia.Statistics.Cl.Model.Default.MaximumReasonableStockValue;
  230:  
  231:                 productPriceStockQuantitySold.Product = product;
  232:                 productPriceStockQuantitySold.Price = price;
  233:                 productPriceStockQuantitySold.Stock = stock;
  234:  
  235:                 productPriceStockQuantitySoldList.Add(productPriceStockQuantitySold);
  236:             }
  237:  
  238:             exception = string.Empty;
  239:         }
  240:  
  241:         ////////////////////////////////////////////////////////////////////////////
  242:  
  243:         /// <summary>
  244:         ///
  245:         /// </summary>
  246:         public static List<Ia.Statistics.Cl.Model.Category> CategoryList
  247:         {
  248:             get
  249:             {
  250:                 if (categoryList == null || categoryList.Count == 0)
  251:                 {
  252:                     categoryList = new List<Model.Category>();
  253:  
  254:                     foreach (var site in dabdoobSiteList)
  255:                     {
  256:                         categoryList.AddRange((from c in XDocument.Element("dabdoob").Descendants("category")
  257:                                                where !c.HasElements
  258:                                                select new Ia.Statistics.Cl.Model.Category
  259:                                                {
  260:                                                    Id = 0, //Ia.Statistics.Cl.Model.Category.CategoryId(site, int.Parse(c.Attribute("id").Value)),
  261:                                                    SiteId = site.Id,
  262:                                                    Url = site.BaseUrl + c.Attribute("url").Value,
  263:                                                    Name = c.Attribute("name").Value
  264:                                                }
  265:                         ).ToList<Ia.Statistics.Cl.Model.Category>());
  266:  
  267:                         categoryList = categoryList.Shuffle().ToList();
  268:                     }
  269:                 }
  270:  
  271:                 return categoryList;
  272:             }
  273:         }
  274:  
  275:         ////////////////////////////////////////////////////////////////////////////
  276:  
  277:         /// <summary>
  278:         /// 
  279:         /// How to embed and access resources by using Visual C# http://support.microsoft.com/kb/319292/en-us
  280:         /// 
  281:         /// 1. Change the "Build Action" property of your XML file from "Content" to "Embedded Resource".
  282:         /// 2. Add "using System.Reflection".
  283:         /// 3. Manifest resource stream will start with the project namespace, the location of XML file.
  284:         /// 
  285:         /// </summary>
  286:  
  287:         private static XDocument XDocument
  288:         {
  289:             get
  290:             {
  291:                 Assembly _assembly;
  292:                 StreamReader streamReader;
  293:  
  294:                 xd = null;
  295:                 _assembly = Assembly.GetExecutingAssembly();
  296:                 streamReader = new StreamReader(_assembly.GetManifestResourceStream("Ia.Statistics.Cl.model.dabdoob.com.default.xml"));
  297:  
  298:                 try
  299:                 {
  300:                     if (streamReader.Peek() != -1)
  301:                     {
  302:                         xd = System.Xml.Linq.XDocument.Load(streamReader);
  303:                     }
  304:                 }
  305:                 catch (Exception)
  306:                 {
  307:                 }
  308:                 finally
  309:                 {
  310:                 }
  311:  
  312:                 return xd;
  313:             }
  314:         }
  315:  
  316:         ////////////////////////////////////////////////////////////////////////////
  317:         ////////////////////////////////////////////////////////////////////////////
  318:     }
  319: }