2008/11/30

掲示板の移行2

昨日の続き。さて、今までのデータをどうしようかと思い、一旦は移行することをあきらめたのだが、データフォーマットを見ると、まぁそれほど難しくはない。KYviewもそれほどでもなさそうなので変換することにした。
PHPで作成。コンソール用
たまにしかプログラムを作らないのでケアレスミスの連発。PHPとPerlの構文もごっちゃになってリファレンスマニュアルを見ながらの作成した。なかなか思うように作れなかったが、ようやく希望通りの動作になった。
kyv2forum.php
<?php
  $tagdir = '.';
  $output = 'data.txt';

  # ディレクトリ内の .dat ファイルを確認
  if ($dh = opendir($tagdir)) {
    $i = 0;
    while ($file = readdir($dh)) {
      if (preg_match ('/\.dat$/', $file)) {
        $kyvfile[$i++] = $file;
      }
    }
    closedir($dh);
  } else {
    print "directory open error\n";
    return;
  }

  $countall = 0;
  $topall = 0;

  # .dat ファイルを全て読み込む
  foreach ($kyvfile as $filename) {
    if (!($fh = fopen ($filename, 'r'))) {
      print "open file error {$filename}\n";
      return;
    }
    print "converting ... {$filename}\n";

    $rline = 1;
    $cnum = 0;
    $linenumber = 1;
    while (!feof($fh)) {
      $buf = trim (fgets ($fh, 4096));
      if ($rline == 1) {
        $subject = $buf;
      } elseif ($rline == 2) {
        $date = $buf;
      } elseif ($rline == 3) {
        $postname = $buf;
      } elseif ($rline == 4) {
        ereg ("^IP:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)", $buf, $ipaddress);
      } elseif ($rline == 6) {
        $url = $buf;
      } elseif ($rline == 7) {
        $article = $buf;
      } elseif ($rline == 15) {
        if ($cnum == 0) $keydate = $date;
        $postdata[$keydate][$cnum]["subject"] = $subject;
        $postdata[$keydate][$cnum]["postdate"] = $date;
        $postdata[$keydate][$cnum]["postname"] = $postname;
        $postdata[$keydate][$cnum]["ipaddress"] = $ipaddress[1];
        $postdata[$keydate][$cnum]["url"] = $url;
        $postdata[$keydate][$cnum]["article"] = $article;

        ereg ("^", $buf, $poststatus);
        if (feof($fh) || !strcmp ($poststatus[1], "NOTE")) {
          $postdata[$keydate][0]["commentnum"] = $cnum;
          $postdata[$keydate][0]["latestdate"] = $date;
          if ($cnum) {
            $postdata[$keydate][0]["latestname"] = $postname;
            $cnum = 0;
          }
          $topall++;
        } elseif (!strcmp ($poststatus[1], "APPEND")) {
          $cnum++;
        } else {
          print "kyv file is broken {$filename} ({$linenumber}) {$poststatus[1]}: {$buf}\n";
          return;
        }
        unset ($subject);
        unset ($date);
        unset ($postname);
        unset ($ipaddress);
        unset ($url);
        unset ($article);
        unset ($poststatus);
        $rline = 0;
        $countall++;
      }
      $rline++;
      $linenumber++;
    }
    fclose ($fh);
  }

  # 全てのデータを日付順にソート
  krsort ($postdata, SORT_NUMERIC);
  $p_year = 0;
  foreach ($postdata as $keydate => $current) {
    $dform = localtime ($current[0]["postdate"], true);
    $postdata[$keydate][0]["w_year"] = $dform["tm_year"] + 1900;
    $postdata[$keydate][0]["w_month"] = $dform["tm_mon"] + 1;
    if ($p_year != $dform["tm_year"] || $p_month != $dform["tm_mon"]) {
      $postdata[$keydate]["mflag"] = "nor";
      if (isset($p_key) && !isset ($postdata[$p_key][0]["mflag"])) $postdata[$p_key][0]["mflag"] = "nol";
      $p_year = $dform["tm_year"];
      $p_month = $dform["tm_mon"];
    }
    $p_key = $keydate;
  }
  print "completed sorting and dating\n";

  # 新しいデータフォーマットにして書き込み
  $tnum = $topall;
  $anum = $countall;
  $fh = fopen ($output, "w");
  fwrite ($fh, "{$countall}<>0<>{$topall}<><><>\n");
  foreach ($postdata as $keydate => $current) {
    ksort ($current, SORT_NUMERIC);
    $num = $anum - $current[0]["commentnum"];
    for ($cnum = 0; $cnum <= $current[0]["commentnum"]; $cnum++) {
      $top = $cnum ? '' : 'm';
      $cdate = $current[$cnum]["postdate"];
      $cname = $current[$cnum]["postname"];
      $url = $current[$cnum]["url"];
      $subject = $current[$cnum]["subject"];
      $article = $current[$cnum]["article"];
      $ipaddress = $current[$cnum]["ipaddress"];
      $comments = $cnum ? '' : $current[0]["commentnum"];
      $latestname = $cnum || !isset($current[0]["latestname"]) ? '' : $current[0]["latestname"];
      $latestdate = $cnum || !isset($current[0]["latestdate"]) ? '' : $current[0]["latestdate"];
      $w_year = $current[0]["w_year"];
      $w_month = $current[0]["w_month"];
      $mflag = isset($current[0]["mflag"]) ? $current[0]["mflag"] : '';

      $linedata = "{$num}<>{$top}<>{$tnum}<>{$cdate}<>{$cname}<><>{$url}<><>{$subject}<>{$article}<>{$ipaddress}<><>{$comments}<>{$latestname}<>{$latestdate}<><><><><><><><>{$w_year}<>{$w_month}<>{$mflag}<>\n";
      fwrite ($fh, $linedata);
      $anum--;
      $num++;
    }
    $tnum--;
  }
  fclose ($fh);

?>

動くものだからとりあえずバックアップ代わりに掲載しておく。

0 件のコメント:

色々な画像ファイル形式をhtmlに埋め込む(PHP)

画像をhtmlに埋め込む際、単一の場合は img/src、複数の拡張子を指定すると img/source/srcsetに展開してくれる便利関数。また、単一拡張子のみが指定されている場合は、ブラウザのサポート状況に応じ、avifやwebpの拡張子を持つ同名のファイルがある場合は[a...