public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'deck-info')]//h1").InnerText); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//ul[@class='listado mazo-cartas']/li"); foreach (var cardNode in cardNodes) { var count = int.Parse(cardNode.SelectSingleNode(".//span[@class='cantidad']").InnerText); var name = HttpUtility.HtmlDecode(cardNode.SelectSingleNode(".//span[@class='nombreCarta']").InnerText); var card = Database.GetCardFromName(name); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck { Name = doc.DocumentNode.SelectSingleNode("//h1[@id='deck-title']").InnerText }; var cardList = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//table[@id='deck-guide']").Attributes["data-deck"].Value); cardList = cardList.Replace("\"", "").Replace("[", "").Replace("]", "").Replace("\\", ""); foreach (var cardNode in cardList.Split(',').GroupBy(x => x)) { var card = Hearthstone.Database.GetCardFromId(cardNode.Key); card.Count = cardNode.Count(); deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); deck.Name = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("/html/body/div/div[4]/div/div[2]/div/div[1]/h3").InnerText.Trim()); var cards = doc.DocumentNode.SelectNodes("//div[contains(@class, 'cardname')]/span"); var deckInfo = doc.DocumentNode.SelectSingleNode("//div[@id='subinfo']").SelectNodes("//span[contains(@class, 'midlarge')]/span"); if (deckInfo.Count == 2) { deck.Class = HttpUtility.HtmlDecode(deckInfo[0].InnerText).Trim(); var decktype = HttpUtility.HtmlDecode(deckInfo[1].InnerText).Trim(); if (!string.IsNullOrEmpty(decktype) && decktype != "None" && Config.Instance.TagDecksOnImport) { if (!DeckList.Instance.AllTags.Contains(decktype)) { DeckList.Instance.AllTags.Add(decktype); DeckList.Save(); if (Helper.MainWindow != null) // to avoid errors when running tests { Core.MainWindow.ReloadTags(); } } deck.Tags.Add(decktype); } } foreach (var cardNode in cards) { var nameString = HttpUtility.HtmlDecode(cardNode.InnerText); var match = Regex.Match(nameString, @"^\s*(\d+)\s+(.*)\s*$"); if (match.Success) { var count = match.Groups[1].Value; var name = match.Groups[2].Value; var card = Database.GetCardFromName(name); card.Count = count.Equals("2") ? 2 : 1; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
private async Task <IDictionary <int, HsReplayArchetype> > GetHsReplayArchetypes() { var json = await ImportingHelper.JsonRequest($"https://hsreplay.net/api/v1/archetypes/"); var archetypes = JsonConvert.DeserializeObject <List <HsReplayArchetype> >(json); return(archetypes.ToDictionary(a => a.Id, a => a)); }
private static async Task <Deck> ImportHearthPwn(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode( doc.DocumentNode.SelectSingleNode( "//section[contains(@class,'deck-info')]/h2[contains(@class,'deck-title')]") .InnerText); deck.Name = deckName; var cardNameNodes = doc.DocumentNode.SelectNodes("//td[contains(@class,'col-name')]//a[contains(@href,'/cards/') and contains(@class,'rarity')]"); var cardCountNodes = doc.DocumentNode.SelectNodes("//td[contains(@class,'col-name')]"); //<span class="deck-type">Midrange</span> var decktype = doc.DocumentNode.SelectSingleNode("//span[contains(@class,'deck-type')]").InnerText; if (decktype != "None" && Config.Instance.TagDecksOnImport) { if (!DeckList.Instance.AllTags.Contains(decktype)) { DeckList.Instance.AllTags.Add(decktype); DeckList.Save(); if (Core.MainWindow != null) // to avoid errors when running tests { Core.MainWindow.ReloadTags(); } } deck.Tags.Add(decktype); } var cardNames = cardNameNodes.Select(cardNameNode => HttpUtility.HtmlDecode(cardNameNode.InnerText)); var cardCosts = cardCountNodes.Select(countNode => int.Parse(Regex.Match(countNode.LastChild.InnerText, @"\d+").Value)); var cardInfo = cardNames.Zip(cardCosts, (n, c) => new { Name = n, Count = c }); foreach (var info in cardInfo) { var card = Database.GetCardFromName(info.Name.Trim()); card.Count = info.Count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
private static async Task <Deck> ImportHearthPwnDeckBuilder(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//div[contains(@class,'deck-name-container')]/h2").InnerText); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//tr[contains(@class,'deck-card-link')]"); /* <tr class="deck-card-link odd" data-tooltip-href="//www.hearthpwn.com/cards/22385-power-word-glory" * data-description="Choose a minion. Whenever it attacks, restore 4 Health to your hero." data-race="" * data-rarity="1" data-class="6" data-cost="1" data-hp="0" data-attack="0" * data-image="http://media-Hearth.cursecdn.com/avatars/252/489/22385.png" data-type="5" data-id="22385" * data-name="Power Word: Glory" data-mechanics=""> */ Dictionary <int, string> cardDatabase = new Dictionary <int, string>(); foreach (var cardtr in cardNodes) { var cardId = cardtr.GetAttributeValue("data-id", -1); var cardName = HttpUtility.HtmlDecode(cardtr.GetAttributeValue("data-name", "")); cardDatabase[cardId] = cardName; } // http://www.hearthpwn.com/deckbuilder/priest#38:1;117:2;207:2;212:2;346:2;395:2;409:2;415:2;431:2;435:2;544:1;554:2;600:2;7750:2;7753:2;7755:2; var cardMatches = Regex.Matches(url, @"(\d+):(\d+)"); foreach (Match cardMatch in cardMatches) { var cardId = int.Parse(cardMatch.Groups[1].Value); var cardCount = int.Parse(cardMatch.Groups[2].Value); var cardName = cardDatabase[cardId]; var card = Database.GetCardFromName(cardName); card.Count = cardCount; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
public static async Task <Deck> Import(string url) { try { // check url looks correct var match = Regex.Match(url, "/decks/([^/]+)$"); // get deck name from url, and post the json request if (match.Success && match.Groups.Count == 2) { var slug = match.Groups[1].ToString(); var param = "{\"where\":{\"slug\":\"" + slug + "\"},\"fields\":{},\"include\":[{\"relation\":\"cards\",\"scope\":{\"include\":[\"card\"]}}]}"; var data = await ImportingHelper.JsonRequest("https://tempostorm.com/api/decks/findOne?filter=" + param); //parse json var jsonObject = JsonConvert.DeserializeObject <dynamic>(data); if (jsonObject.error == null) { var deck = new Deck(); deck.Name = jsonObject.name.ToString(); var cards = jsonObject.cards; foreach (var item in cards) { var card = Database.GetCardFromName(item.card.name.ToString()); card.Count = item.cardQuantity.ToString().Equals("2") ? 2 : 1; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } throw new Exception("JSON request failed for '" + slug + "'."); } throw new Exception("The url (" + url + ") is not a vaild TempoStorm deck."); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { // check url looks correct var pattern = "/decks/([^/]+)$"; var match = Regex.Match(url, pattern); // get deck name from url, and post the json request if (match.Success && match.Groups.Count == 2) { var slug = match.Groups[1].ToString(); var data = await ImportingHelper.PostJson("https://tempostorm.com/deck", "{\"slug\": \"" + slug + "\"}"); // parse json var jsonObject = JsonConvert.DeserializeObject <dynamic>(data); if (jsonObject.success.ToObject <bool>()) { var deck = new Deck(); deck.Name = jsonObject.deck.name.ToString(); //deck.Class = jsonObject.deck.playerClass.ToString(); var cards = jsonObject.deck.cards; foreach (var item in cards) { var card = Database.GetCardFromName(item.card.name.ToString()); card.Count = item.qty.ToString().Equals("2") ? 2 : 1; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } throw new Exception("JSON request failed for '" + slug + "'."); } throw new Exception("The url (" + url + ") is not a vaild TempoStorm deck."); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//*[@id='deck-list-title']").InnerText); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//div[contains(@class,'guide-deck-list')]/div/div[contains(@class,'card')]"); foreach (var cardNode in cardNodes) { //silly names contain right-single quotation mark var cardName = cardNode.SelectSingleNode(".//span[contains(@class, 'card-title')]") .InnerText.Replace("’", "'") .Replace("‘", "'"); var name = HttpUtility.HtmlDecode(cardName); //no count there if count == 1 var countNode = cardNode.SelectSingleNode(".//span[contains(@class, 'card-count')]"); var count = 1; if (countNode != null) { count = int.Parse(countNode.InnerText); } var card = Database.GetCardFromName(name); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } card.Count = count; deck.Cards.Add(card); } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckRoot = doc.DocumentNode.SelectSingleNode("//div[@class='decklist-meta-data']"); var deckInfo = deckRoot.SelectNodes(".//div[@class='row']/div"); if (deckInfo.Count != 3) { Log.Error("Wrong number of columns."); return(null); } // get metadata deck.Name = HttpUtility.HtmlDecode(deckRoot.SelectSingleNode(".//h2/a").InnerText).Trim(); var deckType = HttpUtility.HtmlDecode(deckInfo[0].SelectNodes(".//p")[2].InnerText).Trim(); if (!string.IsNullOrWhiteSpace(deckType) && Config.Instance.TagDecksOnImport) { if (!DeckList.Instance.AllTags.Contains(deckType)) { DeckList.Instance.AllTags.Add(deckType); DeckList.Save(); if (Core.MainWindow != null) // to avoid errors when running tests { Core.MainWindow.ReloadTags(); } } deck.Tags.Add(deckType); } // get cards CardNodes(deckInfo[1], deck); CardNodes(deckInfo[2], deck); return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { if (!url.Contains("http://www.")) { url = "http://www." + url.Split('.').Skip(1).Aggregate((c, n) => c + "." + n); } // don't seem to need to Get with WebBrowser anymore var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//*[@id='deckguide-name']").InnerText); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//*[contains(@class,'deckguide-cards-type')]//ul//li"); foreach (var cardNode in cardNodes) { var nameRaw = cardNode.SelectSingleNode(".//a").InnerText; var name = HttpUtility.HtmlDecode(nameRaw); var count = cardNode.InnerText.Remove(0, nameRaw.Length - 1).Contains("2") ? 2 : 1; var card = Database.GetCardFromName(name); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
private async Task <string> MulliganWinrate(string cardName) { try { if (_doc == null) { _doc = await ImportingHelper.GetHtmlDoc(ActiveDeckUrl()); } var ournode = _doc.DocumentNode.SelectNodes("//span[@class=\"card-name\"]").First(x => x.InnerText == cardName); return(HttpUtility.HtmlDecode(ournode.SelectSingleNode("//ancestor::tr/td[@class=\"winrate-cell\"][1]").InnerText)); } catch (Exception ex) { Log.Error("Unable to get Mulligan Winrate ->"); Log.Error(ex); return("error"); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'single-deck-title-wrap')]/h2").InnerText); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//table[contains(@class, 'cards-table')]/tbody/tr/td[1]/div"); foreach (var cardNode in cardNodes) { var nameString = HttpUtility.HtmlDecode(cardNode.InnerText); var match = Regex.Match(nameString, @"^\s*(.*)\s*(x 2)?\s*$"); if (match.Success) { var name = match.Groups[1].Value; var count = match.Groups[2].Value; var card = Database.GetCardFromName(name); card.Count = String.IsNullOrEmpty(count) ? 1 : 2; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck { IsArenaDeck = true }; var cardNodes = doc.DocumentNode.SelectSingleNode(".//ul[@class='deckList']"); var nameNodes = cardNodes.SelectNodes(".//span[@class='name']"); var countNodes = cardNodes.SelectNodes(".//span[@class='quantity']"); var numberOfCards = nameNodes.Count; for (var i = 0; i < numberOfCards; i++) { var nameRaw = nameNodes.ElementAt(i).InnerText; var name = HttpUtility.HtmlDecode(nameRaw); var card = Hearthstone.Database.GetCardFromName(name); card.Count = int.Parse(countNodes.ElementAt(i).InnerText); deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } if (DeckList.Instance.AllTags.Contains("Arena")) { deck.Tags.Add("Arena"); } deck.Name = Helper.ParseDeckNameTemplate(Config.Instance.ArenaDeckNameTemplate, deck); return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDocGzip(url); var deck = new Deck { Name = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//header[@class='panel-heading']/h1[@class='panel-title']").InnerText) .Trim() }; var nodes = doc.DocumentNode.SelectNodes("//*[@id='list']/div/table/tbody/tr"); foreach (var cardNode in nodes) { var name = HttpUtility.HtmlDecode(cardNode.SelectSingleNode(".//a").Attributes[3].Value); var temp = HttpUtility.HtmlDecode(cardNode.SelectSingleNode(".//span[@class='text-muted']").InnerText[0].ToString()); var count = int.Parse(temp); var card = Database.GetCardFromName(name); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//h2[contains(@class, 'dname')]").InnerText); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//ul[@class='vminionslist' or @class='vspellslist']/li"); foreach (var cardNode in cardNodes) { var count = int.Parse(cardNode.SelectSingleNode(".//span[@class='cantidad']").InnerText); var name = HttpUtility.HtmlDecode( cardNode.SelectSingleNode( ".//span[@class='nombreCarta rarity_legendary' or @class='nombreCarta rarity_epic' or @class='nombreCarta rarity_rare' or @class='nombreCarta rarity_common' or @class='nombreCarta rarity_basic']") .InnerText); var card = Database.GetCardFromName(name); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck { Name = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//*[@id='content']/div[contains(@class, 'deck')]/h1").InnerText).Trim() }; var nodes = doc.DocumentNode.SelectNodes("//a[@real_id]"); foreach (var cardNode in nodes) { var id = cardNode.Attributes["real_id"].Value; var count = int.Parse(cardNode.Attributes["nb_card"].Value); var card = Hearthstone.Database.GetCardFromId(id); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//h1[contains(@class,'page-title')]").FirstChild.InnerText); deck.Name = deckName; var cardNameNodes = doc.DocumentNode.SelectNodes("//div[contains(@class,'name')]"); var cardCountNodes = doc.DocumentNode.SelectNodes("//div[contains(@class,'qty')]"); var cardNames = cardNameNodes.Select(cardNameNode => HttpUtility.HtmlDecode(cardNameNode.InnerText)); var cardCosts = cardCountNodes.Select(countNode => int.Parse(countNode.InnerText)); var cardInfo = cardNames.Zip(cardCosts, (n, c) => new { Name = n, Count = c }); foreach (var info in cardInfo) { var card = Database.GetCardFromName(info.Name); card.Count = info.Count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var titleNode = doc.DocumentNode.SelectSingleNode("//div[contains(@class,'header__title internal')]/div[contains(@class,'container')]/h1"); var cardNodes = doc.DocumentNode.SelectNodes("//ul[contains(@class,'list-unstyled cartas_list')]/li"); var deck = new Deck(); deck.Name = HttpUtility.HtmlDecode(titleNode.ChildNodes.FirstOrDefault(x => x.Name == "#text").InnerText); foreach (var node in cardNodes) { var nameNode = node.SelectSingleNode("span[contains(@class,'cartas__name')]/a"); var countNode = node.SelectSingleNode("span[contains(@class,'cartas__qtd')]"); var validChild = countNode?.ChildNodes.SingleOrDefault(c => c.Name == "#text"); var id = nameNode.Attributes.FirstOrDefault(a => a.Name == "data-hcfw-card-id").Value; var count = validChild != null?int.Parse(countNode.InnerText) : 1; var card = Database.GetCardFromId(id); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//header[@class='entry-header']/h1[@class='entry-title']").InnerText); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//ul[contains(@class,'deck-class')]/li"); foreach (var cardNode in cardNodes) { var name = HttpUtility.HtmlDecode(cardNode.SelectSingleNode(".//a/span[@class='card-name']").InnerText); var count = int.Parse(HttpUtility.HtmlDecode(cardNode.SelectSingleNode(".//span[@class='card-count']").InnerText)); var card = Database.GetCardFromName(name.Replace("’", "'")); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var deckName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode("//span[contains(@class, 'deckName')]").InnerText).Trim(); deck.Name = deckName; var cardNodes = doc.DocumentNode.SelectNodes("//table[@class='deck_card_list']/tbody/tr/td/a[@class='real_id']"); foreach (var cardNode in cardNodes) { var id = cardNode.Attributes["real_id"].Value; var count = int.Parse(cardNode.Attributes["nb_card"].Value); var card = Database.GetCardFromId(id); card.Count = count; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } return(deck); } catch (Exception e) { Logger.WriteLine(e.ToString(), "DeckImporter"); return(null); } }
/// <summary> /// Gets all decks from HSReplay. /// </summary> /// <param name="archetypes">The HSReplay archetypes</param> /// <param name="progress">Tuple of two integers holding the progress information for the UI</param> /// <returns>The list of all parsed decks</returns> private async Task <IList <Deck> > GetHsreplayDecks(IDictionary <int, HsReplayArchetype> archetypes, string gameType, IProgress <Tuple <int, int> > progress) { var pattern = @"(\[\d+,[12]{1}\])"; var json = await ImportingHelper.JsonRequest($"https://hsreplay.net/analytics/query/list_decks_by_win_rate_v2/?GameType={gameType}"); var decks = JsonConvert.DeserializeObject <HsReplayDecks>(json).Series.Data; return(decks.SelectMany(x => decks[x.Key].Select(d => { // Count found decks thread-safe Interlocked.Increment(ref _decksFound); // Get the archetype or default HsReplayArchetype archetype; if (!archetypes.ContainsKey(d.ArchetypeId)) { archetype = new HsReplayArchetype(); archetype.Name = "Other"; archetype.Url = $"/archetypes/{d.ArchetypeId}"; archetype.Class = HsReplayNameToClassId[x.Key]; } else { archetype = archetypes[d.ArchetypeId]; } // Create new deck var deck = new Deck(); deck.Name = archetype.Name; deck.Url = archetype.Url; deck.Class = HsReplayClassIdToName[archetype.Class]; // Insert deck note for statistics deck.Note = $"#Games: {d.TotalGames}, #Win Rate: {d.WinRate}%"; // Set import datetime as LastEdited deck.LastEdited = DateTime.Now; var matches = Regex.Matches(d.DeckList, pattern); foreach (Match match in matches) { var matchText = match.Value.Trim('[', ']'); // Get card from database with dbf id var card = Database.GetCardFromDbfId(int.Parse(matchText.Split(',')[0])); card.Count = int.Parse(matchText.Split(',')[1]); deck.Cards.Add(card); } // Count imported decks thread-safe Interlocked.Increment(ref _decksImported); // Report progress for UI progress.Report(new Tuple <int, int>(_decksImported, _decksFound)); return deck; })).ToList()); }
public static async Task <Deck> Import(string url) { try { var doc = await ImportingHelper.GetHtmlDoc(url); var deck = new Deck(); var dname = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode( "//h1[contains(@class, 'panel-title')]").InnerText); deck.Name = Regex.Replace(dname, @"\s+", " "); // remove sequence of tabs var cards = doc.DocumentNode.SelectNodes("//div[contains(@class, 'cardname')]/span"); var deckExtra = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'deck_banner_description')]"); var deckInfo = deckExtra.SelectNodes("//span[contains(@class, 'midlarge')]/span"); // get class and tags if (deckInfo.Count == 3) { deck.Class = HttpUtility.HtmlDecode(deckInfo[1].InnerText).Trim(); var decktype = HttpUtility.HtmlDecode(deckInfo[2].InnerText).Trim(); if (!string.IsNullOrWhiteSpace(decktype) && decktype != "None" && Config.Instance.TagDecksOnImport) { if (!DeckList.Instance.AllTags.Contains(decktype)) { DeckList.Instance.AllTags.Add(decktype); DeckList.Save(); if (Core.MainWindow != null) // to avoid errors when running tests { Core.MainWindow.ReloadTags(); } } deck.Tags.Add(decktype); } } // TODO uncomment for standard/wild tags /* * var deckFormat = deckExtra.SelectSingleNode("//span[contains(@class, 'small')]").InnerText.Trim(); * if(!string.IsNullOrWhiteSpace(deckFormat) && Config.Instance.TagDecksOnImport) * { * var format = "Standard"; * if(Regex.IsMatch(deckFormat, @"Format:\s*Wild")) * format = "Wild"; * if(!DeckList.Instance.AllTags.Contains(format)) * { * DeckList.Instance.AllTags.Add(format); * DeckList.Save(); * if(Core.MainWindow != null) // to avoid errors when running tests * Core.MainWindow.ReloadTags(); * } * deck.Tags.Add(format); * } */ foreach (var cardNode in cards) { var nameString = HttpUtility.HtmlDecode(cardNode.InnerText); var match = Regex.Match(nameString, @"^\s*(\d+)\s+(.*)\s*$"); if (match.Success) { var count = match.Groups[1].Value; var name = match.Groups[2].Value; var card = Database.GetCardFromName(name); card.Count = count.Equals("2") ? 2 : 1; deck.Cards.Add(card); if (string.IsNullOrEmpty(deck.Class) && card.PlayerClass != "Neutral") { deck.Class = card.PlayerClass; } } } return(deck); } catch (Exception e) { Log.Error(e); return(null); } }