/// <summary> /// 根据ID得到一个帖子实体 /// </summary> /// <param name="id">帖子ID</param> /// <returns>帖子实体</returns> public static ForumPostEntity GetForumPost(Int32 id) { if (id <= 0) { throw new InvalidRequstException(RequestType.ForumPost); } ForumPostEntity entity = ForumPostCache.GetForumPostCache(id); if (entity == null) { entity = ForumPostRepository.Instance.GetEntity(id); ForumPostCache.SetForumPostCache(entity); } if (entity == null) { throw new NullResponseException(RequestType.ForumPost); } if (entity.IsHide && !AdminManager.HasPermission(PermissionType.ForumManage)) { throw new NoPermissionException("You have no privilege to view the post!"); } return(entity); }
public void IsQuoting_Is_False_When_Not_Quoting() { Assert.Inconclusive("This property is not being parsed."); ForumPostEntity post = ParseEntity(PostHtmlFromRegularUser); Assert.IsFalse(post.IsQuoting); }
public ActionResult Reply(String id, FormCollection form) { ContestEntity contest = ViewData["Contest"] as ContestEntity; ForumPostEntity post = ForumPostManager.GetForumPostByTopicID(id); ForumTopicEntity topic = ForumTopicManager.GetForumTopic(post.TopicID); if (topic.Type != ForumTopicType.Contest || topic.RelativeID != contest.ContestID) { return(RedirectToErrorMessagePage("This contest does not have this topic!")); } ForumPostEntity reply = new ForumPostEntity() { Title = form["title"], Content = form["content"] }; String userip = this.GetCurrentUserIP(); String link = Url.Action("Topic", "Forum", new { area = "Contest", cid = contest.ContestID, id = post.TopicID }); if (!ForumPostManager.InsertForumPost(reply, topic, post, userip, link)) { return(RedirectToErrorMessagePage("Failed to post your reply!")); } return(RedirectToAction("Topic", "Forum", new { area = "Contest", cid = contest.ContestID, id = post.TopicID })); }
/// <summary> /// 向缓存中写入指定帖子信息 /// </summary> /// <param name="Post">指定帖子信息</param> public static void SetForumPostCache(ForumPostEntity post) { if (post != null) { CacheManager.Set(GetForumPostCacheKey(post.PostID), post); } }
public ActionResult Reply(Int32 id, FormCollection form) { ForumPostEntity post = ForumPostManager.GetForumPost(id); ForumTopicEntity topic = ForumTopicManager.GetForumTopic(post.TopicID); if (topic.Type == ForumTopicType.Contest) { return(RedirectToErrorMessagePage("This topic is not in the main disscus board!")); } ForumPostEntity reply = new ForumPostEntity() { Title = form["title"], Content = form["content"] }; String userip = this.GetCurrentUserIP(); String link = Url.Action("Reply", "Forum", new { id = post.PostID }); if (!ForumPostManager.InsertForumPost(reply, topic, post, userip, link)) { return(RedirectToErrorMessagePage("Failed to post your reply!")); } return(RedirectToAction("Reply", "Forum", new { id = post.PostID })); }
/// <summary> /// 根据主题ID得到一个帖子实体 /// </summary> /// <param name="topicID">主题ID</param> /// <returns>帖子实体</returns> public static ForumPostEntity GetForumPostByTopicID(String topicID) { Int32 tid = 0; Int32.TryParse(topicID, out tid); if (tid <= 0) { throw new InvalidRequstException(RequestType.ForumTopic); } ForumPostEntity entity = ForumPostRepository.Instance.GetEntityByTopicID(tid); if (entity == null) { throw new NullResponseException(RequestType.ForumPost); } if (entity.IsHide && !AdminManager.HasPermission(PermissionType.ForumManage)) { throw new NoPermissionException("You have no privilege to view the post!"); } return(entity); }
public void PostLink_Is_Successfully_Parsed() { Assert.Inconclusive("This property is not being parsed."); ForumPostEntity post = ParseEntity(PostHtmlFromRegularUser); Assert.AreEqual("", post.PostLink); }
public void PostFormatted_Is_Successfully_Parsed() { ForumPostEntity post = ParseEntity(PostHtmlFromRegularUser); Assert.AreEqual( "<!-- BeginContentMarker --> <!-- google_ad_section_start --> The fact that this thread stands alone as a bulwark of non-terrible posting in the veritable wasteland that is new GBS is making me want to do this but I am super poor and super uncreative. I am debating what to do. <!-- google_ad_section_end --> <!-- EndContentMarker --> <p class=\"editedby\">", post.PostFormatted.Trim()); }
private static string ParsePosts(int startingCount, int endCount, List <ForumPostEntity> postEntities, bool isPrivateMessage) { int seenCount = 1; string threadHtml = string.Empty; for (int index = startingCount; index < endCount; index++) { ForumPostEntity post = postEntities[index]; if (seenCount > 2) { seenCount = 1; } string hasSeen = post.HasSeen ? string.Concat("seen", seenCount) : string.Concat("postCount", seenCount); seenCount++; string userAvatar = string.Empty; if (!string.IsNullOrEmpty(post.User.AvatarLink)) { userAvatar = string.Concat("<img data-user-id=\"", post.User.Id, "\" src=\"", post.User.AvatarLink, "\" alt=\"\" class=\"av\" border=\"0\">"); } string username = $"<p style=\"padding: 0;\" class=\"text article-title win-type-ellipsis\"><span class=\"{post.User.Roles}\">{post.User.Username}</span></p>"; string postData = $"<p class=\"text article-title win-type-caption-alt\"><span class=\"registered\">{post.PostDate}</span></p>"; string postBody = string.Format("<div id=\"{1}\" class=\"postbody\">{0}</div>", post.PostHtml, post.PostId); string userInfoClass = string.IsNullOrEmpty(post.User.AvatarLink) ? "" : "userinfo"; string userInfo = $"<div class=\"{userInfoClass}\">{username}{postData}</div>"; string postButtons = CreateButtons(post); string footer = string.Empty; if (!isPrivateMessage) { footer = $"<tr class=\"postbar\"><td class=\"postlinks\">{postButtons}</td></tr>"; } threadHtml += string.Format( "<div class={6} id={4}>" + "<div id={5}>" + "<div class=\"row clearfix\">" + "<div class=\"col-md-4\">" + "<div id=\"threadView\">" + "{0}{1}" + "</div>" + "</div>" + "<div style=\"padding: 15px;\" class=\"col-md-8\">" + "<div class=\"article-content\">" + "{2}" + "<footer>{3}</footer>" + "</div>" + "</div>" + "</div>" + "</div>" + "</div>", userAvatar, userInfo, postBody, footer, string.Concat("\"pti", index + 1, "\""), string.Concat("\"postId", post.PostId, "\""), string.Concat("\"", hasSeen, "\"")); } return(threadHtml); }
public async Task<ForumThreadEntity> GetThreadPosts(ForumThreadEntity forumThread) { try { string url = forumThread.Location; if (forumThread.CurrentPage > 0) { url = forumThread.Location + string.Format(Constants.PAGE_NUMBER, forumThread.CurrentPage); } else if (forumThread.HasBeenViewed) { url = forumThread.Location + Constants.GOTO_NEW_POST; } var forumThreadPosts = new ObservableCollection<ForumPostEntity>(); //TEMP CODE var threadManager = new ThreadManager(); var doc = await threadManager.GetThread(forumThread, url); HtmlNode threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); foreach ( HtmlNode postNode in threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post"))) { var post = new ForumPostEntity(); post.Parse(postNode); forumThreadPosts.Add(post); } threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("class", string.Empty).Contains("pages top")); if (threadNode != null) { threadNode = threadNode.Descendants("option") .FirstOrDefault(node => node.GetAttributeValue("selected", string.Empty).Contains("selected")); if (forumThread.CurrentPage <= 0) { forumThread.CurrentPage = GetPageNumber(threadNode); } } forumThread.ForumPosts = forumThreadPosts; return forumThread; } catch (Exception) { return null; } }
/// <summary> /// Populates the page with content passed during navigation. Any saved state is also /// provided when recreating a page from a prior session. /// </summary> /// <param name="sender"> /// The source of the event; typically <see cref="NavigationHelper" /> /// </param> /// <param name="e"> /// Event data that provides both the navigation parameter passed to /// <see cref="Frame.Navigate(Type, Object)" /> when this page was initially requested and /// a dictionary of state preserved by this page during an earlier /// session. The state will be null the first time a page is visited. /// </param> private void navigationHelper_LoadState(object sender, LoadStateEventArgs e) { _forumPost = e.NavigationParameter as ForumPostEntity; if (_forumPost != null) { ReplyText.Text = string.Format(Constants.QUOTE_EXP, _forumPost.User.Username, _forumPost.PostId, _forumPost.PostFormatted); } _forumThread = e.NavigationParameter as ForumThreadEntity; }
private static ForumPostEntity ParseEntity(string html) { var doc = new HtmlDocument(); doc.LoadHtml(html); var entity = new ForumPostEntity(); entity.Parse(doc.DocumentNode.Descendants("table").FirstOrDefault()); return(entity); }
public async Task <List <ForumPostEntity> > GetThreadPosts(ForumThreadEntity forumThread) { string url = forumThread.Location; if (forumThread.CurrentPage > 0) { url = forumThread.Location + string.Format(Constants.PAGE_NUMBER, forumThread.CurrentPage); } else if (forumThread.HasBeenViewed) { url = forumThread.Location + Constants.GOTO_NEW_POST; } var forumThreadPosts = new List <ForumPostEntity>(); //TEMP CODE var result = await _webManager.DownloadHtml(url); HtmlDocument doc = result.Document; string responseUri = result.AbsoluteUri; /* TODO: The following checks the thread URL for "pti" (which indicated which post to scroll to) * Having it in the post manager though, is wrong. This needs to be refactored and a better method of * getting this needs to be put in. */ string[] test = responseUri.Split('#'); if (test.Length > 1 && test[1].Contains("pti")) { forumThread.ScrollToPost = Int32.Parse(Regex.Match(responseUri.Split('#')[1], @"\d+").Value) - 1; } HtmlNode threadNode = doc.DocumentNode.Descendants("div").FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); foreach (HtmlNode postNode in threadNode.Descendants("table").Where(node => node.GetAttributeValue("class", string.Empty).Contains("post"))) { var post = new ForumPostEntity(); post.Parse(postNode); forumThreadPosts.Add(post); } threadNode = doc.DocumentNode.Descendants("div").FirstOrDefault(node => node.GetAttributeValue("class", string.Empty).Contains("pages top")); threadNode = threadNode.Descendants("option").FirstOrDefault(node => node.GetAttributeValue("selected", string.Empty).Contains("selected")); if (forumThread.CurrentPage <= 0) { forumThread.CurrentPage = GetPageNumber(threadNode); } HtmlNode pageNode = doc.DocumentNode.Descendants("select").FirstOrDefault(); forumThread.TotalPages = forumThread.CurrentPage <= 1 ? 1 : Convert.ToInt32(pageNode.Descendants("option").LastOrDefault().GetAttributeValue("value", string.Empty)); return(forumThreadPosts); }
public async Task <ForumThreadEntity> GetThreadPosts(ForumThreadEntity forumThread) { string url = forumThread.Location; if (forumThread.CurrentPage > 0) { url = forumThread.Location + string.Format(Constants.PAGE_NUMBER, forumThread.CurrentPage); } else if (forumThread.HasBeenViewed) { url = forumThread.Location + Constants.GOTO_NEW_POST; } var forumThreadPosts = new ObservableCollection <ForumPostEntity>(); //TEMP CODE var threadManager = new ThreadManager(); var doc = await threadManager.GetThread(forumThread, url); HtmlNode threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); foreach ( HtmlNode postNode in threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post"))) { var post = new ForumPostEntity(); post.Parse(postNode); forumThreadPosts.Add(post); } threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("class", string.Empty).Contains("pages top")); if (threadNode != null) { threadNode = threadNode.Descendants("option") .FirstOrDefault(node => node.GetAttributeValue("selected", string.Empty).Contains("selected")); if (forumThread.CurrentPage <= 0) { forumThread.CurrentPage = GetPageNumber(threadNode); } } forumThread.ForumPosts = forumThreadPosts; return(forumThread); }
private async Task FormatPmHtml(ForumPostEntity postEntity) { var list = new List<ForumPostEntity> {postEntity}; var thread = new ForumThreadEntity() { IsPrivateMessage = true }; #if WINDOWS_PHONE_APP thread.PlatformIdentifier = PlatformIdentifier.WindowsPhone; #else thread.PlatformIdentifier = PlatformIdentifier.Windows8; #endif Html = await HtmlFormater.FormatThreadHtml(thread, list); }
/// <summary> /// 讨论版主题页面 /// </summary> /// <param name="id">主题ID</param> /// <returns>操作后的结果</returns> public ActionResult Topic(Int32 id = -1) { ContestEntity contest = ViewData["Contest"] as ContestEntity; ForumPostEntity post = ForumPostManager.GetForumPostByTopicID(id.ToString()); ForumTopicEntity topic = ForumTopicManager.GetForumTopic(post.TopicID); if (topic.Type != ForumTopicType.Contest || topic.RelativeID != contest.ContestID) { return(RedirectToErrorMessagePage("This contest does not have this topic!")); } List <ForumPostEntity> list = ForumPostManager.GetForumPostList(topic, false); return(View(new Tuple <ForumTopicEntity, List <ForumPostEntity> >(topic, list))); }
private async Task FormatPmHtml(ForumPostEntity postEntity) { var list = new List <ForumPostEntity> { postEntity }; var thread = new ForumThreadEntity() { IsPrivateMessage = true }; #if WINDOWS_PHONE_APP thread.PlatformIdentifier = PlatformIdentifier.WindowsPhone; #else thread.PlatformIdentifier = PlatformIdentifier.Windows8; #endif Html = await HtmlFormater.FormatThreadHtml(thread, list); }
public void PostHtml_Is_Successfully_Parsed() { ForumPostEntity post = ParseEntity(PostHtmlFromRegularUser); string expected = @"<!DOCTYPE html><html><head><link rel=""stylesheet"" type=""text/css"" href=""ms-appx-web:///Assets/bbcode.css""><link rel=""stylesheet"" type=""text/css"" href=""ms-appx-web:///Assets/forums.css""><link rel=""stylesheet"" type=""text/css"" href=""ms-appx-web:///Assets/main.css""><link rel=""stylesheet"" type=""text/css"" href=""ms-appx-web:///Assets/ui-light.css""><meta name=""MSSmartTagsPreventParsing"" content=""TRUE""><meta http-equiv=""X-UA-Compatible"" content=""chrome=1""><script type=""text/javascript"" src=""ms-appx-web:///Assets/jquery.min.js""></script><link rel=""stylesheet"" type=""text/css"" href=""ms-appx-web:///Assets/jquery-ui.css""><script type=""text/javascript"" src=""ms-appx-web:///Assets/jquery-ui.min.js""></script><script type=""text/javascript"">disable_thread_coloring = true;</script><script type=""text/javascript"" src=""ms-appx-web:///Assets/forums.combined.js""></script><style type=""text/css""></style></head><body> <!-- BeginContentMarker --> <!-- google_ad_section_start --> The fact that this thread stands alone as a bulwark of non-terrible posting in the veritable wasteland that is new GBS is making me want to do this but I am super poor and super uncreative. I am debating what to do. <!-- google_ad_section_end --> <!-- EndContentMarker --> <p class=""editedby""> </body></html>" ; Assert.AreEqual(expected, post.PostHtml); }
/// <summary> /// 讨论版回复页面 /// </summary> /// <param name="id">帖子ID</param> /// <param name="tid">主题ID</param> /// <returns>操作后的结果</returns> public ActionResult Reply(Int32 id = -1, String tid = "") { ForumPostEntity post = (String.IsNullOrEmpty(tid) ? ForumPostManager.GetForumPost(id) : ForumPostManager.GetForumPostByTopicID(tid)); ForumTopicEntity topic = ForumTopicManager.GetForumTopic(post.TopicID); if (topic.Type == ForumTopicType.Contest) { return(RedirectToErrorMessagePage("This topic is not in the main disscus board!")); } post.RelativeType = (topic.Type == ForumTopicType.Problem ? topic.Type : ForumTopicType.Default); post.RelativeID = (topic.Type == ForumTopicType.Problem ? topic.RelativeID : -1); List <TreeNode <ForumPostEntity> > listTreeNode = ForumPostManager.GetPostTreeList(topic, post.PostID); ViewBag.IsLocked = topic.IsLocked; return(View(new Tuple <ForumPostEntity, List <TreeNode <ForumPostEntity> > >(post, listTreeNode))); }
private static string CreateButtons(ForumPostEntity post) { var clickHandler = string.Format("window.ForumCommand('quote', '{0}')", post.PostId); string quoteButton = HtmlButtonBuilder.CreateSubmitButton("Quote", clickHandler); clickHandler = string.Format("window.ForumCommand('edit', '{0}')", post.PostId); string editButton = HtmlButtonBuilder.CreateSubmitButton("Edit", clickHandler); clickHandler = string.Format("window.ForumCommand('markAsLastRead', '{0}')", post.PostIndex); string markAsLastReadButton = HtmlButtonBuilder.CreateSubmitButton("Last Read", clickHandler); return post.User.IsCurrentUserPost ? string.Concat("<ul class=\"profilelinks\">", quoteButton, markAsLastReadButton, editButton, "</ul>") : string.Concat("<ul class=\"profilelinks\">", quoteButton, markAsLastReadButton, "</ul>"); }
private static string CreateButtons(ForumPostEntity post) { var clickHandler = string.Format("window.ForumCommand('quote', '{0}')", post.PostId); string quoteButton = HtmlButtonBuilder.CreateSubmitButton("Quote", clickHandler); clickHandler = string.Format("window.ForumCommand('edit', '{0}')", post.PostId); string editButton = HtmlButtonBuilder.CreateSubmitButton("Edit", clickHandler); clickHandler = string.Format("window.ForumCommand('markAsLastRead', '{0}')", post.PostIndex); string markAsLastReadButton = HtmlButtonBuilder.CreateSubmitButton("Last Read", clickHandler); return(post.User.IsCurrentUserPost ? string.Concat("<ul class=\"profilelinks\">", quoteButton, markAsLastReadButton, editButton, "</ul>") : string.Concat("<ul class=\"profilelinks\">", quoteButton, markAsLastReadButton, "</ul>")); }
public async Task<string> GetPost(int postId) { try { string url = string.Format(Constants.SHOW_POST, postId); WebManager.Result result = await _webManager.GetData(url); HtmlDocument doc = result.Document; HtmlNode threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); HtmlNode postNode = threadNode.Descendants("table") .FirstOrDefault(node => node.GetAttributeValue("class", string.Empty).Contains("post")); var post = new ForumPostEntity(); post.Parse(postNode); return await HtmlFormater.FormatPostHtml(post); } catch (Exception) { return null; } }
public async Task <string> GetPrivateMessageHtml(string url) { string html = await PathIO.ReadTextAsync("ms-appx:///Assets/thread.html"); var doc2 = new HtmlDocument(); doc2.LoadHtml(html); HtmlNode bodyNode = doc2.DocumentNode.Descendants("body").FirstOrDefault(); HtmlDocument doc = (await _webManager.GetData(url)).Document; HtmlNode[] replyNodes = doc.DocumentNode.Descendants("div").Where(node => node.GetAttributeValue("id", "").Equals("thread")).ToArray(); HtmlNode threadNode = replyNodes.FirstOrDefault(node => node.GetAttributeValue("id", "").Equals("thread")); int threadId = ParseInt(threadNode.GetAttributeValue("class", string.Empty)); IEnumerable <HtmlNode> postNodes = threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post")); ObservableCollection <ForumPostEntity> postList = new ObservableCollection <ForumPostEntity>(); foreach ( HtmlNode postNode in postNodes) { var post = new ForumPostEntity(); post.Parse(postNode); postList.Add(post); } ForumThreadEntity threadEntity = new ForumThreadEntity() { ForumPosts = postList }; return(await HtmlFormater.FormatThreadHtml(threadEntity)); }
public async Task <string> GetPost(int postId) { try { string url = string.Format(Constants.SHOW_POST, postId); WebManager.Result result = await _webManager.GetData(url); HtmlDocument doc = result.Document; HtmlNode threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); HtmlNode postNode = threadNode.Descendants("table") .FirstOrDefault(node => node.GetAttributeValue("class", string.Empty).Contains("post")); var post = new ForumPostEntity(); post.Parse(postNode); return(await HtmlFormater.FormatPostHtml(post)); } catch (Exception) { return(null); } }
/// <summary> /// 增加一条数据 /// </summary> /// <param name="topic">主题实体</param> /// <param name="content">主题内容</param> /// <param name="ip">发布IP</param> /// <returns>操作影响的记录数</returns> public Int32 InsertEntity(ForumTopicEntity topic, String content, String ip) { return(this.UsingTransaction <Int32>((trans) => { Int32 result = this.Insert() .Set(USERNAME, topic.UserName) .Set(TITLE, topic.Title) .Set(TYPE, (Byte)topic.Type) .Set(RELATIVEID, topic.RelativeID) .Set(LASTDATE, topic.LastDate) .Result(trans); if (result <= 0) { trans.Rollback(); return 0; } ForumPostEntity post = new ForumPostEntity(); post.TopicID = this.Select().QueryIdentity().Result(trans); post.ParentPostID = 0; post.Deepth = ForumPostRepository.DEEPTH_MIN; post.UserName = topic.UserName; post.Title = topic.Title; post.Content = content; post.PostDate = topic.LastDate; post.PostIP = ip; result = ForumPostRepository.Instance.InternalGetInsertEntityCommand(post) .Result(trans);//提交主题帖内容 trans.Commit(); return result; })); }
public async Task<ForumReplyEntity> GetReplyCookies(ForumThreadEntity forumThread) { try { string url = string.Format(Constants.REPLY_BASE, forumThread.ThreadId); WebManager.Result result = await _webManager.GetData(url); HtmlDocument doc = result.Document; HtmlNode[] formNodes = doc.DocumentNode.Descendants("input").ToArray(); HtmlNode formKeyNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("formkey")); HtmlNode formCookieNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("form_cookie")); HtmlNode bookmarkNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("bookmark")); HtmlNode[] textAreaNodes = doc.DocumentNode.Descendants("textarea").ToArray(); HtmlNode textNode = textAreaNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("message")); HtmlNode threadIdNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("threadid")); var threadManager = new ThreadManager(); var forumThreadPosts = new ObservableCollection<ForumPostEntity>(); HtmlNode threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); foreach ( HtmlNode postNode in threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post"))) { var post = new ForumPostEntity(); post.Parse(postNode); forumThreadPosts.Add(post); } forumThread.ForumPosts = forumThreadPosts; string htmlThread = await HtmlFormater.FormatThreadHtml(forumThread); var forumReplyEntity = new ForumReplyEntity(); try { string formKey = formKeyNode.GetAttributeValue("value", ""); string formCookie = formCookieNode.GetAttributeValue("value", ""); string quote = WebUtility.HtmlDecode(textNode.InnerText); string threadId = threadIdNode.GetAttributeValue("value", ""); forumReplyEntity.MapThreadInformation(formKey, formCookie, quote, threadId); forumReplyEntity.PreviousPostsRaw = htmlThread; return forumReplyEntity; } catch (Exception) { throw new InvalidOperationException("Could not parse newReply form data."); } } catch (Exception) { return null; } }
public async Task<ForumReplyEntity> GetReplyCookiesForEdit(long postId) { try { string url = string.Format(Constants.EDIT_BASE, postId); WebManager.Result result = await _webManager.GetData(url); HtmlDocument doc = result.Document; HtmlNode[] formNodes = doc.DocumentNode.Descendants("input").ToArray(); HtmlNode bookmarkNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("bookmark")); HtmlNode[] textAreaNodes = doc.DocumentNode.Descendants("textarea").ToArray(); HtmlNode textNode = textAreaNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("message")); var threadManager = new ThreadManager(); //Get previous posts from quote page. string url2 = string.Format(Constants.QUOTE_BASE, postId); WebManager.Result result2 = await _webManager.GetData(url2); HtmlDocument doc2 = result2.Document; var forumThreadPosts = new ObservableCollection<ForumPostEntity>(); HtmlNode threadNode = doc2.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); foreach ( HtmlNode postNode in threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post"))) { var post = new ForumPostEntity(); post.Parse(postNode); forumThreadPosts.Add(post); } ForumThreadEntity threadEntity = new ForumThreadEntity() { ForumPosts = forumThreadPosts }; string htmlThread = await HtmlFormater.FormatThreadHtml(threadEntity); var forumReplyEntity = new ForumReplyEntity(); try { string quote = WebUtility.HtmlDecode(textNode.InnerText); forumReplyEntity.PreviousPostsRaw = htmlThread; string bookmark = bookmarkNode.OuterHtml.Contains("checked") ? "yes" : "no"; forumReplyEntity.MapEditPostInformation(quote, postId, bookmark); return forumReplyEntity; } catch (Exception) { throw new InvalidOperationException("Could not parse newReply form data."); } } catch (Exception) { return null; } }
/// <summary> /// 增加一条回帖 /// </summary> /// <param name="post">帖子实体</param> /// <param name="topic">主题实体</param> /// <param name="parentPost">回复的帖子实体</param> /// <param name="postip">发布者IP</param> /// <param name="link">当前页面地址</param> /// <returns>是否成功增加</returns> public static Boolean InsertForumPost(ForumPostEntity post, ForumTopicEntity topic, ForumPostEntity parentPost, String postip, String link) { if (!UserManager.IsUserLogined) { throw new UserUnLoginException(); } if (String.IsNullOrEmpty(post.Title)) { throw new InvalidInputException("Reply title can not be NULL!"); } if (post.Title.Length > ForumPostRepository.TITLE_MAXLEN) { throw new InvalidInputException("Reply title is too long!"); } if (!KeywordsFilterManager.IsForumPostContentLegal(post.Title)) { throw new InvalidInputException("Reply title can not contain illegal keywords!"); } if (String.IsNullOrEmpty(post.Content) || post.Content.Length < ForumPostRepository.POST_MINLEN) { throw new InvalidInputException("Reply content is too short!"); } if (post.Content.Length > ForumPostRepository.POST_MAXLEN) { throw new InvalidInputException("Reply content is too long!"); } if (!KeywordsFilterManager.IsForumPostContentLegal(post.Content)) { throw new InvalidInputException("Reply content can not contain illegal keywords!"); } if (parentPost.Deepth + 1 < ForumPostRepository.DEEPTH_MIN) { throw new InvalidInputException("Reply deepth is INVALID!"); } if (parentPost.Deepth + 1 > ForumPostRepository.DEEPTH_MAX) { throw new InvalidInputException("Reply deepth is too deep!"); } if (topic.IsLocked) { throw new NoPermissionException("You have no privilege to reply the post!"); } if (!UserSubmitStatus.CheckLastSubmitForumPostTime(UserManager.CurrentUserName)) { throw new InvalidInputException(String.Format("You can not submit post more than twice in {0} seconds!", ConfigurationManager.SubmitInterval.ToString())); } post.TopicID = parentPost.TopicID; post.Title = HtmlEncoder.HtmlEncode(post.Title); post.Content = HtmlEncoder.HtmlEncode(post.Content); post.UserName = UserManager.CurrentUserName; post.Deepth = parentPost.Deepth + 1; post.ParentPostID = parentPost.PostID; post.PostDate = DateTime.Now; post.PostIP = postip; Boolean success = ForumPostRepository.Instance.InsertEntity(post) > 0; if (success && !String.Equals(parentPost.UserName, post.UserName)) { if (ConfigurationManager.ReplyPostMailNotification) { try { UserMailEntity mail = new UserMailEntity(); String url = ConfigurationManager.DomainUrl + ((link[0] == '/') ? link.Substring(1) : link); mail.FromUserName = ConfigurationManager.SystemAccount; mail.ToUserName = parentPost.UserName; mail.Title = "Your post has new reply!"; mail.Content = String.Format("Your post \"{0}\" has new reply, <br/>", parentPost.Title) + String.Format("Please visit <a href=\"{0}\" target=\"_blank\">{0}</a>", url); UserMailManager.InternalSendUserMail(mail); } catch { } } } return(success); }
public async Task <ForumReplyEntity> GetReplyCookiesForEdit(long postId) { try { string url = string.Format(Constants.EDIT_BASE, postId); WebManager.Result result = await _webManager.GetData(url); HtmlDocument doc = result.Document; HtmlNode[] formNodes = doc.DocumentNode.Descendants("input").ToArray(); HtmlNode bookmarkNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("bookmark")); HtmlNode[] textAreaNodes = doc.DocumentNode.Descendants("textarea").ToArray(); HtmlNode textNode = textAreaNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("message")); var threadManager = new ThreadManager(); //Get previous posts from quote page. string url2 = string.Format(Constants.QUOTE_BASE, postId); WebManager.Result result2 = await _webManager.GetData(url2); HtmlDocument doc2 = result2.Document; var forumThreadPosts = new ObservableCollection <ForumPostEntity>(); HtmlNode threadNode = doc2.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); foreach ( HtmlNode postNode in threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post"))) { var post = new ForumPostEntity(); post.Parse(postNode); forumThreadPosts.Add(post); } ForumThreadEntity threadEntity = new ForumThreadEntity() { ForumPosts = forumThreadPosts }; string htmlThread = await HtmlFormater.FormatThreadHtml(threadEntity); var forumReplyEntity = new ForumReplyEntity(); try { string quote = WebUtility.HtmlDecode(textNode.InnerText); forumReplyEntity.PreviousPostsRaw = htmlThread; string bookmark = bookmarkNode.OuterHtml.Contains("checked") ? "yes" : "no"; forumReplyEntity.MapEditPostInformation(quote, postId, bookmark); return(forumReplyEntity); } catch (Exception) { throw new InvalidOperationException("Could not parse newReply form data."); } } catch (Exception) { return(null); } }
public async Task <ForumReplyEntity> GetReplyCookies(ForumThreadEntity forumThread) { try { string url = string.Format(Constants.REPLY_BASE, forumThread.ThreadId); WebManager.Result result = await _webManager.GetData(url); HtmlDocument doc = result.Document; HtmlNode[] formNodes = doc.DocumentNode.Descendants("input").ToArray(); HtmlNode formKeyNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("formkey")); HtmlNode formCookieNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("form_cookie")); HtmlNode bookmarkNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("bookmark")); HtmlNode[] textAreaNodes = doc.DocumentNode.Descendants("textarea").ToArray(); HtmlNode textNode = textAreaNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("message")); HtmlNode threadIdNode = formNodes.FirstOrDefault(node => node.GetAttributeValue("name", "").Equals("threadid")); var threadManager = new ThreadManager(); var forumThreadPosts = new ObservableCollection <ForumPostEntity>(); HtmlNode threadNode = doc.DocumentNode.Descendants("div") .FirstOrDefault(node => node.GetAttributeValue("id", string.Empty).Contains("thread")); foreach ( HtmlNode postNode in threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post"))) { var post = new ForumPostEntity(); post.Parse(postNode); forumThreadPosts.Add(post); } forumThread.ForumPosts = forumThreadPosts; string htmlThread = await HtmlFormater.FormatThreadHtml(forumThread); var forumReplyEntity = new ForumReplyEntity(); try { string formKey = formKeyNode.GetAttributeValue("value", ""); string formCookie = formCookieNode.GetAttributeValue("value", ""); string quote = WebUtility.HtmlDecode(textNode.InnerText); string threadId = threadIdNode.GetAttributeValue("value", ""); forumReplyEntity.MapThreadInformation(formKey, formCookie, quote, threadId); forumReplyEntity.PreviousPostsRaw = htmlThread; return(forumReplyEntity); } catch (Exception) { throw new InvalidOperationException("Could not parse newReply form data."); } } catch (Exception) { return(null); } }
public static async Task <string> FormatThreadHtml(ForumThreadEntity forumThreadEntity) { ObservableCollection <ForumPostEntity> postEntities = forumThreadEntity.ForumPosts; string html = await PathIO.ReadTextAsync("ms-appx:///Assets/thread.html"); var doc2 = new HtmlDocument(); doc2.LoadHtml(html); HtmlNode head = doc2.DocumentNode.Descendants("head").FirstOrDefault(); switch (forumThreadEntity.PlatformIdentifier) { case PlatformIdentifier.WindowsPhone: head.InnerHtml += "<link href=\"ms-appx-web:///Assets/WindowsPhone-Default.css\" type=\"text/css\" media=\"all\" rel=\"stylesheet\">"; break; } switch (forumThreadEntity.ForumId) { case 219: head.InnerHtml += "<link href=\"ms-appx-web:///Assets/219.css\" type=\"text/css\" media=\"all\" rel=\"stylesheet\">"; break; case 26: break; } HtmlNode bodyNode = doc2.DocumentNode.Descendants("body").FirstOrDefault(); string threadHtml = string.Empty; int seenCount = 1; if (postEntities == null) { return(WebUtility.HtmlDecode(WebUtility.HtmlDecode(doc2.DocumentNode.OuterHtml))); } for (int index = 0; index < postEntities.Count; index++) { ForumPostEntity post = postEntities[index]; if (seenCount > 2) { seenCount = 1; } string hasSeen = post.HasSeen ? string.Concat("seen", seenCount) : string.Concat("postCount", seenCount); seenCount++; string userAvatar = string.Empty; if (!string.IsNullOrEmpty(post.User.AvatarLink)) { userAvatar = string.Concat("<img src=\"", post.User.AvatarLink, "\" alt=\"\" class=\"av\" border=\"0\">"); } string username = string.Format( "<h2 class=\"text article-title win-type-ellipsis\"><span class=\"author\">{0}</span><h2>", post.User.Username); string postData = string.Format( "<h4 class=\"text article-title win-type-ellipsis\"><span class=\"registered\">{0}</span><h4>", post.PostDate); string postBody = string.Format("<div class=\"postbody\">{0}</div>", post.PostHtml); string userInfo = string.Format("<div class=\"userinfo\">{0}{1}</div>", username, postData); string postButtons = CreateButtons(post); string footer = string.Format("<tr class=\"postbar\"><td class=\"postlinks\">{0}</td></tr>", postButtons); threadHtml += string.Format( "<div class={6} id={4}><div id={5}><div id=\"threadView\"><header>{0}{1}</header><article><div class=\"article-content\">{2}</div></article><footer>{3}</footer></div></div></div>", userAvatar, userInfo, postBody, footer, string.Concat("\"pti", index + 1, "\""), string.Concat("\"postId", post.PostId, "\""), string.Concat("\"", hasSeen, "\"")); } bodyNode.InnerHtml = threadHtml; return(doc2.DocumentNode.OuterHtml); }
public static async Task <string> FormatPostHtml(ForumPostEntity forumPostEntity) { return(string.Format("<div class=\"postbody\">{0}</div>", forumPostEntity.PostHtml)); }
public void PostId_Is_Successfully_Parsed() { ForumPostEntity post = ParseEntity(PostHtmlFromRegularUser); Assert.AreEqual(421467978, post.PostId); }
public static async Task<string> FormatPostHtml(ForumPostEntity forumPostEntity) { return string.Format("<div class=\"postbody\">{0}</div>", forumPostEntity.PostHtml); }
public DispatchForumPostCommand(ForumPostEntity forumPostEntity) { _forumPostEntity = forumPostEntity; }
public void PostDate_Is_Successfully_Parsed() { ForumPostEntity post = ParseEntity(PostHtmlFromRegularUser); Assert.AreEqual("Nov 6, 2013 05:15", post.PostDate); }
public async Task<string> GetPrivateMessageHtml(string url) { string html = await PathIO.ReadTextAsync("ms-appx:///Assets/thread.html"); var doc2 = new HtmlDocument(); doc2.LoadHtml(html); HtmlNode bodyNode = doc2.DocumentNode.Descendants("body").FirstOrDefault(); HtmlDocument doc = (await _webManager.GetData(url)).Document; HtmlNode[] replyNodes = doc.DocumentNode.Descendants("div").Where(node => node.GetAttributeValue("id", "").Equals("thread")).ToArray(); HtmlNode threadNode = replyNodes.FirstOrDefault(node => node.GetAttributeValue("id", "").Equals("thread")); int threadId = ParseInt(threadNode.GetAttributeValue("class", string.Empty)); IEnumerable<HtmlNode> postNodes = threadNode.Descendants("table") .Where(node => node.GetAttributeValue("class", string.Empty).Contains("post")); ObservableCollection<ForumPostEntity> postList = new ObservableCollection<ForumPostEntity>(); foreach ( HtmlNode postNode in postNodes) { var post = new ForumPostEntity(); post.Parse(postNode); postList.Add(post); } ForumThreadEntity threadEntity = new ForumThreadEntity() { ForumPosts = postList }; return await HtmlFormater.FormatThreadHtml(threadEntity); }
public void Poster_Is_Successful_Parsed() { ForumPostEntity post = ParseEntity(PostHtmlFromRegularUser); Assert.IsNotNull(post.User); }