private void LoadRecursive(XmlNode node, BookmarkFolder folder) { // フォルダを作成 folder.Name = node.Attributes["Name"].Value; folder.Expanded = Boolean.Parse(node.Attributes["Expanded"].Value); XmlAttribute id = node.Attributes["ID"]; if (id != null) { BookmarkEntry.SetEntryId(folder, Int32.Parse(id.Value)); } // 子ノードを検索 foreach (XmlNode subNode in node.SelectNodes("Children/Folder")) { BookmarkFolder subFolder = new BookmarkFolder(); folder.Children.Add(subFolder); LoadRecursive(subNode, subFolder); } // お気に入りコレクションを検索 foreach (XmlNode child in node.SelectNodes("Children/Item")) { string url = child.Attributes["URL"].Value; ThreadHeader header = URLParser.ParseThread(url); if (header != null) { //XmlAttribute idattr = child.Attributes["ID"]; BookmarkEntry entry = null; header.Subject = child.InnerText; //if (idattr != null) // entry = new BookmarkThread(header, Int32.Parse(idattr.Value)); //else entry = new BookmarkThread(header); folder.Children.Add(entry); } } }
/// <summary> /// オンラインで板一覧を更新 ([BBS MENU for 2ch]に対応) /// </summary> /// <param name="url">更新先URL</param> /// <param name="callback">板が移転していた場合に呼ばれるコールバック</param> 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/05 Mizutama実装 // 板情報を抽出 // <BR><BR><B>カテゴリ名</B><BR> // <A HREF=http://[サーバー]/[板名]/>名前</A> MatchCollection cats = Regex.Matches ( htmlData, @"<BR><BR><B>(?<cat>.+?)</B><BR>(?<brds>.+?)(?=\<BR\>\<BR\>\<B\>)", 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, @"<A HREF=(?<url>[^\s>]+).*?>(?<subj>.+?)</A>", 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(); } } }