public async Task <PrimeItemData> GetData(string wikiUrl) { // Ash Prime for some reason acts differently and gives a redirect to /wiki/Ash#Prime instead of loading the page /wiki/Ash/Prime if (wikiUrl.Contains("Ash_Prime")) { wikiUrl = wikiUrl.Replace("Ash_Prime", "Ash/Prime"); } var web = new HtmlWeb(); var doc = await web.LoadFromWebAsync($"{BaseUrl}{wikiUrl}"); // Select where image should normally be var img = doc.DocumentNode.SelectSingleNode(@"//*[@id='mw-content-text']//aside//img"); string src; if (img != null) { src = img.Attributes["data-src"]?.Value; // In case of prime item if (string.IsNullOrEmpty(src)) { // In case of prime warframe src = img.Attributes["src"]?.Value; } } else { // In case of kavasa prime collar var selected = doc.DocumentNode.SelectNodes(@"//*[@id='mw-content-text']/div/a[contains(@class, 'image-thumbnail')]/img"); img = doc.DocumentNode.SelectNodes(@"//*[@id='mw-content-text']/div/a[contains(@class, 'image-thumbnail')]/img").First(); src = img.Attributes["data-src"]?.Value ?? img.Attributes["src"]?.Value; } if (src == null) { throw new ApplicationException("Could not find an appropriate image on " + wikiUrl); } var result = new PrimeItemData(); using (var webClient = new WebClient()) { result.Image = webClient.OpenRead(new Uri(src)); } AddPartData(result, doc); return(result); }
/// <inheritdoc /> public async Task <PrimeItem> AddOrUpdatePrimeItem(PrimeItem primeItem, PrimeItemData itemData) { // Create a base group for Ingredients foreach (var ingredientGroupData in itemData.PartsData) { // Create the ingredients group var groupName = ingredientGroupData.Key; if (string.IsNullOrEmpty(groupName)) { groupName = null; } var group = await AddOrUpdatePeristentItem( new IngredientsGroup() { Name = groupName, PrimeItemId = primeItem.Id, PrimeItem = primeItem, }, (dest, source, _) => { if (dest.Name != source.Name) { dest.Name = source.Name; } if (dest.PrimeItemId != source.PrimeItemId) { dest.PrimeItemId = source.PrimeItemId; dest.PrimeItem = source.PrimeItem; } // Always completely clear the ingredients list if (dest.ResourceIngredients.Count > 0) { dest.ResourceIngredients.Clear(); } }); // Add all ingredients to it foreach (var ingredientData in ingredientGroupData.Value) { // Get the image var data = await StreamToByteArray(ingredientData.Image); // If part was found, update count and image var foundPart = primeItem.PrimePartIngredients.FirstOrDefault(x => x.PrimePart.Name.StartsWith(ingredientData.Name)); if (foundPart != null) { foundPart.Count = ingredientData.Count; // Add image var partImage = await AddOrUpdatePeristentItem( new Image() { Data = data }, (dest, source, _) => dest.Data = source.Data ); foundPart.PrimePart.ImageId = partImage.Id; foundPart.PrimePart.Image = partImage; } // It's also a resource, so create or update it also as a resource var resourceImage = await AddOrUpdatePeristentItem( new Image() { Data = data }, (dest, source, _) => dest.Data = source.Data ); var resource = await AddOrUpdatePeristentItem( new Resource() { Name = ingredientData.Name, ImageId = resourceImage.Id, Image = resourceImage, }, (dest, source, _) => { if (dest.Name != source.Name) { dest.Name = source.Name; } if (dest.ImageId != source.ImageId) { dest.ImageId = source.ImageId; dest.Image = source.Image; } }); var resourceIngredient = await AddOrUpdateItem( new ResourceIngredient() { ResourceId = resource.Id, Resource = resource, IngredientsGroupId = group.Id, IngredientsGroup = group, Count = ingredientData.Count, }, i => new object[] { i.IngredientsGroupId, i.ResourceId }, (dest, source, entry) => { if (dest.ResourceId != source.ResourceId) { dest.ResourceId = source.ResourceId; dest.Resource = source.Resource; } if (dest.IngredientsGroupId != source.IngredientsGroupId) { dest.IngredientsGroupId = source.IngredientsGroupId; dest.IngredientsGroup = source.IngredientsGroup; } if (dest.Count != source.Count) { dest.Count = source.Count; } } ); } } // Add the image var image = await AddOrUpdatePeristentItem( new Image() { Data = await StreamToByteArray(itemData.Image), }, (dest, source, _) => dest.Data = source.Data ); primeItem.ImageId = image.Id; primeItem.Image = image; return(primeItem); }
private void AddPartData(PrimeItemData data, HtmlDocument doc) { var cells = doc.DocumentNode.SelectNodes(@"//*[@id='mw-content-text']/table[@class='foundrytable']/tr/td"); var currentKey = ""; foreach (var cell in cells) { // Check if drop locations was found if (cell.InnerText.Contains("Drop Locations")) { // End of the important stuff, skip the rest break; } // Check if next part is encountered if (cell.Attributes["colspan"]?.Value == "6") { // Set key if so currentKey = cell.InnerText.Trim(); continue; } // The table always has an anchor if there is an ingredient var a = cell.SelectSingleNode(@"./a"); if (a == null) { continue; } // Get name of part var title = a.Attributes["title"]?.Value; if (string.IsNullOrEmpty(title)) { continue; } title = HttpUtility.HtmlDecode(title); // Get count var innerText = cell.InnerText.Replace(",", "").Trim(); int count; if (string.IsNullOrWhiteSpace(innerText)) { count = 1; } else if (int.TryParse(innerText, out var tmpCount)) { count = tmpCount; } else { continue; } // Check now if data already exists // If it does, we don't bother getting the image again if (data.PartsData.TryGetValue(currentKey, out var partDataList)) { var existing = partDataList.FirstOrDefault(p => p.Name == title); if (existing != null) { existing.Count += count; continue; } } // Get image var img = a.SelectSingleNode(@"./img"); var src = img?.Attributes["data-src"]?.Value ?? img?.Attributes["src"]?.Value; if (src == null) { continue; } var regex = new Regex(@"/scale-to-width-down/(\d+)"); src = regex.Replace(src, "/scale-to-width-down/150", 1); Stream image; using (var webClient = new WebClient()) { try { image = webClient.OpenRead(new Uri(src)); } catch (Exception) { continue; } } // Add data var partData = new PrimePartData() { Name = title, Count = count, Image = image, }; if (!data.PartsData.ContainsKey(currentKey)) { data.PartsData.Add(currentKey, new List <PrimePartData>()); } data.PartsData[currentKey].Add(partData); } }