示例#1
0
 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);
 }
示例#3
0
        /// <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 != "&raquo;");
                        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();
            }


        }