public async Task <bool> DeleteArticle(ArticleInfo article) { var queryData = new Dictionary <string, string>(); queryData.Add("bo_table", article.Table); queryData.Add("wr_id", article.ID.ToString()); string response = await Broker.FetchPage("http://www.clien.net/cs2/bbs/delete.php", queryData, HttpBroker.Method.Get); // 글에서 테이블 주소를 발견하면 성공 if (response.IndexOf("bo_table=" + article.Table) >= 0) { return(true); } else { return(false); } }
public async Task <List <CommentInfo> > GetMyCommentsInArticle(ArticleInfo article, int comment_page = 1) { var comments = new List <CommentInfo>(); var queryData = new Dictionary <string, string>(); queryData.Add("bo_table", article.Table); queryData.Add("wr_id", article.ID.ToString()); queryData.Add("comment_page", comment_page.ToString()); string content = await Broker.FetchPage("http://www.clien.net/cs2/bbs/board.php", queryData); var html = new HtmlDocument(); html.LoadHtml(content); var document = html.DocumentNode; // 모든 글 선택 foreach (var node in document.QuerySelectorAll("img[alt='수정']")) { // javascript:comment_box('23997945', 'cu');" string modifyScript = node.ParentNode.Attributes["href"].Value; int queryIndex = modifyScript.IndexOf("'"); // ? 문자열 시작부터 "');" 전까지 substring string commentId = modifyScript.Substring(queryIndex + 1, modifyScript.Length - 10 - queryIndex); comments.Add(new CommentInfo() { ArticleID = article.ID, Table = article.Table, CommentID = long.Parse(commentId) }); } return(comments); }
public async Task <bool> UpdateArticle(ArticleInfo article, string subject, string content) { // 첨부파일, 카테고리가 있는지 부터 체크 var queryData = new Dictionary <string, string>(); queryData.Add("w", "u"); queryData.Add("bo_table", article.Table); queryData.Add("wr_id", article.ID.ToString()); string response = await Broker.FetchPage("http://www.clien.net/cs2/bbs/write.php", queryData, HttpBroker.Method.Get); var html = new HtmlDocument(); html.LoadHtml(response); var document = html.DocumentNode; // 카테고리가 있는경우 마지막 카테고리로 선택한다. foreach (var node in document.QuerySelectorAll("select[name='ca_name'] option:last-child")) { queryData.Add("ca_name", node.Attributes["value"].Value); } // 파일 첨부 옵션인 bf_file_del이 어디까지 있는지 확인한다 int files = 0; foreach (var node in document.QuerySelectorAll("script")) { while (true) { if (node.InnerText.IndexOf(String.Format("bf_file_del[{0}]", files)) >= 0) { files++; continue; } break; } } // 파일이 있는경우 모두 삭제한다. for (int i = 0; i < files; i++) { queryData.Add(String.Format("bf_file_del[{0}]", i), "1"); } // 제목 + 내용 입력 queryData.Add("wr_subject", subject); queryData.Add("wr_content", content); response = await Broker.FetchPage("http://www.clien.net/cs2/bbs/write_update.php", queryData, HttpBroker.Method.Post, (files > 0)); // 글에서 글번호를 발견하면 성공 if (response.IndexOf("wr_id=" + article.ID.ToString()) >= 0) { return(true); } else { return(false); } }
private async Task<List<ArticleInfo>> GoogleSearch(List<ArticleInfo> myArticles) { // 구글 검색 키워드를 만든다 StringBuilder sb = new StringBuilder(); sb.Append('"'); sb.Append(await Clien.GetMyNickname()); sb.Append("님\" " + Board + " site:clien.net"); List<ArticleInfo> searchArticles = new List<ArticleInfo>(); string keyword = sb.ToString(); Console.WriteLine("구글에서 {0} 로 검색하여 해당 게시판에에 내가 쓴 댓글이 있는 글도 수집합니다.", keyword); GoogleSearch search = new GoogleSearch(keyword, 100); while (true) { var searchResult = search.FetchResults(); searchResult.Wait(); foreach (var result in searchResult.Result) { try { // /url?q=http://webcache.googleusercontent.com/search%3Fhl%3Den%26q%3Dcache:phgR10UBmtYJ:http://powoy558vs.egloos.com/2422221%252B%25EB%2585%25B8%25EB%25A6%25AC%25EB%258B%2598%26num%3D100%26%26ct%3Dclnk&sa=U&ei=hzf4U9XsG5S48gW-iIHIDQ&ved=0CKcEECAwZw&usg=AFQjCNEZ3-BmuR67Y2UKzq6nuFHjGOySsQ // "/url?q=" 로 시작하므로 앞에 글자를 제거하자 var proxyUrl = HttpUtility.ParseQueryString(HttpUtility.HtmlDecode(result.Url.Substring(4))); var realUrl = HttpUtility.HtmlDecode(proxyUrl["q"]); int queryIndex = realUrl.IndexOf('?'); var queryString = HttpUtility.ParseQueryString(realUrl.Substring(queryIndex + 1)); // 게시판 URL일때만 큐에 넣어둔다. if (realUrl.IndexOf("board.php") >= 0 && queryString["bo_table"] == Board) { var foundArticle = new ArticleInfo() { Subject = result.Title, ID = long.Parse(queryString["wr_id"]), Table = queryString["bo_table"] }; // 담겨진 요소를 캐시해서 배열에서 요소를 다시 찾아보는낭비를 줄여야하지만 // 이 프로그램은 이정도 성능 이슈는 상관없으므로 무시하자. if (myArticles.Where(x => (x.ID == foundArticle.ID && x.Table.Equals(foundArticle.Table))).Count() == 0) { searchArticles.Add(foundArticle); //Console.WriteLine("[구글링 결과] {0}" + foundArticle.Subject); } } } catch(Exception e) { // 검색결과를 파싱하다가 나는 에러는 무시하자. } } if (search.HasNext == false) { break; } await Task.Delay(1000); } return searchArticles; }
public async Task<bool> DeleteArticle(ArticleInfo article) { var queryData = new Dictionary<string, string>(); queryData.Add("bo_table", article.Table); queryData.Add("wr_id", article.ID.ToString()); string response = await Broker.FetchPage("http://www.clien.net/cs2/bbs/delete.php", queryData, HttpBroker.Method.Get); // 글에서 테이블 주소를 발견하면 성공 if (response.IndexOf("bo_table=" + article.Table) >= 0) { return true; } else { return false; } }
public async Task<bool> UpdateArticle(ArticleInfo article, string subject, string content) { // 첨부파일, 카테고리가 있는지 부터 체크 var queryData = new Dictionary<string, string>(); queryData.Add("w", "u"); queryData.Add("bo_table", article.Table); queryData.Add("wr_id", article.ID.ToString()); string response = await Broker.FetchPage("http://www.clien.net/cs2/bbs/write.php", queryData, HttpBroker.Method.Get); var html = new HtmlDocument(); html.LoadHtml(response); var document = html.DocumentNode; // 카테고리가 있는경우 마지막 카테고리로 선택한다. foreach (var node in document.QuerySelectorAll("select[name='ca_name'] option:last-child")) { queryData.Add("ca_name", node.Attributes["value"].Value); } // 파일 첨부 옵션인 bf_file_del이 어디까지 있는지 확인한다 int files = 0; foreach (var node in document.QuerySelectorAll("script")) { while (true) { if (node.InnerText.IndexOf(String.Format("bf_file_del[{0}]", files)) >= 0) { files++; continue; } break; } } // 파일이 있는경우 모두 삭제한다. for (int i = 0; i < files; i++) { queryData.Add(String.Format("bf_file_del[{0}]", i), "1"); } // 제목 + 내용 입력 queryData.Add("wr_subject", subject); queryData.Add("wr_content", content); response = await Broker.FetchPage("http://www.clien.net/cs2/bbs/write_update.php", queryData, HttpBroker.Method.Post, (files > 0)); // 글에서 글번호를 발견하면 성공 if (response.IndexOf("wr_id=" + article.ID.ToString()) >= 0) { return true; } else { return false; } }
public async Task<List<CommentInfo>> GetMyCommentsInArticle(ArticleInfo article, int comment_page = 1) { var comments = new List<CommentInfo>(); var queryData = new Dictionary<string, string>(); queryData.Add("bo_table", article.Table); queryData.Add("wr_id", article.ID.ToString()); queryData.Add("comment_page", comment_page.ToString()); string content = await Broker.FetchPage("http://www.clien.net/cs2/bbs/board.php", queryData); var html = new HtmlDocument(); html.LoadHtml(content); var document = html.DocumentNode; // 모든 글 선택 foreach (var node in document.QuerySelectorAll("img[alt='수정']")) { // javascript:comment_box('23997945', 'cu');" string modifyScript = node.ParentNode.Attributes["href"].Value; int queryIndex = modifyScript.IndexOf("'"); // ? 문자열 시작부터 "');" 전까지 substring string commentId = modifyScript.Substring(queryIndex + 1, modifyScript.Length - 10 - queryIndex); comments.Add(new CommentInfo() { ArticleID = article.ID, Table = article.Table, CommentID = long.Parse(commentId) }); } return comments; }
private async Task <List <ArticleInfo> > GoogleSearch(List <ArticleInfo> myArticles) { // 구글 검색 키워드를 만든다 StringBuilder sb = new StringBuilder(); sb.Append('"'); sb.Append(await Clien.GetMyNickname()); sb.Append("님\" site:clien.net"); List <ArticleInfo> searchArticles = new List <ArticleInfo>(); string keyword = sb.ToString(); Console.WriteLine("구글에서 {0} 로 검색하여 내가 쓴 댓글이 있는 글도 수집합니다.", keyword); GoogleSearch search = new GoogleSearch(keyword, 100); while (true) { var searchResult = search.FetchResults(); searchResult.Wait(); foreach (var result in searchResult.Result) { try { // /url?q=http://webcache.googleusercontent.com/search%3Fhl%3Den%26q%3Dcache:phgR10UBmtYJ:http://powoy558vs.egloos.com/2422221%252B%25EB%2585%25B8%25EB%25A6%25AC%25EB%258B%2598%26num%3D100%26%26ct%3Dclnk&sa=U&ei=hzf4U9XsG5S48gW-iIHIDQ&ved=0CKcEECAwZw&usg=AFQjCNEZ3-BmuR67Y2UKzq6nuFHjGOySsQ // "/url?q=" 로 시작하므로 앞에 글자를 제거하자 var proxyUrl = HttpUtility.ParseQueryString(HttpUtility.HtmlDecode(result.Url.Substring(4))); var realUrl = HttpUtility.HtmlDecode(proxyUrl["q"]); // 게시판 URL일때만 큐에 넣어둔다. if (realUrl.IndexOf("board.php") >= 0) { int queryIndex = realUrl.IndexOf('?'); var queryString = HttpUtility.ParseQueryString(realUrl.Substring(queryIndex + 1)); var foundArticle = new ArticleInfo() { Subject = result.Title, ID = long.Parse(queryString["wr_id"]), Table = queryString["bo_table"] }; // 담겨진 요소를 캐시해서 배열에서 요소를 다시 찾아보는낭비를 줄여야하지만 // 이 프로그램은 이정도 성능 이슈는 상관없으므로 무시하자. if (myArticles.Where(x => (x.ID == foundArticle.ID && x.Table.Equals(foundArticle.Table))).Count() == 0) { searchArticles.Add(foundArticle); //Console.WriteLine("[구굴링 결과] {0}" + foundArticle.Subject); } } } catch (Exception e) { // 검색결과를 파싱하다가 나는 에러는 무시하자. } } if (search.HasNext == false) { break; } await Task.Delay(1000); } return(searchArticles); }