private Paragraph GenerateParagraph(IHtmlParagraphElement node) { Paragraph paragraph = null; string attributeStyle = null; if (node.ClassName != "FirstInDiv" && node.ClassName != "FirstAndLastInDiv" && node.HasAttribute("style")) { attributeStyle = node.Attributes["style"].Value; } if (attributeStyle == "display: inline;") { paragraph = GetOrCreateLastParagraph(richTextBlock.Blocks); AddInlineChildren(node, paragraph.Inlines); } else { paragraph = new Paragraph(); AddInlineChildren(node, paragraph.Inlines); } if (attributeStyle != "display: inline;") { startWithAnotherParagraph = true; } return(paragraph); }
private Paragraph GenerateParagraph(IHtmlParagraphElement node) { var paragraph = new Paragraph(); AddInlineChildren(node, paragraph.Inlines); return(paragraph); }
/// <summary> /// Загрузка всей структуры групп товаров /// </summary> /// <returns>Список групп товаров</returns> public static async Task <GroupsCollection> GetGroupsCollection() { GroupsCollection groupsCollection = new GroupsCollection(); if (await groupsCollection.Loader.LoadPageAsync(groupsCollection.Url)) { // Для разбора наименования группы string pattern = @"^(?<name>[^<]+)"; Regex regex = new Regex(pattern); Match match; string categoryName; var catalogBlockList = groupsCollection.Loader.Document.QuerySelectorAll("div") .Where(item => item.ClassName != null && item.ClassName.Contains("category")); foreach (IHtmlDivElement catalogBlock in catalogBlockList) { if (!SiteWorker.CURRENT_INSTANCE.IsActive) { return(groupsCollection); } IHtmlAnchorElement catalogAnchor = (IHtmlAnchorElement)catalogBlock.QuerySelectorAll("a").FirstOrDefault(); if (catalogAnchor != null) { IHtmlParagraphElement catalogLabel = (IHtmlParagraphElement)catalogAnchor.QuerySelectorAll("p").FirstOrDefault(); if (catalogLabel != null) { match = regex.Match(catalogLabel.InnerHtml); if (match.Success) { categoryName = match.Groups["name"].Value.Trim(); Group groupItem = new Group(categoryName, Site.PrepareUrl(catalogAnchor.Href.Trim())); groupsCollection.Groups.Add(groupItem); // Добавление корневой группы groupItem.RegisterGroup(); // Загрузка дочерних групп GroupsCollection subgroupsCollection = await groupItem.GetSubgroupsCollection(); groupsCollection.Groups.AddRange(subgroupsCollection); } } } } // Обновление уровней подчинённости в таблице групп groupsCollection.UpdateDBParents(); } else { string logMessage = @"Ошибка при загрузке страницы: {0}"; SiteWorker.CURRENT_INSTANCE.Log = String.Format(logMessage, groupsCollection.Url); SiteWorker.CURRENT_INSTANCE.Stop(); } return(groupsCollection); }
private List <Labordaten> UpdateLaborCache(List <Labordaten> AlteLaborDaten) { var context = BrowsingContext.New(Configuration.Default.WithDefaultLoader()); IDocument LaborStartSeite = context.OpenAsync(BaseUrl).Result; List <Labordaten> NeueLaborDaten = LaborStartSeite.QuerySelectorAll <IHtmlAnchorElement>("#content-section div.csc-space-after-1 div.csc-default a.button-link").Where(x => x.Href.Contains("/fritz-labor/")).Select(link => { string fallbackDate = null; var lastUpdate = link.ParentElement.PreviousElementSibling; if (lastUpdate.TextContent.StartsWith(KeywordLetztesUpdate)) { fallbackDate = lastUpdate.TextContent.Substring(KeywordLetztesUpdate.Length); } IDocument detailPage = link.NavigateAsync().Result; IHtmlParagraphElement downloadInformations = detailPage.QuerySelector <IHtmlParagraphElement>("p:contains('Downloadinformationen:')") ?? detailPage.QuerySelector <IHtmlParagraphElement>("p:contains('Informationen zum Download:')"); if (downloadInformations == null) { return(null); } Labordaten daten = new Labordaten(); daten.Typ = detailPage.Title.EndsWith(TitleAVM) ? detailPage.Title.Remove(detailPage.Title.Length - TitleAVM.Length) : detailPage.Title; daten.Version = downloadInformations.ChildNodes.Where(x => x.TextContent.StartsWith(KeywordVersion)).Select(x => x.TextContent.Substring(KeywordVersion.Length)).FirstOrDefault(); daten.Datum = downloadInformations.ChildNodes.Where(x => x.TextContent.StartsWith(KeywordDatum)).Select(x => x.TextContent.Substring(KeywordDatum.Length)).FirstOrDefault() ?? fallbackDate; daten.Url = link.Href; return(daten); }).ToList(); try { NeueLaborDaten.AddRange(GetFTPBetas()); } catch (FtpCommandException ex) { if (ex.Message == "There are too many connections from your internet address.") { Log.Warning("Abrufen von FTP Labors wegen zu vielen Connections fehlgeschlagen"); } else { Log.Error(ex, "Abrufen von FTP Labors fehlgeschlagen"); } } if (NeueLaborDaten.Count > 0) { return(NeueLaborDaten); } return(AlteLaborDaten); }
public ParagraphNode(IHtmlParagraphElement content) { Content = content; Children = AstHelper.TryCreateNodes(content.ChildNodes.ToList()).ToList(); }
private IEnumerable <R4UCard> CreateBaseCards(IHtmlParagraphElement paragraph, Dictionary <string, R4UReleaseSet> setMap) { List <R4UCard> cards = new List <R4UCard>(); cards.Add(new R4UCard()); var card = cards.First(); var content = paragraph.InnerHtml; var text = paragraph.GetInnerText(); var cursor = text.AsSpanCursor(); // var space = " "; // Format: <Serial> <Rarity> <JP Name with Spaces> <strong>English Name with Spaces</strong><br> if (TryGetExceptionalSerialRarityName(cursor.CurrentLine.ToString(), out var exceptionalResults)) { cards = exceptionalResults.Select(res => { var card = new R4UCard(); card.Serial = res.Serial; card.Rarity = res.Rarity; card.Name = res.Name; return(card); }).ToList(); if (cards.Count < 1) { yield break; } card = cards.First(); } else if (serialRarityJPNameMatcher.IsMatch(content)) { var firstLineMatch = serialRarityJPNameMatcher.Match(content); card.Serial = firstLineMatch.Groups[1].Value.Trim(); card.Rarity = firstLineMatch.Groups[2].Value.Trim(); card.Name = new MultiLanguageString(); card.Name.JP = rubyMatcher.Replace(firstLineMatch.Groups[3].Value, "").Trim(); // TODO: Resolve <ruby>永<rt>えい</rt>遠<rt>えん</rt></ruby>の<ruby>巫<rt>み</rt>女<rt>こ</rt></ruby> <ruby>霊<rt>れい</rt>夢<rt>む</rt></ruby> card.Name.EN = firstLineMatch.Groups[4].Value.Trim(); } else { throw new NotImplementedException($"The serial/rarity/JP Name line cannot be parsed. Here's the offending line: {cursor.CurrentLine.ToString()}"); } var releaseID = releaseIDMatcher.Match(card.Serial).Groups[1].Value; card.Set = setMap.GetValueOrDefault(releaseID, null) ?? CreateTemporarySet(releaseID); // Format: Cost <Cost> / <Series Name> / <Traits> cursor.Next(); var secondLine = cursor.CurrentLine.ToString(); if (costSeriesTraitMatcher.IsMatch(secondLine)) { card.Type = CardType.Character; var secondLineMatch = costSeriesTraitMatcher.Match(cursor.CurrentLine.ToString()); card.Cost = int.Parse(secondLineMatch.Groups[1].Value); card.Traits = secondLineMatch.Groups[3].Value // .Split(" – ") // .Select(str => str.Trim()) // .Select(t => new MultiLanguageString() { EN = t }) // .ToList(); cursor.Next(); card.ATK = cursor.CurrentLine .Slice("ATK ".Length) .AsParsed <int>(int.TryParse); cursor.Next(); string defLine = cursor.CurrentLine.ToString(); card.DEF = cursor.CurrentLine .Slice("DEF ".Length) .AsParsed <int>(int.TryParse); Regex flavorTextMatcher = new Regex(@"" + defLine + @"<br><em>(.+)</em><br>"); if (flavorTextMatcher.IsMatch(content)) { cursor.Next(); card.Flavor = new MultiLanguageString(); card.Flavor.EN = cursor.CurrentLine.ToString(); // flavorTextMatcher.Match(content).Groups[1].Value; } } else if (seriesRebirthMatcher.IsMatch(secondLine)) { card.Type = CardType.Rebirth; var rebirthLine = secondLine; Regex flavorTextMatcher = new Regex(@"" + rebirthLine + @"<br><em>(.+)</em><br>"); if (flavorTextMatcher.IsMatch(content)) { cursor.Next(); card.Flavor = new MultiLanguageString(); card.Flavor.EN = cursor.CurrentLine.ToString(); // flavorTextMatcher.Match(content).Groups[1].Value; } } else { card.Type = CardType.Partner; card.Color = CardColor.Red; } if (card.Color != CardColor.Red) { List <MultiLanguageString> effects = new List <MultiLanguageString>(); while (cursor.Next()) { Log.Information("Adding Effect: {eff}", cursor.CurrentLine.ToString()); effects.Add(new MultiLanguageString() { EN = cursor.CurrentLine.ToString() }); } effects = Compress(effects); card.Effect = effects.ToArray(); card.Color = CardUtils.InferFromEffect(card.Effect); } yield return(card); foreach (var dupCard in cards.Skip(1)) { var detailedDupCard = card.Clone(); detailedDupCard.Serial = dupCard.Serial; detailedDupCard.Rarity = dupCard.Rarity; detailedDupCard.Name = dupCard.Name; yield return(detailedDupCard); } }
/// <summary> /// Заполнение данных о товаре с сайта поставщика /// </summary> public async Task <bool> FillByUrl() { bool res = false; if (await Loader.LoadPageAsync(Url)) { // Получение наименования товара IHtmlHeadingElement pageHeader = (IHtmlHeadingElement)Loader.Document.QuerySelectorAll("h1") .Where(item => item.TextContent.Trim().Length > 0) .FirstOrDefault(); if (pageHeader != null) { Name = pageHeader.TextContent.Trim(); } // Получение цены товара IHtmlSpanElement mainPrice = (IHtmlSpanElement)Loader.Document.QuerySelectorAll("span") .Where(item => item.Id != null && item.Id.Trim() == @"main-price") .FirstOrDefault(); if (mainPrice != null) { int mainPriceValue = 0; if (int.TryParse(mainPrice.TextContent.Trim().Replace(" ", string.Empty), out mainPriceValue)) { Price = mainPriceValue; } } // Получение старой цены товара IHtmlDivElement oldPriceElement = (IHtmlDivElement)Loader.Document.QuerySelectorAll("div") .Where(item => item.ClassName != null && item.ClassName.Contains(@"old-price")) .FirstOrDefault(); if (oldPriceElement != null) { Regex rgOldPrice = new Regex(@"^(?<value>\d+)"); Match mtOldPrice = rgOldPrice.Match(oldPriceElement.TextContent.Trim().Replace(" ", string.Empty)); if (mtOldPrice.Success) { int oldPriceValue = 0; if (int.TryParse(mtOldPrice.Groups["value"].ToString(), out oldPriceValue)) { OldPrice = oldPriceValue; } } } // Загрузка списка технических характеристик IHtmlElement techSpecSection = (IHtmlElement)Loader.Document.QuerySelectorAll("section") .Where(item => item.ClassName != null && item.ClassName.Contains(@"tech-specs")) .FirstOrDefault(); if (techSpecSection != null) { var techSpecRowsCollection = techSpecSection.QuerySelectorAll("div") .Where(item => item.ClassName != null && item.ClassName.Contains(@"row")); foreach (IHtmlDivElement techSpecRow in techSpecRowsCollection) { IHtmlSpanElement techSpecName = (IHtmlSpanElement)techSpecRow.QuerySelectorAll("span") .FirstOrDefault(); IHtmlParagraphElement techSpecValue = (IHtmlParagraphElement)techSpecRow.QuerySelectorAll("p") .Where(item => item.ClassName != null && item.ClassName.Contains(@"p-style2")) .FirstOrDefault(); if (techSpecName != null && techSpecValue != null && techSpecName.TextContent.Trim().Length > 0 && techSpecValue.TextContent.Trim().Length > 0) { Options.Add(new InventItemOption(techSpecName.TextContent.Trim(), techSpecValue.TextContent.Trim())); } } } // Загрузка описания товара IHtmlDivElement descrElement = (IHtmlDivElement)Loader.Document.QuerySelectorAll("div") .Where(item => item.Id != null && item.Id.Trim() == @"descr") .FirstOrDefault(); if (descrElement != null) { Descr = descrElement.TextContent.Trim(); } // Формирование списка изображений товара IHtmlUnorderedListElement imagesListElement = (IHtmlUnorderedListElement)Loader.Document.QuerySelectorAll("ul") .Where(item => item.ClassName != null && item.ClassName.Contains(@"pagination")) .FirstOrDefault(); if (imagesListElement != null) { var imagesListCallection = imagesListElement.QuerySelectorAll("img"); foreach (IHtmlImageElement imageItem in imagesListCallection) { if (imageItem.Source != null && imageItem.Source.Length > 0) { Images.Add(Site.PrepareUrl(imageItem.Source)); } } } res = true; } RegisterInventItem(); return(res); }