public async Task <LootItemViewModel> AddLootByTauheadURL(int campaignId, string url, bool showApplyButton = false, bool showLootEditControls = true) { var campaign = _dbContext.Campaign.SingleOrDefault(c => c.Id == campaignId); if (campaign == null) { return(null); } var itemData = await _tauHead.GetItemData(url); if (itemData == null) // Failed to parse TauHead data or no connection { return(null); } var existingItem = _dbContext.Item.SingleOrDefault(i => i.Slug == itemData.Slug); if (existingItem == null) { await _dbContext.AddAsync(itemData); //TODO: Not sure if needed here - might be logical to perform a save at the end of the method only await _dbContext.SaveChangesAsync(); existingItem = itemData; } var campaignLootItem = new CampaignLoot { CampaignId = campaignId, ItemId = existingItem.Id, Status = CampaignLoot.CampaignLootStatus.Undistributed, }; await _dbContext.AddAsync(campaignLootItem); await _dbContext.SaveChangesAsync(); var players = _dbContext.Player.Where(p => p.SyndicateId == campaign.SyndicateId).OrderBy(p => p.Name).AsEnumerable(); var model = new LootItemViewModel { Loot = campaignLootItem, ShowApplyButton = showApplyButton, ShowEditControls = showLootEditControls, LootStatuses = EnumExtensions.ToDictionary <int>(typeof(CampaignLoot.CampaignLootStatus)), Players = players, }; return(model); }
public async Task <CampaignPageParseResultViewModel> ParseCampaignPage(string fileContents, int campaignId) { var campaign = _dbContext.Campaign.SingleOrDefault(c => c.Id == campaignId); if (campaign == null) { return(null); } var model = new CampaignPageParseResultViewModel { ErrorMessages = new List <string>(), SuccessMessages = new List <string>(), WarningMessages = new List <string>() }; var document = new HtmlDocument(); document.LoadHtml(fileContents); var epicImages = document.DocumentNode.SelectNodes("//div[contains(concat(\" \",normalize-space(@class),\" \"),\" epic \")]/img"); var leaderboardLines = document.DocumentNode.SelectNodes("//div[@id=\"campaign-result-leaderboard\"]/table/tbody/tr"); if (epicImages != null) { foreach (var epicNode in epicImages) { var countBlock = epicNode.ParentNode.ParentNode.NextSibling.NextSibling; var countLine = countBlock.Descendants("#text").FirstOrDefault().InnerText.Trim().TrimEnd(' ', 'x'); var count = 1; if (!int.TryParse(countLine, out count)) { count = 1; } var linkifyLinks = countBlock.Descendants("a"); if (linkifyLinks.Count() > 0) { var url = linkifyLinks.First().Attributes["href"].Value; var urlParts = url.Split('/'); var slug = urlParts.Last(); var epic = _dbContext.Item.SingleOrDefault(i => i.Slug == slug); if (epic == null) { epic = await _tauHead.GetItemData(_tauHead.UrlFromSlug(slug)); if (epic == null) // Item is missing from TauHead { model.ErrorMessages.Add( string.Format( "Item with slug {0} is missing from TauHead! Please contact Dotsent and firefu.", slug )); } else { model.SuccessMessages.Add( string.Format( "Item with slug {0} has been successfully imported from TauHead.", slug )); await _dbContext.AddAsync(epic); await _dbContext.SaveChangesAsync(); } } if (epic != null) { if (epic.Type == Item.ItemType.Armor || epic.Type == Item.ItemType.Weapon) { var existingLootCount = _dbContext.CampaignLoot.Count(cl => cl.ItemId == epic.Id && cl.CampaignId == campaignId); while (existingLootCount < count) { var loot = new CampaignLoot { CampaignId = campaignId, Status = CampaignLoot.CampaignLootStatus.Undistributed, ItemId = epic.Id, }; await _dbContext.AddAsync(loot); existingLootCount++; model.SuccessMessages.Add( string.Format( "Item with slug {0} has been added to the loot list.", slug )); } } else { model.WarningMessages.Add( string.Format( "Ignoring epic item with slug {0} since it's neither weapon nor armor.", slug )); } } } else { // This check is probably going to be very noisy since it will activate on items // that Linkify doesn't decorate, yet they still have Epic frames // model.WarningMessages.Add( // "Skipping epic item without URL. Perhaps, Linkify.user.js is not installed?" // ); } } } if (leaderboardLines != null) { foreach (var playerLine in leaderboardLines) { var cells = playerLine.Descendants("td").ToArray(); var player = _dbContext.Player.SingleOrDefault(p => p.Name == cells[2].InnerText); if (player != null) { var attendance = _dbContext.CampaignAttendance.SingleOrDefault(a => a.PlayerId == player.Id && a.CampaignId == campaignId); if (attendance == null) { attendance = new CampaignAttendance { CampaignId = campaignId, PlayerId = player.Id, }; await _dbContext.AddAsync(attendance); } } else { model.WarningMessages.Add( string.Format( "Player {0} does not seem to belong to the syndicate. Please ensure that members' list is up to date!", cells[2].InnerText )); } } } campaign.Status = Campaign.CampaignStatus.Completed; await _dbContext.SaveChangesAsync(); return(model); }