public SAThreadPage(SAThread data, int page, int userID = 0) : this() { this.ThreadID = data.ID; this.ThreadTitle = data.ThreadTitle; this.Thread = data; this.UserID = userID; if (page != 0) { this.PageNumber = page; this.Url = String.Format("http://forums.somethingawful.com/showthread.php?threadid={0}&userid={1}&perpage=40&pagenumber={2}", this.ThreadID, userID, page); } else if (userID == 0) { this.PageNumber = 0; this.Url = String.Format("http://forums.somethingawful.com/showthread.php?threadid={0}&goto=newpost", m_id); } else { this.PageNumber = 0; this.Url = String.Format("http://forums.somethingawful.com/showthread.php?threadid={0}&userid={1}", m_id, userID); } }
public static ICancellable BuildAsync(Action<Awful.Core.Models.ActionResult, SAThreadPage> result, SAThread thread, bool refresh = false, int pageNumber = 0, int userID = 0) { BackgroundWorker worker = new BackgroundWorker(); Factory.AddDoWorkEvent(worker, thread, refresh, pageNumber, userID); Factory.AddRunWorkCompletedEvent(worker, result); CancellableTask task = new CancellableTask(worker); worker.RunWorkerAsync(); return task; }
public static SAThreadPage Build(SAThread thread, bool refresh = false, int pageNumber = 0, int userID = 0) { SAThreadPage page = null; // check database for page first (if not refreshing). if (userID == 0 && refresh == false) { page = Factory.LoadFromDatabase(thread, pageNumber); } if (page == null) { page = Factory.LoadFromWeb(thread, pageNumber, userID); } return page; }
private void ParseRating(SAThread thread, HtmlNode node) { var ratingNode = node.Descendants("img") .Where(imgNode => { string src = imgNode.GetAttributeValue("src", ""); return src.Contains("rate"); }) .FirstOrDefault(); if (ratingNode == null) thread.Rating = 0; else { string src = ratingNode.GetAttributeValue("src", ""); var tokens = src.Split('/'); var ratingToken = tokens[tokens.Length - 1]; switch (ratingToken) { case Globals.Constants.THREAD_RATING_5: thread.Rating = 5; break; case Globals.Constants.THREAD_RATING_4: thread.Rating = 4; break; case Globals.Constants.THREAD_RATING_3: thread.Rating = 3; break; case Globals.Constants.THREAD_RATING_2: thread.Rating = 2; break; case Globals.Constants.THREAD_RATING_1: thread.Rating = 1; break; } } }
public static SAThread Build(HtmlNode node, int forumID) { Awful.Core.Event.Logger.AddEntry("SAThread - Node Html Print:"); Awful.Core.Event.Logger.AddEntry("SAThread ------------------"); Awful.Core.Event.Logger.AddEntry(node.OuterHtml); Awful.Core.Event.Logger.AddEntry("SAThread ------------------"); SAThread result = null; int id = Factory.GetThreadID(node); result = new SAThread(); result.ID = id; result.ForumID = forumID; Factory.ParseThreadSeen(result, node); Factory.ParseThreadTitleAndUrl(result, node); Factory.ParseThreadAuthor(result, node); Factory.ParseReplies(result, node); Factory.ParseRating(result, node); Factory.ParseSticky(result, node); result.LastUpdated = DateTime.Now; return result; }
public ThreadData GenerateThreadData(object parameter) { SAThread thread = null; switch (parameter.ToString()) { case USE_URL: thread = CreateThreadDataFromUrl(Url); break; case USE_THREAD_ID: try { int threadID = int.Parse(this.ThreadID.ToString()); thread = new SAThread(null) { ID = threadID }; } catch (Exception) { } break; case USE_URL_OR_THREADID: int id = -1; if (int.TryParse(ThreadID.ToString(), out id)) { thread = new SAThread(null) { ID = id }; } else { thread = CreateThreadDataFromUrl(this.Url); } break; } if (thread == null && parameter.ToString().Equals(USE_URL)) { MessageBox.Show(string.Format("Could not parse the target '{0}'.", Url), ":(", MessageBoxButton.OK); } return thread; }
private SAThread CreateThreadDataFromUrl(string url) { SAThread thread = null; try { // parse the url KollaSoft.UrlParser parser = new KollaSoft.UrlParser(url); // check to see if url contains the something awful forums base if (!parser.Base.Contains("forums.somethingawful.com/showthread.php")) throw new Exception(); thread = new SAThread(null); thread.ThreadURL = url; // pull thread id value: if not present throw exception (can't navigate to an id-less thread!) if (parser.Query.ContainsKey("threadid")) { int threadID = int.Parse(parser.Query["threadid"]); thread.ID = threadID; } else throw new Exception(); // check to see if there is a page number there, if not then load first page thread.LastViewedPageIndex = parser.Query.ContainsKey("pagenumber") ? Int32.Parse(parser.Query["pagenumber"]) : 1; // check to see if a postID is specified string postID = parser.Hash; if (!string.IsNullOrEmpty(postID) && postID.Contains("post")) { // remove 'post' from hash (i.e. 'post30340507' -> '33040507' postID = postID.Replace("post", ""); // parse into integer thread.LastViewedPostID = int.Parse(postID); } } catch (Exception) { thread = null; } return thread; }
private string FormatNewPostCount(SAThread thread) { int value = thread.NewPostCount; if (value == Int32.MaxValue) { thread.ShowPostCount = true; return "no"; } if (value == -1) { thread.ShowPostCount = false; return String.Empty; } thread.ShowPostCount = true; return value.ToString(); }
private SAThreadPage LoadFromWeb(SAThread thread, int pageNumber, int userID) { SAThreadPage page = null; /// Only do work on nonnegative page numbers. I think I should throw an exception here, to be honest... if (pageNumber >= 0) { page = new SAThreadPage(thread, pageNumber, userID); HtmlDocument doc = this.LoadHtmlFromWeb(page); if (doc != null) { Awful.Core.Models.ActionResult result = this.ProcessData(page, doc); if (result == Awful.Core.Models.ActionResult.Failure) return null; } } if (page.PageNumber > 0 && userID == 0) { ThreadCache.AddPageToCache(page); } return page; }
private void ParseThreadCount(SAThread thread, HtmlNode node) { // locate the thread count var threadCountNode = node.Descendants("a") .Where(value => value.GetAttributeValue("class", "").Equals("count")) .FirstOrDefault(); // if we found the new post count, get and set the value if (threadCountNode != null) { #region if we found the thread count... int count = -1; if (Int32.TryParse(threadCountNode.InnerText.Sanitize(), out count)) { thread.NewPostCount = count; thread.ShowPostCount = true; Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - Thread has new unread posts: {0}", count)); } else { // no new posts, set to maximum int value for low score sorting thread.NewPostCount = Int32.MaxValue; thread.ShowPostCount = true; Awful.Core.Event.Logger.AddEntry("SAThread - Thread has no new posts."); } if (count > 0) { int readPostCount = thread.Replies - count; int postsPerPage = Globals.Constants.POSTS_PER_THREAD_PAGE; int readPage = (readPostCount / postsPerPage) + (readPostCount % postsPerPage > 0 ? 1 : 0); Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - posts read: {0}, last page: {1}", readPostCount, thread.MaxPages)); } #endregion } else { Awful.Core.Event.Logger.AddEntry("SAThread - Couldn't find the threadCountNode. no new posts."); thread.NewPostCount = Int32.MaxValue; } }
private void ParseThreadAuthor(SAThread thread, HtmlNode node) { var threadAuthorParentNode = node.Descendants("td") .Where(value => value.GetAttributeValue("class", "").Equals("author")) .FirstOrDefault(); thread.AuthorName = threadAuthorParentNode.FirstChild.InnerText; Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - Author Name: {0}", thread.AuthorName)); }
private void ParseSticky(SAThread thread, HtmlNode node) { var stickyNode = node.Descendants("td").Where(aNode => aNode.GetAttributeValue("class", "") .Contains("sticky")).FirstOrDefault(); thread.IsSticky = stickyNode != null; }
private void ParseReplies(SAThread thread, HtmlNode node) { var threadRepliesNode = node.Descendants("td") .Where(value => value.GetAttributeValue("class", "").Equals("replies")) .FirstOrDefault(); try { string repliesValue = threadRepliesNode.InnerText.Sanitize(); int replies = 0; if (Int32.TryParse(repliesValue, out replies)) { thread.Replies = replies; Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - # of replies: {0}", replies)); } int postsPerPage = Globals.Constants.POSTS_PER_THREAD_PAGE; thread.MaxPages = (replies / postsPerPage) + (replies % postsPerPage > 0 ? 1 : 0); Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - Max Pages: {0}", thread.MaxPages)); } catch (Exception ex) { Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - Exception thrown while parsing replies: {0}", ex.Message)); } }
private SAThreadPage LoadFromDatabase(SAThread thread, int pageNumber) { SAThreadPage page = null; /// only do work if the pageNumber is nonzero and positive. Should probably throw an exception here... if (pageNumber >= 1) { page = ThreadCache.GetPageFromCache(thread, pageNumber); } return page; }
private void ParseThreadSeen(SAThread thread, HtmlNode node) { // if the node is null, then we haven't seen this thread, otherwise it's been visited var threadSeenNode = node.DescendantsAndSelf() .Where(value => value.GetAttributeValue("class", "").Contains("thread seen")) .FirstOrDefault(); bool seen = threadSeenNode == null ? false : true; thread.ThreadSeen = seen; // if thread is new, all posts are new, so don't show post count if (!thread.ThreadSeen) { thread.NewPostCount = -1; thread.ShowPostCount = false; Awful.Core.Event.Logger.AddEntry("SAThread - This thread is brand new! Hide the post count."); } // else parse thread count else { this.ParseThreadCount(thread, node); } }
public SAThreadPage() { this._Thread = null; }
private void ParseThreadTitleAndUrl(SAThread thread, HtmlNode node) { var threadTitleNode = node.Descendants("a") .Where(value => value.GetAttributeValue("class", "").Equals("thread_title")) .FirstOrDefault(); var title = threadTitleNode.InnerText.Sanitize(); thread.ThreadTitle = HttpUtility.HtmlDecode(title); thread.ThreadTitle = ContentFilter.Censor(thread.ThreadTitle); Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - Thread Title: {0}", thread.ThreadTitle)); thread.ThreadURL = Globals.Constants.SA_BASE + "/" + threadTitleNode.GetAttributeValue("href", ""); Awful.Core.Event.Logger.AddEntry(string.Format("SAThread - Thread Url: '{0}'", thread.ThreadURL)); }
public SAThreadPage(SAThread data) : this(data, 0) { }
private void AddDoWorkEvent(BackgroundWorker worker, SAThread thread, bool refresh, int pageNumber, int userID) { DoWorkEventHandler doWork = null; doWork = (doWorkObj, doWorkArgs) => { BackgroundWorker bgWorker = doWorkObj as BackgroundWorker; bgWorker.DoWork -= new DoWorkEventHandler(doWork); SAThreadPage page = null; bool finished = false; ThreadPool.QueueUserWorkItem(state => { page = Build(thread, refresh, pageNumber, userID); finished = true; }, null); while (!finished && !doWorkArgs.Cancel) { if (bgWorker.CancellationPending) { doWorkArgs.Cancel = true; } } doWorkArgs.Result = page; }; worker.DoWork += new DoWorkEventHandler(doWork); }