private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { WixossCard wixCard = e.UserState as WixossCard; String newLine = Environment.NewLine; String hadError = e.Error == null ? newLine + "Passed " : newLine + e.Error.InnerException.Message + newLine; AuditLog.log(hadError + "Card Name: " + wixCard.CardName + newLine, "Images Updated.txt"); }
private void setEffect(HtmlNode tableNode, WixossCard wixossCard) { // First the *second* table HtmlNode effectTable = tableNode.Descendants().Where (x => (x.Name == "table")).ToList()[1]; // Check if the table is the 'card abilities' table if (HTMLHelper.TableHeaderContains(effectTable, "Card Abilities")) { HTMLHelper.getCardEffect(effectTable, ref wixossCard); } }
public static void handleCardCost(HtmlNode costRow, ref WixossCard wixossCard) { // Find all 'a' tags List <HtmlNode> imgNodes = costRow.Descendants().Where (x => (x.Name == "a")).ToList(); List <CardCost> costForCard = new List <CardCost>(); List <long> cardCostList = new List <long>(); // Loop thru all card cost values // We first removeHTML then split it based on 'x' // i.e 1Gx1W becomes ['1G','1W'] foreach (var item in removeHTML(costRow.InnerText).Split(new String[] { " x " }, StringSplitOptions.RemoveEmptyEntries)) { // Make sure its not just whitespace if (item.Trim() != "") { String cleanedItem = item; // sometimes its an 'or' not just 'x' if (item.Contains("or")) { cleanedItem = item.Split(' ')[0]; } cardCostList.Add(Convert.ToInt16(cleanedItem.Trim())); } } // Loop thru all img nodes, because those contain what color to use for (int i = 0; i < imgNodes.Count; i++) { CardCost cost = new CardCost(); if (i < cardCostList.Count) { cost.NumberPerColor = (int)cardCostList[i]; } else { cost.NumberPerColor = 0; } cost.Color = colorFromName(imgNodes[i].Attributes["title"].Value); costForCard.Add(cost); } wixossCard.Cost = costForCard; }
public static void handleCardColor(HtmlNode colorRow, ref WixossCard wixossCard) { // Find all 'img' tags List <HtmlNode> imgNodes = colorRow.Descendants().Where (x => (x.Name == "img")).ToList(); List <CardColor> colorsForCard = new List <CardColor>(); // Loop thru all imgNodes foreach (var imgNode in imgNodes) { // Add the color based on the imgNode's 'alt' attr colorsForCard.Add(colorFromName(imgNode.Attributes["alt"].Value)); } wixossCard.Color = colorsForCard; }
// The main method // This is were all the magic happens public WixossCard GetCardFromUrl(String urlOfCard) { WixossCard wixossCard = new WixossCard(); var html = new HtmlDocument(); html.LoadHtml(new WebClient().DownloadString(urlOfCard)); var root = html.DocumentNode; // Find all div tags that have an id of 'cftable' // i.e. <div id='cftable'></div> List <HtmlNode> cardTable = html.DocumentNode.Descendants().Where (x => (x.Name == "div" && x.Attributes["id"] != null && x.Attributes["id"].Value.Contains("cftable"))).ToList(); // assuming we found a table, set up the get the card if (cardTable.Count != 0) { wixossCard.CardName = getCardName(cardTable[0]);//info-main setUpCard(cardTable[0], wixossCard); } // Find the image // In this case, we are looking for an 'img' tag that has a width and height of 250 and that starts with 3 (30, 300, 3XX) List <HtmlNode> imageTable = html.DocumentNode.Descendants().Where (x => (x.Name == "img" && x.Attributes["width"] != null && x.Attributes["width"].Value.Contains("250") && x.Attributes["height"] != null && (x.Attributes["height"].Value.StartsWith("3")))).ToList(); wixossCard.CardUrl = urlOfCard; // Assuming we found the image, set the cards image url to that's 'src' if (imageTable.Count != 0) { // Set image url to the first found 'img' tag via its 'src' attr // i.e. '<img src='BLAH BLAH.jpg'> wixossCard.ImageUrl = imageTable[0].Attributes["src"].Value; } return(wixossCard); }
// The real main method. // Updates the passed in 'wixossCard' object private void setUpCard(HtmlNode tableNode, WixossCard wixossCard) { // Find a div that has a class of 'info-main' // <div class='info-main'></div> HtmlNode infoTable = tableNode.Descendants().Where (x => (x.Name == "div" && x.Attributes["class"] != null && x.Attributes["class"].Value.Contains("info-main"))).ToList()[0]; // Find the first table in 'infoTable' infoTable = infoTable.Descendants().Where (x => (x.Name == "table")).ToList()[0]; // Convert each row in table into a hash map // Key: title // Value: HTML Node (the value) Dictionary <String, HtmlNode> tableMap = htmlTableToDictionary(infoTable); setInfoTable(tableMap, wixossCard); setEffect(tableNode, wixossCard); setCardSetInfo(tableNode, wixossCard); }
// Method to get cards private void updateCardsWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; int setCount = 0; // Loop thru cardSets foreach (var cardSet in cardSets) { setCount++; // Get a hashmap of all the sets card // Key: Card URL // Value: Number of cards (This only really matters for decks) Dictionary <String, int> cardList = cardMaker.GetCardsFromUrl(cardSet.Value); List <WixossCard> setCards = new List <WixossCard>(); worker.ReportProgress(cardList.Values.Count, "Card Set Count"); worker.ReportProgress(setCount, "Card Set Value"); int cardCount = 0; // Loop thru all cards in the set foreach (var cardItem in cardList) { cardCount++; worker.ReportProgress(cardCount, "Card Value"); // Get card from url WixossCard theCard = cardMaker.GetCardFromUrl(cardItem.Key); // Create or update the card to sql lite db WixCardService.CreateOrUpdate(theCard); } worker.ReportProgress(-1, "Set: " + cardSet + " updated"); } worker.ReportProgress(setCount + 1, "Card Set Value"); }
private void setCardSetInfo(HtmlNode tableNode, WixossCard wixossCard) { HtmlNode setTable = null; // Find all table elements List <HtmlNode> tableNodes = tableNode.Descendants().Where (x => (x.Name == "table")).ToList(); // Look for the one true 'setTable' foreach (var theTableNode in tableNodes) { // Check if the table contins 'Sets' in the header if (HTMLHelper.TableHeaderContains(theTableNode, "Sets")) { setTable = theTableNode; } } // make sure the 'setTable' is not null if (setTable != null) { // loop thru all row data foreach (var setInfo in HTMLHelper.getRowData(setTable, "Sets")) { // make sure it's not null or blank... well i guess just blank if (setInfo != "") { HtmlDocument htmlTableData = new HtmlDocument(); htmlTableData.LoadHtml(setInfo); // Look for all 'a' tags that have a title and href contain 'WX' or 'SP' // <a title='anything' href='asdasdasWXdasdadasd'></a> var aTags = htmlTableData.DocumentNode.Descendants("a") .Where(d => d.Attributes.Contains("title") && ( d.Attributes["href"].Value.Contains("WX") || d.Attributes["href"].Value.Contains("SP")) ); // Loop thru all 'a' tags foreach (var aTag in aTags) { //A very cheap way to do this. //Will have to update if they ever do in the three digits // Set setName to the tags 'href' value String setName = aTag.Attributes["href"].Value; // The 'cheap' thing. Sometimes we grab 'WXD' instead of 'WX' // this throws all sub string logic out of wack // to avoid this will increase the count by one based on 'WXD' or 'WX' int maxCount = setName.Contains("WXD") ? 6 : 5; setName = setName.Substring(setName.LastIndexOf("/") + 1, maxCount); wixossCard.CardSets.Add(setName); } } } } }
private void setInfoTable(Dictionary <String, HtmlNode> tableMap, WixossCard wixossCard) { // loop thru all keys and set up the 'wixossCard' based on the keys foreach (var key in tableMap.Keys) { switch (key) { case "LevelLimit": try { wixossCard.LevelLimit = Convert.ToInt16(tableMap[key].FirstChild.InnerText.Trim()); } catch (Exception ex) { wixossCard.LevelLimit = 0; } break; case "Card Type": wixossCard.Type = (CardType)Enum.Parse(typeof(CardType), tableMap[key].ChildNodes[1].InnerText.Trim()); break; case "Level": wixossCard.Level = Convert.ToInt16(tableMap[key].FirstChild.InnerText.Trim()); break; case "Color": HTMLHelper.handleCardColor(tableMap[key], ref wixossCard); break; case "Grow Cost": HTMLHelper.handleCardCost(tableMap[key], ref wixossCard); break; case "Cost": HTMLHelper.handleCardCost(tableMap[key], ref wixossCard); break; case "Power": wixossCard.Power = Convert.ToInt16(tableMap[key].FirstChild.InnerText.Trim()); break; case "Class": wixossCard.Class.Add(tableMap[key].ChildNodes[1].InnerText.Trim()); break; case "Use Timing": // Regular expression, aka magical string // I have long since forgotten what this is suppose to match var pattern = @"\[(.*?)\]"; var matches = Regex.Matches(tableMap[key].FirstChild.InnerText.Trim(), pattern); // For each match, add it as the correct timing foreach (Match m in matches) { switch (m.Groups[1].Value) { case "Attack Phase": wixossCard.Timing.Add(CardTiming.AttackPhase); break; case "Main Phase": wixossCard.Timing.Add(CardTiming.MainPhase); break; case "Spell Cut-In": wixossCard.Timing.Add(CardTiming.SpellCutIn); break; default: break; } } break; } } }
public static void getCardEffect(HtmlNode effect, ref WixossCard wixossCard) { String cardEffect = ""; // Find the first 'td' effect = effect.Descendants().Where (x => (x.Name == "td")).ToList()[0]; // Loop thru all decendants as well as itself foreach (var node in effect.DescendantsAndSelf()) { // check if it has child // if not do nothing if (!node.HasChildNodes) { // Convert br to new line if (node.Name == "br") { cardEffect += "\n"; } // Check if the node is an image that has class with nothing // <img class=""></img> if (node.Name == "img" && node.Attributes["class"].Value == "") { // The 'alt' attr has what the image is suppose to be. In this case only lifeburst cardEffect += "{" + node.Attributes["alt"].Value + "}"; switch (node.Attributes["alt"].Value) { case "Lifeburst": // set the lifeburst value to ture wixossCard.LifeBurst = true; break; default: break; } } // Check if the effect contains 'Guard' if (node.InnerText == "Guard") { wixossCard.Guard = true; } // Check if the effect has 'Multi Ener' if (node.InnerText == "Multi Ener") { wixossCard.MultiEner = true; } string text = node.InnerText; // Make sure the text is not null or empty // Then remove an html value or convert them to real values if (!string.IsNullOrEmpty(text)) { cardEffect += removeHTML(text); } } } //Check timing if (cardEffect.Contains("Use Timing")) { cardEffect = cardEffect.Replace("Use Timing", ""); // Theres that magical string again... still don't know what it matches var pattern = @"\[(.*?)\]"; var matches = Regex.Matches(cardEffect, pattern); // Find every match and set timming on the card accordingly foreach (Match m in matches) { switch (m.Groups[1].Value) { case "Attack Phase": wixossCard.Timing.Add(CardTiming.AttackPhase); cardEffect = cardEffect.Replace("[Attack Phase]", ""); break; case "Main Phase": wixossCard.Timing.Add(CardTiming.MainPhase); cardEffect = cardEffect.Replace("[Main Phase]", ""); break; case "Spell Cut-In": wixossCard.Timing.Add(CardTiming.SpellCutIn); cardEffect = cardEffect.Replace("[Spell Cut-In]", ""); break; default: break; } } } // Remove any HTML and remove whitespace on both sides wixossCard.CardEffect = removeHTML(cardEffect).Trim(); }