From 7418ab588f1d815506b015303a49d469e545f231 Mon Sep 17 00:00:00 2001 From: Ma Tao Date: Sun, 16 Sep 2012 04:37:15 +0800 Subject: [PATCH] init version --- BMY.cs | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++ BMY.csproj | 44 ++++++++ HTTPClient.cs | 129 +++++++++++++++++++++++ Main.cs | 57 ++++++++++ 4 files changed, 516 insertions(+) create mode 100644 BMY.cs create mode 100644 BMY.csproj create mode 100644 HTTPClient.cs create mode 100644 Main.cs diff --git a/BMY.cs b/BMY.cs new file mode 100644 index 0000000..e44ee4b --- /dev/null +++ b/BMY.cs @@ -0,0 +1,286 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Web; +using System.Text; +using System.Text.RegularExpressions; +using System.Linq; + +namespace BMY +{ + public class Article + { + public string artToken{ get; private set; } + public string artTitle{ get; private set; } + public string artText{ get; private set; } + public string artRef { get; private set; } + private Topic artTopic{ get; set; } + public Article (Topic top, string tok, string t) + { + artTopic = top; + artTitle = t; + artToken = tok; + var m = Regex.Match (artToken, @"&F=(.+)$"); + artRef = m.Groups [1].Value; + } + private void fetchText (BMYClient client) + { + if (artText != null) { + return; + } + var url = string.Format ("{0}{1}{2}", BMYClient.firstURL, client.bbsToken, artToken); + var page = client.Client.GetSrc (url, "GBK"); + var match = Regex.Match (page, @"(发信人:.+)本文链接", RegexOptions.Multiline); + if (match.Success) { + var text = match.Groups [1].Value; + text = text.Replace ("
", "\n"); + text = Regex.Replace (text, @"<[^>]+>", ""); + artText = text; + } + } + public bool reply (BMYClient client, string text, string title = null, string qmd = "---\nFrom Mono C# Client") + { + if (title == null) { + if (artTitle.Substring (0, 3) != "Re:") { + title = "Re: " + artTitle; + } else { + title = artTitle; + } + } + var url = string.Format ("{0}{1}bbssnd?board={2}&th={3}&ref={4}", + BMYClient.firstURL, + client.bbsToken, + artTopic.boardID, + artTopic.topicID, + artRef); + Console.WriteLine (url); + var data = string.Format ("title={0}&text={1}", title, text + "\n" + qmd); + var rsp = client.Client.PostData (url, data, "GBK", "GBK"); + Console.WriteLine ("Response:"); + Console.WriteLine (rsp); + + return true; + } + + } + public class Topic + { + public string topicID{ get; private set; } + public string topicTitle{ get; private set; } + public string boardID { get; private set; } + public List
articleList{ get; private set; } + public BBSBoard boardHandle { get; private set; } + public Topic (BBSBoard bn, string id, string title) + { + boardHandle = bn; + boardID = boardHandle.boardID; + topicTitle = title; + topicID = id; + + articleList = new List
(); + } + public void Refresh (BMYClient client) + { + if (articleList.Count != 0) { + articleList.Clear (); + + } + fetchArticles (client); + } + private void fetchArticles (BMYClient client) + { + var url = string.Format ("{0}{1}tfind?B={2}&th={3}", BMYClient.firstURL, client.bbsToken, boardID, topicID); + var page = client.Client.GetSrc (url); + Console.WriteLine (page); + var matchs = Regex.Matches (page, @"]+)>([^<]+)", RegexOptions.Multiline); + foreach (Match m in matchs) { + articleList.Add (new Article (this, m.Groups [1].Value, m.Groups [2].Value)); + } + } + + } + public class Topics + { + public BBSBoard boardHandle{ get; private set; } + public List topicList { + get; + private set; + } + private string nextURL{ get; set; } + private string preURL{ get; set; } + public Topics (BBSBoard b) + { + boardHandle = b; + topicList = new List (); + } + private string getBoardPage (BMYClient client) + { + var url = string.Format ("{0}{1}tdoc?B={2}", BMYClient.firstURL, client.bbsToken, boardHandle.boardID); + var page = client.Client.GetSrc (url); + return page; + } + private void fetchList (BMYClient client) + { + var page = getBoardPage (client); + Console.WriteLine (page); + var matchs = Regex.Matches (page, "]*&th=([^>\"]+)>([^<]+)", RegexOptions.Multiline); + foreach (Match m in matchs) { + topicList.Add (new Topic (boardHandle, m.Groups [1].Value, m.Groups [2].Value)); + } + } + public void Refresh (BMYClient client) + { + if (topicList.Count != 0) { + topicList.Clear (); + } + + fetchList (client); + } + public override string ToString () + { + var titles = from Topic t in this.topicList + select t.topicTitle; + var res = string.Empty; + foreach (var i in titles) { + res += (i + "\n"); + } + return res; + } + } + public class BBSBoard + { + public string boardID { get; private set; } + public string boardName { get; private set; } + public Topics topics { get; private set; } + + public BBSBoard (string id, string name) + { + boardID = id; + boardName = name; + topics = new Topics (this); + } + public bool post (BMYClient client, string title, string text, string qmd = "---\nFrom Mono C#\n") + { + var url = string.Format ("{0}{1}bbssnd?board={2}&th=-1", BMYClient.firstURL, client.bbsToken, boardID); + var data = string.Format ("title={0}&text=\n{1}", title, text + "\n" + qmd); + var rsp = client.Client.PostData (url, data, "GBK", "GBK"); + Console.WriteLine (rsp); + return true; + } + + } + public class BMYClient + { + public static string firstURL = "http://bbs.xjtu.edu.cn/"; + static string sectionURL = "boa?secstr={0}"; + static Dictionary secList = new Dictionary + { + {"交通大学","1"}, + {"开发技术","2"}, + {"电脑应用","3"}, + {"学术科学","4"}, + {"社会科学","5"}, + {"文学艺术","6"}, + {"知性感性","7"}, + {"体育运动","8"}, + {"休闲音乐","9"}, + {"游戏天地","G"}, + {"新闻信息","N"}, + {"乡音乡情", "H"}, + {"校务信息", "A"}, + {"俱乐部区", "C"}, + }; + public string passWord { get; set; } + public string userName { get; set; } + public bool isLogin { get; private set; } + public string bbsToken { get; private set; } + public HttpClient Client { get; private set; } + public BMYClient (string user, string pass) + { + userName = user; + passWord = pass; + Client = new HttpClient (); + } + public string login () + { + + Client.Headers ["User-Agent"] = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " + + "(compatible; MSIE 6.0; Windows NT 5.1; " + + ".NET CLR 1.1.4322; .NET CLR 2.0.50727)"; + Console.WriteLine (firstURL); + + string loginToken = string.Format ("{0}={1}&{2}={3}", "id", userName, "pw", passWord); + Console.WriteLine (loginToken); + string result = Client.PostData (firstURL + "BMY/bbslogin", loginToken, "ASCII", "GBK"); + Console.WriteLine ("Login:"); + Console.WriteLine (result); + Match match = Regex.Match (result, @" url=(.+/)"); + if (match.Success) { + var uri = match.Groups [1].Value; + Console.WriteLine (uri); + bbsToken = uri; + isLogin = true; + return uri; + } else { + throw new Exception ("Login Failed"); + + } + } + public string getMain (string token) + { + var uri = firstURL + token; + return Client.GetSrc (uri, "GBK"); + } + public string getNav (string page) + { + Match match = Regex.Match (page, @"src=(bbsleft.+) "); + var navToken = match.Groups [1].Value; + var navURL = firstURL + bbsToken + navToken; + return Client.GetSrc (navURL, "GBK"); + + } + private string getSecURL (string token) + { + var url = string.Format ("{0}{1}{2}", firstURL, bbsToken, string.Format (sectionURL, token)); + Console.WriteLine (url); + return url; + } + private string getSecPage (string token) + { + var url = getSecURL (token); + return Client.GetSrc (url); + } + private string getBoardURL (string token) + { + var url = string.Format ("{0}{1}{2}", firstURL, bbsToken, token); + return url; + } + + private List parserBoardList (string page) + { + var dict = new List (); + //var pattern = new Regex ("(.*)"); + var matchs = Regex.Matches (page, @"]*)>([^<]+)", RegexOptions.Multiline); + + foreach (Match m in matchs) { + //Console.WriteLine (m); + if (!Regex.IsMatch (m.Groups [2].Value, @"[a-zA-Z0-9 ]+")) { + dict.Add (new BBSBoard (m.Groups [1].Value, m.Groups [2].Value)); + } + + } + return dict; + + } + + public List getBoardList (string secName) + { + var secNo = secList [secName]; + var page = getSecPage (secNo); + Console.WriteLine ("Sec:\n {0}{1}\n{2}", secName, secNo, page); + return parserBoardList (page); + } + + } +} + diff --git a/BMY.csproj b/BMY.csproj new file mode 100644 index 0000000..9182d92 --- /dev/null +++ b/BMY.csproj @@ -0,0 +1,44 @@ + + + + Debug + x86 + 8.0.50727 + 2.0 + {38CDFC97-53E2-420D-87F6-0AFDC6B94144} + Exe + test1 + test1 + v2.0 + + + True + full + False + bin\Debug + DEBUG; + prompt + 4 + x86 + True + + + none + False + bin\Release + prompt + 4 + x86 + True + + + + + + + + + + + + \ No newline at end of file diff --git a/HTTPClient.cs b/HTTPClient.cs new file mode 100644 index 0000000..a0aaa4d --- /dev/null +++ b/HTTPClient.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Web; +using System.Text; +using System.Text.RegularExpressions; +using System.Linq; +namespace BMY +{ + public class HttpClient : WebClient + { + // Cookie 容器 + private CookieContainer cookieContainer; + + /// + /// 创建一个新的 WebClient 实例。 + /// + public HttpClient () + { + this.cookieContainer = new CookieContainer (); + } + + /// + /// 创建一个新的 WebClient 实例。 + /// + /// Cookie 容器 + public HttpClient (CookieContainer cookies) + { + this.cookieContainer = cookies; + } + + /// + /// Cookie 容器 + /// + public CookieContainer Cookies { + get { return this.cookieContainer; } + set { this.cookieContainer = value; } + } + + /// + /// 返回带有 Cookie 的 HttpWebRequest。 + /// + /// + /// + protected override WebRequest GetWebRequest (Uri address) + { + WebRequest request = base.GetWebRequest (address); + if (request is HttpWebRequest) { + HttpWebRequest httpRequest = request as HttpWebRequest; + httpRequest.CookieContainer = cookieContainer; + } + return request; + } + + #region 封装了PostData, GetSrc 和 GetFile 方法 + /// + /// 向指定的 URL POST 数据,并返回页面 + /// + /// POST URL + /// POST 的 数据 + /// POST 数据的 CharSet + /// 页面的 CharSet + /// 页面的源文件 + public string PostData (string uriString, string postString, string postStringEncoding, string dataEncoding) + { + try { + // 将 Post 字符串转换成字节数组 + byte[] postData = Encoding.GetEncoding (postStringEncoding).GetBytes (postString); + this.Headers.Add ("Content-Type", "application/x-www-form-urlencoded"); + // 上传数据,返回页面的字节数组 + byte[] responseData = this.UploadData (uriString, "POST", postData); + // 将返回的将字节数组转换成字符串(HTML); + string srcString = Encoding.GetEncoding (dataEncoding).GetString (responseData); + srcString = srcString.Replace ("\t", ""); + srcString = srcString.Replace ("\r", ""); + srcString = srcString.Replace ("\n", ""); + + return srcString; + } catch (WebException we) { + + return string.Empty; + } + } + + /// + /// 获得指定 URL 的源文件 + /// + /// 页面 URL + /// 页面的 CharSet + /// 页面的源文件 + public string GetSrc (string uriString, string dataEncoding = "GBK") + { + try { + // 返回页面的字节数组 + byte[] responseData = this.DownloadData (uriString); + // 将返回的将字节数组转换成字符串(HTML); + string srcString = Encoding.GetEncoding (dataEncoding).GetString (responseData); + srcString = srcString.Replace ("\t", ""); + srcString = srcString.Replace ("\r", ""); + srcString = srcString.Replace ("\n", ""); + + return srcString; + } catch (WebException we) { + + return string.Empty; + } + } + + /// + /// 从指定的 URL 下载文件到本地 + /// + /// 文件 URL + /// 本地文件的完成路径 + /// + public bool GetFile (string urlString, string fileName) + { + try { + this.DownloadFile (urlString, fileName); + + return true; + } catch (WebException we) { + + return false; + } + } +#endregion + } +} + diff --git a/Main.cs b/Main.cs new file mode 100644 index 0000000..46115a8 --- /dev/null +++ b/Main.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Web; +using System.Text; +using System.Text.RegularExpressions; +using System.Linq; + +namespace BMY +{ + + public static class ListUtils + { + public static T ReversedIndex (this List self, int index) + { + return self [self.Count - index - 1]; + } + } + class MainClass + { + public static void Main (string[] args) + { + List numbers = new List{1,2,3}; + + var filtered = from int n in numbers + where n % 2 == 1 + select n; + foreach (int n in filtered) { + Console.WriteLine (n); + } + BMYClient cli = new BMYClient ("Guest", ""); + var uri = cli.login (); + var page = cli.getMain (uri); + Console.WriteLine ("Main Page"); + Console.WriteLine (page); + + page = cli.getNav (page); + Console.WriteLine ("Nav Page"); + Console.WriteLine (page); + + var sec = "电脑应用"; + var blist = cli.getBoardList (sec); + BBSBoard board = blist [3]; + foreach (var p in blist) { + Console.WriteLine ("{0},{1}", p.boardID, p.boardName); + } + board.topics.Refresh (cli); + Console.WriteLine (board.topics); + var top = board.topics.topicList.ReversedIndex (0); + top.Refresh (cli); + top.articleList.ReversedIndex (0) .reply (cli, "Test Mono C# libbmy Article Reply"); + //board.post (cli, "Test From Mono C#", "Just Test"); + // filtered.ForEach(Console.WriteLine); + Console.WriteLine ("Hello World!"); + } + } +}