public static void NotifyMessageRemoved(ForumMessageEntry forumMessage) { if (CachedMessagesDictionary.ContainsKey(forumMessage.TopicId)) { foreach (var page in CachedMessagesDictionary[forumMessage.TopicId]) { var index = page.Value.Messages.FindIndex(entry => entry.Id == forumMessage.Id); if (index != -1) { page.Value.Messages.RemoveAt(index); break; } } } }
public ForumTopicMessageEntryViewModel(ForumMessageEntry data) { Data = data; _isStarred = ResourceLocator.HandyDataStorage.IsMessageStarred(data.Id, data.Poster.MalUser); }
/// <summary> /// Returns tons of data about topic. /// </summary> /// <param name="topicId">Self explanatory</param> /// <param name="page">Page starting from 1</param> /// <param name="lastpage">Override page to last page?</param> /// <param name="messageId"></param> /// <param name="force">Forces cache ignore</param> /// <returns></returns> public static async Task<ForumTopicData> GetTopicData(string topicId,int page,bool lastpage = false,long? messageId = null,bool force = false) { if(!force && !lastpage && messageId == null && topicId != null && CachedMessagesDictionary.ContainsKey(topicId)) if (CachedMessagesDictionary[topicId].ContainsKey(page)) return CachedMessagesDictionary[topicId][page]; try { var client = await ResourceLocator.MalHttpContextProvider.GetHttpContextAsync(); var response = await client.GetAsync( lastpage ? $"/forum/?topicid={topicId}&goto=lastpost" : messageId != null ? $"/forum/message/{messageId}?goto=topic" : $"/forum/?topicid={topicId}&show={(page - 1) * 50}"); if ((lastpage || messageId != null) && response.StatusCode == HttpStatusCode.RedirectMethod) { response = await client.GetAsync(response.Headers.Location); } var doc = new HtmlDocument(); doc.Load(await response.Content.ReadAsStreamAsync()); var foundMembers = new Dictionary<string,MalForumUser>(); var output = new ForumTopicData {Id = topicId}; if (messageId != null && messageId != -1) output.TargetMessageId = messageId.ToString(); try { var pager = doc.FirstOfDescendantsWithClass("div", "fl-r pb4"); var lastLinkNode = pager.Descendants("a").LastOrDefault(node => node.InnerText.Contains("Last")); if (lastLinkNode != null) { output.AllPages = (int.Parse(lastLinkNode .Attributes["href"] .Value.Split('=').Last()) / 50) + 1; } else { var nodes = pager.ChildNodes.Where(node => !string.IsNullOrWhiteSpace(node.InnerText) && node.InnerText != "»"); output.AllPages = int.Parse(nodes.Last().InnerText.Replace("[","").Replace("]","").Trim()); } } catch (Exception) { output.AllPages = 1; } if(!lastpage) try { var pageNodes = doc.FirstOfDescendantsWithClass("div", "fl-r pb4").ChildNodes.Where(node => node.Name != "a"); output.CurrentPage = int.Parse( pageNodes.First(node => Regex.IsMatch(node.InnerText.Trim(), @"\[.*\]")) .InnerText.Replace("[", "").Replace("]", "").Trim()); } catch (Exception e) { output.CurrentPage = output.AllPages; } else { output.CurrentPage = output.AllPages; } output.Title = WebUtility.HtmlDecode(doc.FirstOrDefaultOfDescendantsWithClass("h1", "forum_locheader")?.InnerText.Trim()); if (output.Title == null) { output.Title = WebUtility.HtmlDecode(doc.FirstOrDefaultOfDescendantsWithClass("h1", "forum_locheader icon-forum-locked")?.InnerText.Trim()); if (output.Title != null) { output.IsLocked = true; } } foreach (var bradcrumb in doc.FirstOfDescendantsWithClass("div", "breadcrumb").ChildNodes.Where(node => node.Name == "div")) { output.Breadcrumbs.Add(new ForumBreadcrumb { Name = WebUtility.HtmlDecode(bradcrumb.InnerText.Trim()), Link = bradcrumb.Descendants("a").First().Attributes["href"].Value }); } if (topicId == null) //in case of redirection { var uri = response.RequestMessage.RequestUri.AbsoluteUri; output.TargetMessageId = uri.Split('#').Last().Replace("msg", ""); var pos = uri.IndexOf('&'); if (pos != -1) { uri = uri.Substring(0, pos); topicId = uri.Split('=').Last(); } output.Id = topicId; } foreach (var row in doc.WhereOfDescendantsWithClass("div", "forum_border_around")) { var current = new ForumMessageEntry {TopicId = topicId}; current.Id = row.Attributes["id"].Value.Replace("forumMsg", ""); var divs = row.ChildNodes.Where(node => node.Name == "div").ToList(); var headerDivs = divs[0].Descendants("div").ToList(); current.CreateDate = WebUtility.HtmlDecode(headerDivs[2].InnerText.Trim()); current.MessageNumber = WebUtility.HtmlDecode(headerDivs[1].InnerText.Trim()); var tds = row.Descendants("tr").First().ChildNodes.Where(node => node.Name == "td").ToList(); var posterName = WebUtility.HtmlDecode(tds[0].Descendants("strong").First().InnerText.Trim()); if (foundMembers.ContainsKey(posterName)) { current.Poster = foundMembers[posterName]; } else { var poster = new MalForumUser(); poster.MalUser.Name = posterName; poster.Title = WebUtility.HtmlDecode(tds[0].FirstOrDefaultOfDescendantsWithClass("div", "custom-forum-title")?.InnerText.Trim()); poster.MalUser.ImgUrl = tds[0].Descendants("img") .FirstOrDefault( node => node.Attributes.Contains("src") && node.Attributes["src"].Value.Contains("useravatars"))?.Attributes["src"].Value; if (tds[0].ChildNodes[1].ChildNodes.Count == 10) { poster.Status = tds[0].ChildNodes[1].ChildNodes[5].InnerText.Trim(); poster.Joined = tds[0].ChildNodes[1].ChildNodes[7].InnerText.Trim(); poster.Posts = tds[0].ChildNodes[1].ChildNodes[9].InnerText.Trim(); } else if (tds[0].ChildNodes[1].ChildNodes.Count == 11) { poster.Status = tds[0].ChildNodes[1].ChildNodes[6].InnerText.Trim(); poster.Joined = tds[0].ChildNodes[1].ChildNodes[8].InnerText.Trim(); poster.Posts = tds[0].ChildNodes[1].ChildNodes[10].InnerText.Trim(); } else { poster.Status = tds[0].ChildNodes[1].ChildNodes[2].InnerText.Trim(); poster.Joined = tds[0].ChildNodes[1].ChildNodes[4].InnerText.Trim(); poster.Posts = tds[0].ChildNodes[1].ChildNodes[6].InnerText.Trim(); } try { poster.SignatureHtml = tds[1].FirstOfDescendantsWithClass("div", "sig").OuterHtml; } catch (Exception) { //no signature } foundMembers.Add(posterName,poster); current.Poster = poster; } current.EditDate = WebUtility.HtmlDecode(tds[1].Descendants("em").FirstOrDefault()?.InnerText.Trim()); current.HtmlContent = tds[1].Descendants("div") .First( node => node.Attributes.Contains("id") && node.Attributes["id"].Value == $"message{current.Id}") .OuterHtml; var actions = row.FirstOfDescendantsWithClass("div", "postActions"); current.CanEdit = actions.ChildNodes[0].ChildNodes.Any(node => node.InnerText?.Contains("Edit") ?? false); current.CanDelete = actions.ChildNodes[0].ChildNodes.Any(node => node.InnerText?.Contains("Delete") ?? false); output.Messages.Add(current); } if (!CachedMessagesDictionary.ContainsKey(topicId)) CachedMessagesDictionary.Add(topicId, new Dictionary<int, ForumTopicData> { {output.CurrentPage, output} }); else { if (CachedMessagesDictionary[topicId].ContainsKey(output.CurrentPage)) CachedMessagesDictionary[topicId][output.CurrentPage] = output; else CachedMessagesDictionary[topicId].Add(output.CurrentPage, output); } return output; } catch (Exception) { return new ForumTopicData(); } }