/// <summary> /// Get post associated with post number. /// </summary> /// <returns><see cref="ChanPost">ChanPost</see> detailing the post</returns> /// /// <exception cref="ArgumentNullException">Thrown if board is null.</exception> /// <exception cref="ArgumentException">Thrown if board is empty or whitespace.</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown if postNo <= 0.</exception> /// /// <param name="board">Board where post is located.</param> /// <param name="postNo">Post number.</param> public static ChanPost GetPost(string board, int postNo) { board.ThrowIfNullOrWhiteSpace("board"); if (postNo < 1) { throw new ArgumentOutOfRangeException("post", "Cannot be 0 or negative."); } var jsonReq = string.Format("http://archive.moe/_/api/chan/post/?board={0}&num={1}", board, postNo); var json = WebString.Download(jsonReq); if (!json.Success) { return(new ChanPost(json)); } dynamic postJson = JsonConvert.DeserializeObject(json.Document); int threadNo = postJson.thread_num; string subject = postJson.title; string comment = postJson.comment_sanitized; return(new ChanPost(json.Location, board, ChanTools.GetBoardName(board), threadNo, postNo, subject, comment)); }
/// <summary> /// Get post associated with post number. /// </summary> /// <returns><see cref="ChanPost">ChanPost</see> detailing the post.</returns> /// /// <exception cref="ArgumentNullException">Thrown if board is null.</exception> /// <exception cref="ArgumentException">Thrown if board is empty or whitespace.</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown if threadNo and/or postNo <= 0.</exception> /// /// <param name="board">Board where thread/post is located.</param> /// <param name="threadNo">Thread number.</param> /// <param name="postNo">Post number.</param> public static ChanPost GetPost(string board, int threadNo, int postNo) { board.ThrowIfNullOrWhiteSpace("board"); if (threadNo < 1) { throw new ArgumentOutOfRangeException("thread", "Cannot be 0 or negative."); } else if (postNo < 1) { throw new ArgumentOutOfRangeException("post", "Cannot be 0 or negative."); } var jsonReq = string.Format("http://a.4cdn.org/{0}/res/{1}.json", board, threadNo); var json = WebString.Download(jsonReq); if (!json.Success) { return(new ChanPost(json)); } dynamic threadJson = JsonConvert.DeserializeObject(json.Document); string subject = null; string comment = null; // Simple linear search, seems fast enough for the 100s of posts it needs to look through. foreach (var post in threadJson.posts) { if (post.no == postNo) { subject = post.sub; if (!string.IsNullOrEmpty(subject)) { subject = HttpUtility.HtmlDecode(subject); } comment = post.com; if (!string.IsNullOrEmpty(comment)) { comment = Fix4chanPost(comment); } break; } } return(new ChanPost(json.Location, board, ChanTools.GetBoardName(board), threadNo, postNo, subject, comment)); }
/// <summary> /// Extract board, thread number and optional post number from URL. /// </summary> /// <returns>Tuple containing: board, thread number and post number (last is optional). /// If unable to extract the default return will be (string.Empty, -1, -1).</returns> /// /// <exception cref="ArgumentNullException">Thrown if url is null.</exception> /// <exception cref="ArgumentException">Thrown if url is empty or whitespace.</exception> /// /// <param name="url">URL pointing to a thread and/or post.</param> public static Tuple <string, int, int> Extract(string url) { url.ThrowIfNullOrWhiteSpace("url"); return(ChanTools.Extract(chanUrlRegexp, url)); }