fork(1) download
  1. /// <summary>
  2. /// オンラインで板一覧を更新 ([BBS MENU for 2ch]に対応)
  3. /// </summary>
  4. /// <param name="url">更新先URL</param>
  5. /// <param name="callback">板が移転していた場合に呼ばれるコールバック</param>
  6. public void OnlineUpdate(string url, BoardUpdateEventHandler callback)
  7. {
  8. HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
  9. req.Headers.Add("Pragma", "no-cache");
  10. req.Headers.Add("Cache-Control", "no-cache");
  11.  
  12. HttpWebResponse res = (HttpWebResponse)req.GetResponse();
  13.  
  14. try
  15. {
  16. IBoardTable newTable = new KatjuBoardTable();
  17. string htmlData;
  18.  
  19. using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.GetEncoding("Shift_Jis")))
  20. htmlData = sr.ReadToEnd();
  21.  
  22. res.Close();
  23. res = null;
  24.  
  25. /* 2012/12/02のbbsmenu.html変更で板情報が取れなくなってしまった
  26.   // カテゴリ開始の前に改行を挿入し、処理しやすくする
  27.   htmlData = Regex.Replace(htmlData, "<br><b>", "\r\n<br><b>", RegexOptions.IgnoreCase);
  28.   string[] lines = Regex.Split(htmlData, "\r\n|\r|\n");
  29.  
  30.   // カテゴリ名を検索するための正規表現
  31.   Regex regex1 = new Regex("<br><b>(?<category>.+?)</b><br>",
  32.   RegexOptions.IgnoreCase | RegexOptions.Compiled);
  33.  
  34.   // URL、サーバー名、ディレクトリ名、表示名を検索するための正規表現
  35.   Regex regex2 = new Regex(@"<a href=(?<url>[^\s>]+).*?>(?<subj>.+?)</a>",
  36.   RegexOptions.IgnoreCase | RegexOptions.Compiled);
  37.  
  38.   for (int i = 0; i < lines.Length; )
  39.   {
  40.   // カテゴリを検索
  41.   Match matchCate = regex1.Match(lines[i++]);
  42.   if (matchCate.Success)
  43.   {
  44.   // カテゴリを作成
  45.   Category category = new Category(
  46.   matchCate.Groups["category"].Value);
  47.  
  48.   while (i < lines.Length)
  49.   {
  50.   if (lines[i] == String.Empty)
  51.   break;
  52.  
  53.   // ボードを検索
  54.   Match matchBrd = regex2.Match(lines[i++]);
  55.   if (matchBrd.Success)
  56.   {
  57.   // ボード情報を作成
  58.   BoardInfo newBoard = URLParser.ParseBoard(matchBrd.Groups["url"].Value);
  59.   if (newBoard != null)
  60.   {
  61.   newBoard.Name = matchBrd.Groups["subj"].Value;
  62.   category.Children.Add(newBoard);
  63.  
  64.   if (callback != null)
  65.   {
  66.   // 新板&移転チェック
  67.   BoardInfo old = FromName(newBoard.Name, newBoard.DomainPath);
  68.   BoardUpdateEventArgs args = null;
  69.  
  70.   // 見つからなければ新板と判断
  71.   if (old == null)
  72.   {
  73.   args = new BoardUpdateEventArgs(BoardUpdateEvent.New, null, newBoard);
  74.   }
  75.   // 見つかったが板のURLが違う場合は移転と判断
  76.   else if (old.Server != newBoard.Server)
  77.   {
  78.   args = new BoardUpdateEventArgs(BoardUpdateEvent.Change, old, newBoard);
  79.   }
  80.  
  81.   if (args != null)
  82.   callback(this, args);
  83.   }
  84.   }
  85.   }
  86.   }
  87.  
  88.   if (category.Children.Count > 0)
  89.   newTable.Items.Add(category);
  90.   }
  91.   }
  92. */
  93. // 2012/12/05 Mizutama実装
  94. // 板情報を抽出
  95. // <BR><BR><B>カテゴリ名</B><BR>
  96. // <A HREF=http://[サーバー]/[板名]/>名前</A>
  97. MatchCollection cats = Regex.Matches
  98. (
  99. htmlData ,
  100. @"<BR><BR><B>(?<cat>.+?)</B><BR>(?<brds>.+?)(?=\<BR\>\<BR\>\<B\>)" ,
  101. RegexOptions.Singleline|RegexOptions.IgnoreCase
  102. );
  103. foreach ( Match m in cats )
  104. {
  105. Category category = new Category( m.Groups["cat"].Value );
  106.  
  107. MatchCollection brds = Regex.Matches
  108. (
  109. m.Groups["brds"].Value ,
  110. @"<A HREF=(?<url>[^\s>]+).*?>(?<subj>.+?)</A>" ,
  111. RegexOptions.Singleline|RegexOptions.IgnoreCase
  112. );
  113. foreach ( Match matchBrd in brds )
  114. {
  115. // ボード情報を作成
  116. BoardInfo newBoard = URLParser.ParseBoard( matchBrd.Groups["url"].Value );
  117. if ( newBoard != null )
  118. {
  119. newBoard.Name = matchBrd.Groups["subj"].Value;
  120. category.Children.Add( newBoard );
  121.  
  122. if ( callback != null )
  123. {
  124. // 新板&移転チェック
  125. BoardInfo old = FromName( newBoard.Name , newBoard.DomainPath );
  126. BoardUpdateEventArgs args = null;
  127.  
  128. // 見つからなければ新板と判断
  129. if ( old == null )
  130. {
  131. args = new BoardUpdateEventArgs( BoardUpdateEvent.New , null , newBoard );
  132. }
  133. // 見つかったが板のURLが違う場合は移転と判断
  134. else if ( old.Server != newBoard.Server )
  135. {
  136. args = new BoardUpdateEventArgs( BoardUpdateEvent.Change , old , newBoard );
  137. }
  138.  
  139. if ( args != null )
  140. callback( this , args );
  141. }
  142. }
  143. }
  144.  
  145. if ( category.Children.Count > 0 )
  146. {
  147. newTable.Items.Add( category );
  148. }
  149. }
  150.  
  151. if (newTable.Items.Count > 0)
  152. {
  153. // 新しい板一覧を設定
  154. Items.Clear();
  155. Items.AddRange(newTable.Items);
  156. }
  157. else
  158. {
  159. throw new ApplicationException("板一覧の更新に失敗しました");
  160. }
  161. }
  162. catch (ThreadAbortException)
  163. {
  164. if (callback != null)
  165. callback(this, new BoardUpdateEventArgs(BoardUpdateEvent.Cancelled, null, null));
  166. }
  167. catch (Exception ex)
  168. {
  169. TwinDll.ShowOutput(ex);
  170. }
  171. finally
  172. {
  173. if (res != null)
  174. res.Close();
  175. }
  176. }
  177.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty