開発環境 Microsoft Visual C# 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 空のプロジェクト
プロジェクト名 Jien2ch

プロジェクト

新しいプロジェクト
テンプレート:空のプロジェクト
名前:Jien2ch

プロジェクトの保存
[ソリューションのディレクトリを作成]にチェックを付けておくと、
ソリューションに新しいプロジェクトを追加する時にプロジェクトの階層が整う。

プロジェクト/プロパティ
アプリケーションタブ
出力の種類:Windows アプリケーション

フォーム

プロジェクトにクラスを追加
テンプレート:Windows フォーム
名前:Form1

Form1プロパティ
Text:Jien2ch
Size:800, 600

コンテナー/SplitContainerをForm1上にドロップ
名前:splitContainer1
FixedPanel:Panel1

コモン コントロール/TreeViewをPanel1上にドロップ
名前:treeView1
Dock:Fill

コモン コントロール/TextBoxをPanel2上にドロップ
名前:textBox1
Dock:Fill
MultiLine:True
ScrollBars:Vertical

クラスライブラリ

ソリューションに新しいプロジェクトを追加
テンプレート:クラス ライブラリ
名前:Lib2ch
Class1.csは削除
Lib2chに以下の新しいフォルダーを追加

Data
IO
Model

各種クラスを追加

Lib2ch
+Data
 +BbsMenuItem
 +FileResult
 +SubjectData
 +SubjectList
+IO
 +File
 +FileManager
+Model
 +BbsMenu
 +Subject

Jien2chプロジェクトの参照設定にプロジェクトLib2chを追加

イベントハンドラ

Form1にLoadイベントハンドラを追加
treeView1にAfterSelectイベントハンドラを追加


namespace Jien2ch


Program.cs
using System.Windows.Forms;
 
namespace Jien2ch
{
	class Program
	{
		static void Main()
		{
			Application.Run(new Form1());
		}
	}
}
 

Form1.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Lib2ch.Data;
using Lib2ch.Model;
 
namespace Jien2ch
{
	public partial class Form1 : Form
	{
		Subject _Subject = new Subject();
 
		public Form1()
		{
			InitializeComponent();
		}
 
		private void Form1_Load(object sender, EventArgs e)
		{
			#region 板一覧
			BbsMenu bbsMenu = new BbsMenu();
			List<BbsMenuItem> bbsMenuList = bbsMenu.GetMenuList();
			foreach (BbsMenuItem item in bbsMenuList)
			{
				TreeNode childNode = new TreeNode();
				//childNode.Name = item.Name;
				childNode.Text = item.Name;
				childNode.Tag = item;
				// 親ノード検索
				TreeNode[] node = treeView1.Nodes.Find(item.ParentName, false);
				if (node.Length == 0)
				{
					TreeNode parent = new TreeNode();
					parent.Name = item.ParentName;	// 検索用
					parent.Text = parent.Name;	// 表示用
					parent.Nodes.Add(childNode);
					treeView1.Nodes.Add(parent);
				}
				else
				{
					node[0].Nodes.Add(childNode);
				}
			}
			#endregion
		}
 
		#region 板一覧アイテム選択時
		private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
		{
			if (e.Node.Tag != null)
			{
				ThreadListAdd((BbsMenuItem)e.Node.Tag);
			}
		}
 
		// スレッド一覧
		void ThreadListAdd(BbsMenuItem bbsMenuItem)
		{
			SubjectList list = _Subject.Get(bbsMenuItem);
 
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			int num = 0;	// 番号
			foreach (SubjectData data in list.List)
			{
				num++;
				sb.Append(num + ":[" + data.Title + "]\r\n");
			}
			textBox1.Text = sb.ToString();
		}
		#endregion
	}
}
 


namespace Lib2ch.Data


BbsMenuItem.cs
namespace Lib2ch.Data
{
	public class BbsMenuItem
	{
		public string ParentName;
		public string Name;
		public string Url;
 
		public string Directory
		{
			get
			{
				return "/" + ParentName + "/" + Name;
			}
		}
	}
}
 

FileResult.cs
using System.Collections.Generic;
 
namespace Lib2ch.Data
{
	class FileResult
	{
		public List<string> Line = new List<string>();
	}
}
 

SubjectData.cs
namespace Lib2ch.Data
{
	public class SubjectData : BbsMenuItem
	{
		public string Title;
 
		public SubjectData(string line)
		{
			Title = line;
		}
	}
}
 

SubjectList.cs
using System.Collections.Generic;
 
namespace Lib2ch.Data
{
	public class SubjectList : BbsMenuItem
	{
		public List<SubjectData> List = new List<SubjectData>();
 
		public void Parsing(List<string> list)
		{
			foreach (string line in list)
			{
				SubjectData data = new SubjectData(line);
				data.ParentName = ParentName;
				data.Name = Name;
				data.Url = Url;
				List.Add(data);
			}
		}
	}
}
 


namespace Lib2ch.IO


File.cs
using System.IO;
using System.Collections.Generic;
using System.Net;
using System.Text;
using Lib2ch.Data;
 
namespace Lib2ch.IO
{
	class File
	{
		Encoding _Type = Encoding.GetEncoding("Shift_JIS");
 
		protected FileResult LocalReader(string path)
		{
			try
			{
				FileResult fileResult = new FileResult();
				using (StreamReader sr = new StreamReader(path, _Type))
				{
					string line;
					while ((line = sr.ReadLine()) != null)
					{
						fileResult.Line.Add(line);
					}
				}
				return fileResult;
			}
			catch
			{
				return null;
			}
		}
 
		protected FileResult UrlReader(string url)
		{
			HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
			req.UserAgent = "Monazilla/1.00(Jien2ch/Lib2ch)";
			req.AddRange(0);
			req.KeepAlive = false;
			req.Headers.Add("Pragma", "no-cache");
			req.Headers.Add("Cache-Control", "no-cache");
			WebResponse res = null;
			FileResult fileResult = new FileResult();
			try
			{
				res = req.GetResponse();
			}
			catch (WebException)
			{
				return fileResult;
			}
			using (Stream stream = res.GetResponseStream())
			{
				using (StreamReader sr = new StreamReader(stream, _Type))
				{
					string line;
					while ((line = sr.ReadLine()) != null)
					{
						fileResult.Line.Add(line);
					}
				}
			}
			return fileResult;
		}
 
		protected bool LocalWriter(string dir, string file, List<string> writeData)
		{
			if (!Directory.Exists(dir))
			{
				Directory.CreateDirectory(dir);
			}
			try
			{
				using (StreamWriter sw = new StreamWriter(dir + file, false, _Type))
				{
					sw.NewLine = "\n";
					foreach (string line in writeData)
					{
						sw.WriteLine(line);
					}
				}
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
}
 

FileManager.cs
using Lib2ch.Data;
 
namespace Lib2ch.IO
{
	class FileManager : File
	{
		public FileResult StandardCheck(string path, string host, string fileName)
		{
			FileResult fileResult = new FileResult();
			fileResult = LocalReader(path + fileName);
			if (fileResult == null)
			{
				// サーバーからダウンロード
				fileResult = UrlReader(host + fileName);
				if (fileResult == null) return null;
				// ファイルの書き込み
				if (!LocalWriter(path, fileName, fileResult.Line))
				{
					return null;
				}
			}
			return fileResult;
		}
	}
}
 


namespace Lib2ch.Model


BbsMenu.cs
using System.Collections.Generic;
using Lib2ch.Data;
using Lib2ch.IO;
 
namespace Lib2ch.Model
{
	public class BbsMenu
	{
		string _Path = "./Log";
		string _FileName = "/bbsmenu.html";
		string _Host = "http://menu.2ch.net";
 
		string _HeadStart = "<BR><BR><B>";
		string _HeadEnd = "</B>";
		string _BbsStart = "<A HREF=";
		string _UrlEnd1 = "/>";
		string _UrlEnd2 = "/ TARGET=_blank>";
		string _BbsEnd = "</A>";
 
		FileManager _File = new FileManager();
 
		public List<BbsMenuItem> GetMenuList()
		{
			// ファイルの有無
			FileResult fileResult = _File.StandardCheck(_Path, _Host, _FileName);
			if (fileResult == null) return null;
			// 解析処理
			return BbsMenuParsing(fileResult.Line);
		}
 
		List<BbsMenuItem> BbsMenuParsing(List<string> data)
		{
			List<BbsMenuItem> list = new List<BbsMenuItem>();
			string parent = null;
			foreach (string line in data)
			{
				// 見出し
				// <BR><BR><B>(parent)</B>
				int index1 = line.IndexOf(_HeadStart);
				if (index1 != -1)
				{
					int index2 = line.IndexOf(_HeadEnd);
					if (index2 != -1)
					{
						int start = index1 + _HeadStart.Length;
						parent = line.Substring(start, index2 - start);
					}
				}
				if (parent == null) continue;
 
				BbsMenuItem item = BbsMenuFindLine(line, _BbsStart, _UrlEnd1, _BbsEnd);
				if (item == null)
				{
					item = BbsMenuFindLine(line, _BbsStart, _UrlEnd2, _BbsEnd);
				}
				if (item != null)
				{
					item.ParentName = parent;
					list.Add(item);
				}
			}
			return list;
		}
 
		// 板のURLと名前を取得
		// <A HREF=(Url)/>(Name)</A>
		// <A HREF=(Url)/ TARGET=_blank>(Name)</A>
		BbsMenuItem BbsMenuFindLine(string line, string word1, string word2, string word3)
		{
			int index1 = line.IndexOf(word1);
			if (index1 == -1) return null;
			int index2 = line.IndexOf(word2);
			if (index2 == -1) return null;
			int index3 = line.IndexOf(word3);
			if (index3 == -1) return null;
 
			BbsMenuItem item = new BbsMenuItem();
			int start1 = index1 + word1.Length;
			int start2 = index2 + word2.Length;
			item.Url = line.Substring(start1, index2 - start1);
			item.Name = line.Substring(start2, index3 - start2);
			return item;
		}
	}
}
 

Subject.cs
using Lib2ch.Data;
using Lib2ch.IO;
 
namespace Lib2ch.Model
{
	public class Subject
	{
		FileManager _File = new FileManager();
 
		public SubjectList Get(BbsMenuItem bbsMenuItem)
		{
			SubjectList sl = new SubjectList();
			sl.Name = bbsMenuItem.Name;
			sl.Url = bbsMenuItem.Url;
			sl.ParentName = bbsMenuItem.ParentName;
			FileResult fileResult = _File.StandardCheck(
				"./Log" + sl.Directory, sl.Url, "/subject.txt");
			if (fileResult == null) return null;
			sl.Parsing(fileResult.Line);
			return sl;
		}
	}
}
 
最終更新:2012年11月12日 21:18