Example #1
0
        /// <summary>
        /// Make sure the rate for provided currency is known.
        /// </summary>
        static void EnsureValidRate(Currency currency)
        {
            //Check if there is data in memory
            if (Rates.ContainsKey(currency))
            {
                if (Rates[currency].Expires > DateTime.Now)
                {
                    return;
                }
                else
                {
                    Logger.Log(currency + $" rate has expired since {Rates[currency].Expires} @ Currencier");
                    Rates.Remove(currency);
                }
            }
            else
            {
                Logger.Log(currency + " rate is not defined @ Currencier");
            }

            EnsureImportingMeansSetup();

            //Extraction
            string rawHtml = null;

            try
            {
                //Extraction from Web
                rawHtml = fastWeb.Get($"search?hl=en&gl=en&q={currency}+to+{MainCurrency}");
            }
            catch (FastWeb2Exception)
            {
                Logger.Log($"Cannot retrieve remote rate for {currency}. Reading all rates from file [{filePath}]");

                //Extraction from file
                AttemptReadRatesFromFile(currency);
                return;
            }

            //Having remote page pulled down, continue extraction
            HtmlDocument document = new HtmlDocument();

            document.LoadHtml(rawHtml);
            HtmlNode docNode = document.DocumentNode;

            string exValue = rateParser.ExtractSingle(docNode);

            decimal.TryParse(exValue, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal value);


            //Saving
            SetRate(currency, new ExpirableRate(value, DefaultExpiration));

            //Storing
            WriteAllRates();
        }
Example #2
0
        /// <summary>
        /// Call for starting parsing by the contained rules, using provided crude information html content string.
        /// </summary>
        public PageParseResult Parse(string relativeUri = null)
        {
            if (fastWeb == null)
            {
                fastWeb = new FastWeb2(Domain);
            }

            var rawHtml = fastWeb.Get(relativeUri);

            //PreprocessPlan
            string processedHtml = PagePreprocess == null ? rawHtml : rawHtml.Mold(PagePreprocess);

            //interpret as document node
            HtmlDocument document = new HtmlDocument();

            document.LoadHtml(processedHtml);
            HtmlNode entireDocumentNode = document.DocumentNode;

            var pageParseResult = new PageParseResult
            {
                Title = Title.ExtractSingle(node: entireDocumentNode)
            };

            if (Subtitle != null)
            {
                pageParseResult.Title += " " + Subtitle.ExtractSingleFromNode(node: entireDocumentNode);
            }

            if (Thumbnail != null)
            {
                pageParseResult.ThumbPath = Thumbnail.ExtractSingleFromNode(node: entireDocumentNode);
            }

            //Parsing Actual Options
            if (DefaultOptionMode != DefaultOptionMode.Single)
            {
                try
                {
                    bool isRegex = OptionsList.SelectMethod == SelectMethod.Regex;

                    IEnumerable <object> crudeOptions;

                    if (isRegex)
                    {
                        crudeOptions = OptionsList.ExtractList(entireDocumentNode.InnerHtml);
                    }
                    else
                    {
                        crudeOptions = OptionsList.ExtractList(entireDocumentNode);
                    }

                    foreach (var entry in crudeOptions)
                    {
                        var optionParseResult = isRegex ? ActualOption.Parse(entry as string) : ActualOption.Parse(entry as HtmlNode);

                        if (optionParseResult.Price.Amount == 0 && PriceMode != PriceMode.Add)
                        {
                            continue;
                        }

                        pageParseResult.OptionParseResults.Add(optionParseResult);
                    }
                }
                catch (NullReferenceException nrex) when(DefaultOptionMode == DefaultOptionMode.Alongside || DefaultOptionMode == DefaultOptionMode.Alternative)
                {
                    //swallow when actual options absence allowed
                    Logger.Log(nrex.Message + " @ PageParsing of " + relativeUri);
                }
            }

            //Default Option Logic
            if (DefaultOptionMode != DefaultOptionMode.Ignore)
            {
                if (DefaultOptionMode == DefaultOptionMode.Single)
                {
                    Logger.Log(Domain + " has 1 option per page setup. Add all options separately.");
                }

                OptionParseResult defaultOption;

                try
                {
                    defaultOption           = DefaultOption.Parse(entireDocumentNode);
                    defaultOption.PropertyA = defaultOption.Code = DefaultOptionMode.ToString();
                }
                catch (NullReferenceException nrex)
                {
                    Logger.Log(nrex.Message + " @ PageParsing of " + relativeUri);
                    throw;
                }

                //Prices correction according to Price Mode Setting
                if (PriceMode == PriceMode.Add)
                {
                    foreach (OptionParseResult optParseRes in pageParseResult.OptionParseResults)
                    {
                        optParseRes.Price.Amount += defaultOption.Price.Amount;
                    }
                }

                //Adding default option to the options list, if necessary
                if (DefaultOptionMode == DefaultOptionMode.Alongside ||
                    DefaultOptionMode == DefaultOptionMode.Single ||
                    (DefaultOptionMode == DefaultOptionMode.Alternative && pageParseResult.OptionParseResults.Count == 0))
                {
                    pageParseResult.OptionParseResults.Add(defaultOption);
                }
            }

            //Prices correction according to the Main Currency & Shop Ordering Rules
            foreach (OptionParseResult optParseRes in pageParseResult.OptionParseResults)
            {
                optParseRes.Price = optParseRes.Price.AsMainCurrency();
                var value = optParseRes.Price.Amount;

                value /= 1 + OrderDeduction;

                if (OrderExtra != null && OrderLimit != null && OrderLimit.AsMainCurrency().Amount > 0)
                {
                    decimal limitValue      = OrderLimit.AsMainCurrency().Amount;
                    decimal orderExtraValue = OrderExtra.AsMainCurrency().Amount;
                    decimal piecesPerOrder  = limitValue / value;
                    decimal extraPerPiece   = orderExtraValue / piecesPerOrder;
                    value += extraPerPiece;
                }

                optParseRes.Price.Amount = value;
            }

            return(pageParseResult);
        }