/// /// オンラインで板一覧を更新 ([BBS MENU for 2ch]に対応) /// /// 更新先URL /// 板が移転していた場合に呼ばれるコールバック public void OnlineUpdate(string url, BoardUpdateEventHandler callback) { HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Headers.Add("Pragma", "no-cache"); req.Headers.Add("Cache-Control", "no-cache"); HttpWebResponse res = (HttpWebResponse)req.GetResponse(); try { IBoardTable newTable = new KatjuBoardTable(); string htmlData; using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.GetEncoding("Shift_Jis"))) htmlData = sr.ReadToEnd(); res.Close(); res = null; /* 2012/12/02のbbsmenu.html変更で板情報が取れなくなってしまった // カテゴリ開始の前に改行を挿入し、処理しやすくする htmlData = Regex.Replace(htmlData, "
", "\r\n
", RegexOptions.IgnoreCase); string[] lines = Regex.Split(htmlData, "\r\n|\r|\n"); // カテゴリ名を検索するための正規表現 Regex regex1 = new Regex("
(?.+?)
", RegexOptions.IgnoreCase | RegexOptions.Compiled); // URL、サーバー名、ディレクトリ名、表示名を検索するための正規表現 Regex regex2 = new Regex(@"[^\s>]+).*?>(?.+?)", RegexOptions.IgnoreCase | RegexOptions.Compiled); for (int i = 0; i < lines.Length; ) { // カテゴリを検索 Match matchCate = regex1.Match(lines[i++]); if (matchCate.Success) { // カテゴリを作成 Category category = new Category( matchCate.Groups["category"].Value); while (i < lines.Length) { if (lines[i] == String.Empty) break; // ボードを検索 Match matchBrd = regex2.Match(lines[i++]); if (matchBrd.Success) { // ボード情報を作成 BoardInfo newBoard = URLParser.ParseBoard(matchBrd.Groups["url"].Value); if (newBoard != null) { newBoard.Name = matchBrd.Groups["subj"].Value; category.Children.Add(newBoard); if (callback != null) { // 新板&移転チェック BoardInfo old = FromName(newBoard.Name, newBoard.DomainPath); BoardUpdateEventArgs args = null; // 見つからなければ新板と判断 if (old == null) { args = new BoardUpdateEventArgs(BoardUpdateEvent.New, null, newBoard); } // 見つかったが板のURLが違う場合は移転と判断 else if (old.Server != newBoard.Server) { args = new BoardUpdateEventArgs(BoardUpdateEvent.Change, old, newBoard); } if (args != null) callback(this, args); } } } } if (category.Children.Count > 0) newTable.Items.Add(category); } } */ // 2012/12/05 Mizutama実装 // 板情報を抽出 // <BR><BR><B>カテゴリ名</B><BR> // <A HREF=http://[サーバー]/[板名]/>名前</A> MatchCollection cats = Regex.Matches ( htmlData , @"

(?.+?)
(?.+?)(?=\\\)" , RegexOptions.Singleline|RegexOptions.IgnoreCase ); foreach ( Match m in cats ) { Category category = new Category( m.Groups["cat"].Value ); MatchCollection brds = Regex.Matches ( m.Groups["brds"].Value , @"[^\s>]+).*?>(?.+?)" , RegexOptions.Singleline|RegexOptions.IgnoreCase ); foreach ( Match matchBrd in brds ) { // ボード情報を作成 BoardInfo newBoard = URLParser.ParseBoard( matchBrd.Groups["url"].Value ); if ( newBoard != null ) { newBoard.Name = matchBrd.Groups["subj"].Value; category.Children.Add( newBoard ); if ( callback != null ) { // 新板&移転チェック BoardInfo old = FromName( newBoard.Name , newBoard.DomainPath ); BoardUpdateEventArgs args = null; // 見つからなければ新板と判断 if ( old == null ) { args = new BoardUpdateEventArgs( BoardUpdateEvent.New , null , newBoard ); } // 見つかったが板のURLが違う場合は移転と判断 else if ( old.Server != newBoard.Server ) { args = new BoardUpdateEventArgs( BoardUpdateEvent.Change , old , newBoard ); } if ( args != null ) callback( this , args ); } } } if ( category.Children.Count > 0 ) { newTable.Items.Add( category ); } } if (newTable.Items.Count > 0) { // 新しい板一覧を設定 Items.Clear(); Items.AddRange(newTable.Items); } else { throw new ApplicationException("板一覧の更新に失敗しました"); } } catch (ThreadAbortException) { if (callback != null) callback(this, new BoardUpdateEventArgs(BoardUpdateEvent.Cancelled, null, null)); } catch (Exception ex) { TwinDll.ShowOutput(ex); } finally { if (res != null) res.Close(); } }