#!/usr/bin/perl -w # # shinGETsu - P2P anonymous BBS # # (c) Fuktommy # Released under the GNU General Public License # $Id: $ # # 新月0.1のキャッシュを0.2以降の形式に変換します # 使いかた # % cd 新月のCGIがあるディレクトリ # % perl このスクリプト # 変換後は古いキャッシュを消しても構いません # dat/title-table というファイルに一時的な情報を書き込みます # うまく変換できないことがありますが、だいたい大丈夫でしょう # use lib qw(..); # 上と同じものを書く use Jcode; use Shingetsu::CacheStat; use Shingetsu::Config; use Shingetsu::Extern; use Shingetsu::Gateway; use Shingetsu::Util; # 新しいIDへの変換 sub newid($) { $newid{$_[0]} || "xxxxxxxx" } sub newtitle($) { $$tt{title}{$_[0]} || $_[0] } $datadir = $Shingetsu::Config::datadir; $tablefile = "$datadir/title-table"; $tt = new TitleTable(); # 全てのスレッドに対するメイン処理 foreach $file (glob "$datadir/*.dat") { $file =~ s|$datadir/||; $file =~ s|\.dat$||; next unless ((defined $$tt{type}{$file}) && ($$tt{type}{$file} eq "thread")); print "$file<>$$tt{title}{$file}\n"; # キャッシュ読み込み my @buf = (); local %newid = (); open IN, "$datadir/$file.dat" or die; foreach () { next if /^0+<>/; $_ = new Record($_); next if (keys %{$_} <= 2); if ($$_{name} && $newid{$$_{name}}) { $$_{name} = $newid{$$_{name}}; } if ($$_{body}) { $$_{body} =~ s|(>>)([0-9A-Za-z]+)|$1.newid($2)|eg; $$_{body} =~ s|\[\[([0-9A-Za-z]+)\]\]|"[[".newtitle($1)."]]"|eg; } $_->utf8(); my ($id, $str) = $_->newid(); $newid{substr $$_{id}, 0, 8} = substr $id, 0, 8; push @buf, $str; } close IN; # 新形式に書き込み my $newtitle = new Jcode($$tt{title}{$file})->utf8; my $newfile = file_encode("thread", $newtitle); my @oldbuf = (); if (open IN, "$datadir/$newfile.dat") { @oldbuf = ; close IN; } @buf = sort(@oldbuf, @buf); Shingetsu::Util::lock(); open OUT, "> $datadir/$newfile.dat" or die; my $prev = ""; foreach (@buf) { if ($_ ne $prev) { print OUT; $prev = $_; } } close OUT; Shingetsu::Util::unlock(); } Shingetsu::CacheStat::update(); #----------------------------------------------------------------# # 旧ファイル名→タイトルの変換テーブル package TitleTable; # # コンストラクタ # sub new($) { my($this) = @_; local $_; my $datadir = $main::datadir; # 変換テーブルのキャッシュ読み込み my %type = (); my %title = (); if (open IN, $main::tablefile) { while () { chomp; @_ = split /<>/; $type{$_[0]} = $_[1]; $title{$_[0]} = $_[2]; } close IN; } # メニューからタイトル情報を取得 if (open IN, "$datadir/menu.dat") { while () { chomp; @_ = split /<>/; if ((@_ >= 4) && ($_[2] ne "")) { $type{$_[2]} = "list"; $title{$_[2]} = $_[3]; } } close IN; } # 板からファイル情報を取得 my $file; foreach $file (keys %title) { next if ($type{$file} ne "list"); if (open IN, "$datadir/$file.dat") { while () { chomp; @_ = split /<>/; next if ((@_ < 4) || ($_[0] == 0)); $type{$_[2]} = "thread"; $title{$_[2]} = $_[3]; } close IN; } } # 漏れのあるファイルを調べる foreach $file (glob "$datadir/*.dat") { $file =~ s|$datadir/||; $file =~ s|\.dat$||; next if (($file =~ /_/) || ($file eq "menu") || $type{$file}); next unless (open IN, "$datadir/$file.dat"); my @buf = ; close IN; next if (@buf == 0); if ($buf[0] =~ /^0+<>/) { @_ = split /<>/, $buf[0], -1; if ((@_ > 7) && grep(/type:list/, @_[7..$#_])) { $type{$file} = "list"; $title{$file} = $_[2]; } elsif ((@_ > 7) && grep(/type:(thread|web)/, @_[7..$#_])) { $type{$file} = "thread"; $title{$file} = $_[2]; } elsif (@_ == 3) { $type{$file} = "thread"; $title{$file} = $_[2]; } elsif (@_ == 4) { $type{$file} = "list"; $title{$file} = $_[2]; } else { die "$file: cache error"; } } else { die "$file: cache error"; } } return bless {type=>\%type, title=>\%title}; } # # デストラクタ # sub DESTROY { my($this) = @_; Shingetsu::Util::lock(); open OUT, "> $main::tablefile" or die; local $_; foreach (keys %{$$this{title}}) { print OUT "$_<>$$this{type}{$_}<>$$this{title}{$_}\n"; } close OUT; Shingetsu::Util::unlock(); } #----------------------------------------------------------------# # レコード package Record; # # コンストラクタ # sub new($$) { my($this, $input) = @_; chomp $input; @_ = split /<>/, $input; my %rec = (); local $_; my $i = 0; foreach ("stamp", "id", "name", "mail", "body", "suffix", "attach") { if ((defined $_[$i]) && ($_[$i] ne "")) { $rec{$_} = $_[$i]; } $i++; } return bless \%rec; } # # 文字コード変換 # sub utf8($) { my($this) = @_; local $_; foreach ("name", "mail", "body") { next unless ($$this{$_}); $$this{$_} = new Jcode($$this{$_})->utf8; } } # # IDを振り直す # sub newid($) { my($this) = @_; local $_; my $body = ""; foreach ("name", "mail", "body", "suffix", "attach") { if (defined $$this{$_}) { $body .= "<>$_:$$this{$_}" } } $body =~ s/^<>//; my $id = Shingetsu::Extern::md5digest($body); return ($id, "$$this{stamp}<>$id<>$body\n"); }