Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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&amp;sa=U&amp;ei=hzf4U9XsG5S48gW-iIHIDQ&amp;ved=0CKcEECAwZw&amp;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;
        }
Example #5
0
        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;
            }
        }
Example #6
0
        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;
            }
        }
Example #7
0
        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;
        }
Example #8
0
        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&amp;sa=U&amp;ei=hzf4U9XsG5S48gW-iIHIDQ&amp;ved=0CKcEECAwZw&amp;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);
        }