勢いよく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); } } }