#!/usr/local/bin/perl5 #↑環境に応じて修正の事 #bbs data convert script 2004/11/9-10 abfuku # Akihiro Katoh氏(WebSite消失)製 TreeTypeBBSから # りゅういち氏(http://www.cj-c.com/)製 ChildTree掲示板(以下cbbs)へ # 文書データを変換移行するスクリプト。 # article.dat 及び tree.dat の存在するディレクトリに当cgiを配置。 # (拡張子は.cgiへ・Ascii転送・実行属性追加) # そして当cgiを一回実行(適当な端末からブラウザ表示)させれば、 # cbbs用データcbbs.datを同一ディレクトリに出力。あとはcbbs側に移動の事。 # 無保証・Noサポート・自己責任でどーぞ $olddat = "article.dat"; #変更していた場合はここも適時修正 $oldtree = "tree.dat"; #同上 $outdat = "cbbs.dat"; print "Content-type: text/html\n\n"; print "\n"; print ''; print "\nconvert result\n\n"; print "$olddat & $oldtree -> 変換開始
\n"; open (FP,"<$olddat"); #旧文書情報は最初に一括読み込み while(){ chop; ($num,$renum,$time,$email,$hp,$name,$title,$comment,$r_h,$cou) = split(/<>/); $hashart{$num} = $_; #$hashart{} はGlobal利用 $maxnum = $num if($num > $maxnum); #最終文書 } close(FP); open(OFP,">$outdat"); #OFPはGlobal利用 print OFP "$maxnum<><><><><><><><><>$maxnum<><><><><>\n"; print "最終文書番号:$maxnum
\n
\n"; #以下 Tree情報を基に Main Loop open(FP,"<$oldtree"); while(){ # $_=; chop $_; $OneLine=substr($_,1); #最初の1文字は省く #以下、1Tree分の処理 $TreeLevel=0; $RootNo=int($OneLine); print "【Tree:$RootNo 処理開始】
\n"; $ResCnt=-1; while ($OneLine ne ""){ #文字がなくなるまで続ける $Temp=substr($OneLine,0,1); #1文字調査 if ($Temp eq "("){ $TreeLevel += 1; #「(」なら階層を上げる $OneLine=substr($OneLine,1); #1文字処理済み } elsif ($Temp eq ")"){ $TreeLevel -= 1; #「)」なら階層を下げる $OneLine=substr($OneLine,1); #1文字処理済み } else{ #カッコでない場合はレス番号一つ分処理 $ResCnt+=1; $TreeInfoNO{$ResCnt}=int($OneLine); $TreeInfoLV{$ResCnt}=$TreeLevel; while (substr($OneLine,0,1) =~ /[0-9]/){ #数字を捨てる $OneLine=substr($OneLine,1); #数字1文字をSkip } } } #1行分の情報収集終了、以下降順に出力 for($i=$ResCnt;$i>=0;$i=$i-1){ &conv1mes($RootNo,$TreeInfoNO{$i},$TreeInfoLV{$i}); } } close(FP); close(OFP); print "
\n変換終了 -> $outdat
\n"; print "\n"; #終了 sub conv1mes{ local($RootNo,$MesNo,$LV) = @_; #引数:$RootNo=Target文書のTreeRoot、$MesNo=Target文書、$LV=その階層 #この情報を基にOFPへ1文書分を変換出力する #旧文書情報を入手 local($num,$renum,$time,$email,$hp,$name,$title,$comment,$r_h,$fix); ($num,$renum,$time,$email,$hp,$name,$title,$comment,$r_h,$fix) = split(/<>/,$hashart{$MesNo}); #パラメータ一部修正 if ($LV==0) {$RootNo=0;} #ルート文書の場合はルート指定は0 $LV=$LV * 15 ; #cbbsの仕様にて、階層は15の倍数で表現 if (substr($hp,0,7) eq "http://"){ $hp = substr($hp,7); #WebURLの http:// は省く } $r_h.="::1::||||:||||||::"; #IP以外のcbbs用個人情報カラム追加 $comment =~ s/\/\/go; #

へ #日付の文字表記変換 local($sec,$min,$hour,$mday,$mon,$year,$wday,$week,$date); ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime($time); $year=$year+1900; $mon++; if($mon < 10){$mon ="0$mon"; } if($mday < 10){$mday="0$mday";} if($hour < 10){$hour="0$hour";} if($min < 10){$min ="0$min"; } if($sec < 10){$sec ="0$sec"; } $week=('Sun','Mon','Tue','Wed','Thu','Fri','Sat') [$wday]; $date="$year\/$mon\/$mday\($week\) $hour\:$min\:$sec"; #cbbs形式で出力 print "NO:$MesNo Level:$LV RootNo:$RootNo Subject:$title
\n"; print OFP "$MesNo<>$date<>$name<>$email<>$title<>$comment<>$hp<>$LV<><>"; print OFP "$RootNo<><>$r_h<>$time<><>\n"; } #以下参考:両掲示板のデータフォーマット調査結果 # # 【CBBS】 cbbs.dat 1行1発言、パラメータは<>で区切る # 一行目のみ、最終発言番号情報 (要らないかも?) # n<><><><><><><><><>n<><><><><> # # 二行目以下 # 1.番号 # 2.投稿日(文字列表記) # 3.名前 # 4.メアド # 5.Subject # 6.本文 (改行は
)※
が大文字だとレス引用が正しく動作せず # 7.WebURL(http://は省略) # 8.ルートを0階層とみなし、階層数*15(2階層なら30・10階層なら150) # 9.Null (というか不明・以下同様) # 10.属するTreeのルート文書番号(ルート発言は0) # 11.削除キー(暗号化済み) # 12.IP+"::1::||||:||||||::" (追加値はcbbs特有の個人情報) # 13.投稿日(Unix日付型) # 14.Null # 15.Null (この後には区切り文字<>は付かない) # # Tree単位では新しい順。各Treeの中では、新しい枝の末端 #(見た目上はTree内で下の文書)から逆回帰的(?)に並ぶ。 # 常に枝先→親の順番となり、各Treeの中でRootが最後となる。 # ある行に対して、その後ろで階層値-15のものが親文書となる。 # ※同じTreeの文書群は常に一まとめ # # (例1) # 1−2-4 # └3 # ↓ # 3<>〜中略〜<>15<><>1〜後略〜 # 4<>〜中略〜<>30<><>1〜後略〜 # 2<>〜中略〜<>15<><>1〜後略〜 # 1<>〜中略〜<>0<><>0〜後略〜 # # (例2) # 1−2 # └3-4 # ↓ # 4<>〜中略〜<>30<><>1〜後略〜 # 3<>〜中略〜<>15<><>1〜後略〜 # 2<>〜中略〜<>15<><>1〜後略〜 # 1<>〜中略〜<>0<><>0〜後略〜 # # 【旧TreeBBS(Akihiro Katoh氏制作版)】 # article.dat 1行1発言、パラメータは<>で区切る # # 1.番号 # 2.直属の親文書番号(ルートの場合は0) # 3.投稿日(UNIX日付型) # 4.メアド # 5.WebURL(http://付き) # 6.名前 # 7.Subject # 8.本文 (改行は
)※こちらは
が大文字な点に注意 # 9.IP # 10.0 (用途不明) # # こちらのファイルはおおよそ作成順に並び、複数Treeの文書が様々に混在。 # 一応、上記の情報のみでTreeの構成は可能であるものの、検索性が悪く処理が # 重くなる事から、別途ツリー情報収納ファイルが存在。 # # tree.dat 1行1Tree。 # # 各番号は"("で区切り、同時に1階層下げる扱いとなる。 # 階層が上がる場合は")"追加。2階層以上上がる場合もその都度複数記述。 # ルートから回帰的に各枝へ進行、同一階層はカッコでくくられる形になる。 # (1Tree内の出現順はcbbsと逆になる) # # (例1) # 1−2-4 # └3 # ↓ # (1(2(4())3)) # # (例2) # 1−2 # └3-4 # ↓ # (1(2()3(4()))) #