勢いよくC# Mainのみでコーディング(--;
Wikiのバックアップをテキストベースで保存しておきたっかたので書いてみました。
汎用性は非常に低いので、必要に応じて改造。遅延評価。
rubyの移植も気が向いたらする。
C#
using System;
using System.IO;
using System.Text; // Encoding
using System.Web; // HttpUtility
using System.Net;
using System.Text.RegularExpressions;
class c{
static void Main(string[] args)
{
string wiki_base;
string wiki_page;
if(args.Length<2)
{
wiki_base = "http://chrono.s9.xrea.com/pukiwiki/index.php";
wiki_page = "FrontPage";
}
else
{
wiki_base = args[0];
wiki_page = args[1];
}
// URLエンコード
string wiki_page_encode = HttpUtility.UrlEncode(wiki_page, Encoding.GetEncoding("euc-jp") );
// string wiki_page_encode = HttpUtility.UrlEncode(wiki_page, Encoding.GetEncoding("shift_jis") );
// string wiki_page_encode = HttpUtility.UrlEncode(wiki_page, Encoding.UTF8 );
try{
//プロキシサーバーを指定
// string str_proxy = "http://localhost:8080";
// GlobalProxySelection.Select = new WebProxy( str_proxy );
GlobalProxySelection.Select = WebProxy.GetDefaultProxy();
// 対象ページのバックアップ一覧ページ取得
string open_url = wiki_base + "?"
+ "cmd=backup&"
+ "page="+wiki_page_encode;
WebRequest webreq = WebRequest.Create( open_url );
WebResponse webres = webreq.GetResponse();
Stream st = webres.GetResponseStream();
StreamReader sr = new StreamReader(st);
Console.WriteLine("GET : "+ open_url);
string line;
while( null != (line = sr.ReadLine() ) )
{
// バックアップ一覧のリストにマッチ
// ### <li>のあとにリンカが設定されている場合とされていない場合がある。
Regex reg = new Regex("<li>.*(?<no>[0-9]+) \\((?<date>[0-9-]{10})[^0-9]+(?<time>[0-9:]{8})\\)");
Match m = reg.Match(line);
if( !m.Success ) continue; // マッチしなければ次の行へ
string get_no = m.Groups["no"].Value;
string get_date = m.Groups["date"].Value;
string get_time = m.Groups["time"].Value;
Console.WriteLine("{0}. {1} {2}",get_no,get_date,get_time);
// リンク先ページの取得
string url_sub = open_url + "&age="+get_no+"&action=source";
WebRequest webreq_sub = WebRequest.Create( url_sub );
WebResponse webres_sub = webreq_sub.GetResponse();
Stream st_sub = webres_sub.GetResponseStream();
Console.WriteLine("LinkOpen : "+url_sub);
// Encodingの取得
StreamReader sr_tmp = new StreamReader(st_sub);
Regex reg_enc = new Regex("encoding=\"(?<enc>.*)\"");
string line_tmp;
string enc_type = "";
while( null != (line_tmp = sr_tmp.ReadLine() ) )
{
Match mEnc = reg_enc.Match(line_tmp);
if( mEnc.Success )
{
enc_type = mEnc.Groups["enc"].Value;
break;
}
}
Console.WriteLine("Encoding is "+enc_type);
// 書き込みファイルの設定
string WriteDir = System.Windows.Forms.Application.StartupPath+@"\"+
Regex.Replace(wiki_base, "[\\\\:/<>\\?\\|\"]+", "_");
Directory.CreateDirectory( WriteDir );
string WriteFileName = WriteDir+@"\"+
Regex.Replace(wiki_page, "[\\\\:/<>\\?\\|\"]+", "_")+
String.Format("_{0:D3}_{1}_{2}.txt",
int.Parse(get_no),
get_date,
get_time.Replace(":","") );
StreamWriter sw = new StreamWriter(
WriteFileName,
false,
Encoding.GetEncoding("shift_jis"));
Console.WriteLine("Write : "+WriteFileName);
// 取得したEncodingで読み取り開始
Encoding enc = Encoding.GetEncoding( enc_type );
StreamReader sr_sub = new StreamReader(st_sub, enc);
string line_sub;
bool isRead=false;
while( null != (line_sub = sr_sub.ReadLine() ) )
{
Regex regStart = new Regex("<pre>");
Regex regEnd = new Regex("</pre>");
if(isRead)
{
if( regEnd.IsMatch(line_sub) )
{
isRead = false;
}
}
else
{
if( regStart.IsMatch(line_sub) )
{
isRead = true;
}
else
{
continue;
}
}
sw.WriteLine(line_sub);
}
sw.Close();
sr_tmp.Close();
sr_sub.Close();
st_sub.Close();
webres_sub.Close();
}
sr.Close();
st.Close();
webres.Close();
}
catch(Exception e)
{
Console.WriteLine(e);
}
}
}