#!/usr/bin/perl #!/usr/local/bin/perl # # convert.cgi # # YukiWiki1からYukiWiki2へのデータ変換用CGI # # Based on "YukiWiki1 to WalWiki convert.cgi" by Makio Tsukamoto. # use strict; use CGI::Carp 'fatalsToBrowser'; use lib "."; # 同梱のjcode.pl、Algorithmがあるディレクトリを指定 use AnyDBM_File; use Fcntl; $| = 1; my $jcodelib = 'jcode.pl'; my $kanjicode = 'sjis'; # 'sjis' 'euc' my $newkanjicode = 'euc'; my %form; my %olddb; my %newdb; require "$jcodelib"; &init_form($kanjicode); &main; exit(0); # メイン sub main { if ($form{mycmd} eq 'convert') { &do_convert; } else { &do_form; } } sub do_convert { &print_header('変換結果'); print <<"EOD";
パラメータ
旧データベース名
YukiWiki1の変数\$dbnameの値
$form{old_dbname}
YukiWiki1のデータベースの種類 $form{old_dbtype}
新データベース名
YukiWiki2の変数\$modifier_dir_dataの値と\$datanameの値をスラッシュ(/)でつなげたもの。
$form{new_dataname}
YukiWiki2のデータベースの種類 $form{new_dbtype}
EOD # open old db if ($form{old_dbtype} eq 'dbmopen') { dbmopen(%olddb, "$form{old_dbname}", 0666) or &print_error("(dbmopen) $form{old_dbname} が作れません。"); } else { tie(%olddb, "YukiWikiDB", "$form{old_dbname}") or &print_error("(tie error) $form{old_dbname}"); } # open new db if ($form{new_dbtype} eq 'dbmopen') { dbmopen(%newdb, $form{new_dataname}, 0666) or &print_error("(dbmopen) $form{new_dataname} が作れません。"); } elsif ($form{new_dbtype} eq 'YukiWikiDB') { tie(%newdb, "YukiWikiDB", $form{new_dataname}) or &print_error("(tie error, YukiWikiDB) $form{new_dataname}"); } else { tie(%newdb, "AnyDBM_File", $form{new_dataname}, O_RDWR|O_CREAT, 0666) or &print_error("(tie error, AnyDBM_File) $form{new_dataname}"); } # convert &convert_all; # close old db if ($form{old_dbtype} eq 'dbmopen') { dbmclose(%olddb); } else { untie(%olddb); } # close new db if ($form{new_dbtype} eq 'dbmopen') { dbmclose(%newdb); } elsif ($form{new_dbtype} eq 'YukiWikiDB') { untie(%newdb); } else { untie(%newdb); } } sub convert_all { my $keys = 0; my $result; print <<"EOD"; EOD foreach my $oldkey (keys(%olddb)) { # unarmor my $newkey = ($oldkey =~ /^\[\[(.+)\]\]$/) ? $1 : $oldkey; my $msg = $olddb{$oldkey}; my $oldsize = length($msg); $msg =~ s/ - ([^\[\]][^\n]*)/ - [[$1]]/g if ($oldkey eq 'RecentChanges'); &jcode::convert(\$msg, $newkanjicode); my $newkey_in_oldkanjicode = $newkey; &jcode::convert(\$newkey, $newkanjicode); $newdb{$newkey} = $msg; my $newsize = length($newdb{$newkey}); $keys++; print " \n"; } print <<"EOD";
変換結果
$keys: $oldkey (${oldsize})$newkey_in_oldkanjicode (${newsize})
変換対象$keys 件
EOD } sub do_form { &print_header('変換'); print <<'EOD';
YukiWiki1からYukiWiki2のデータベース変換
旧データベース名
YukiWiki1の変数$dbnameの値
YukiWiki1のデータベースの種類 dbmopen YukiWikiDB
新データベース名
YukiWiki2の変数\$modifier_dir_dataの値と\$datanameの値をスラッシュ(/)でつなげたもの。
YukiWiki2のデータベースの種類 dbmopen YukiWikiDB AnyDBM_File
EOD } # フォームからの情報を連想配列 %form に入れる # &init_form('euc'); sub init_form { my ($charcode) = @_; my $query; if ($ENV{REQUEST_METHOD} =~ /^post$/i) { read(STDIN, $query, $ENV{CONTENT_LENGTH}); } else { $query = $ENV{QUERY_STRING}; } my @assocarray = split(/&/, $query); foreach my $assoc (@assocarray) { my ($property, $value) = split(/=/, $assoc); $value =~ tr/+/ /; $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg; $value =~ s/\x0D\x0A/\n/g; # Walrus add (1) $value =~ tr/\x0D\x0A/\n\n/; # Walrus add (1) &jcode::convert(\$value, $charcode); $form{$property} = $value; } } # エラーページを出力する sub print_error { my ($msg) = @_; &print_header('Error'); exit(0); } sub escape { my ($line) = shift; $line =~ s|<|<|g; $line =~ s|>|>|g; $line =~ s|"|"|g; # $line =~ s|\&|&|g; return $line; } # ページのヘッダを出力 sub print_header { my $title = shift; print <<"EOD"; Content-type: text/html $title EOD } # Definition of YukiWikiDB package YukiWikiDB; my $debug = 1; # Constructor sub new { return shift->TIEHASH(@_); } # tying sub TIEHASH { my ($class, $dbname) = @_; my $self = { dir => $dbname, keys => [], }; if (not -d $self->{dir}) { if (!mkdir($self->{dir}, 0777)) { print "mkdir(" . $self->{dir} . ") fail\n" if ($debug); return undef; } } return bless($self, $class); } # Store sub STORE { my ($self, $key, $val) = @_; my $file = &make_filename($self, $key); if (open(FILE,"> $file")) { binmode(FILE); print FILE $val; close(FILE); return $self->{$key} = $val; } else { print "$file create error."; } } # Fetch sub FETCH { my ($self, $key) = @_; my $file = &make_filename($self, $key); if (open(FILE, $file)) { local $/; $self->{$key} = ; close(FILE); } return $self->{$key}; } # Exists sub EXISTS { my ($self, $key) = @_; my $file = &make_filename($self, $key); return -e($file); } # Delete sub DELETE { my ($self, $key) = @_; my $file = &make_filename($self, $key); unlink $file; return delete $self->{$key}; } sub FIRSTKEY { my ($self) = @_; opendir(DIR, $self->{dir}) or die $self->{dir}; @{$self->{keys}} = grep /\.txt$/, readdir(DIR); foreach my $name (@{$self->{keys}}) { $name =~ s/\.txt$//; $name =~ s/[0-9A-F][0-9A-F]/pack("C", hex($&))/eg; } return shift @{$self->{keys}}; } sub NEXTKEY { my ($self) = @_; return shift @{$self->{keys}}; } sub make_filename { my ($self, $key) = @_; my $enkey = ''; foreach my $ch (split(//, $key)) { $enkey .= sprintf("%02X", ord($ch)); } return $self->{dir} . "/$enkey.txt"; } __END__