PyukiWikiでBugTrackが動作するようにbugtrack.inc.plを修正する

PyukiWikiでBugTrack

PyukiWikiでBugTrack(バグ追跡システム)を動かす.

連鎖ゲームのバグ&要望管理を一元化したいと思って,導入した.

PyukiWikiには標準で bugtrack.inc.pl が付属しており,#bugtrack は簡単に使える. しかし #bugtrack_list は使えないので,一覧を表示できないという片手落ち状態だった.

そこで,#bugtrack_list を使えるように試行錯誤してみた.

ちなみに結果はこれ.
RensaWiki BugTrack


bugtrack_list.inc.pl

#bugtrack_list の実行時に呼び出されるモジュール.このファイルは新規作成する. しかし処理の実体は,bugtrack.inc.plに記述するのでした.

bugtrack_list.inc.pl

require $::plugin_dir . 'bugtrack.inc.pl';

1;

bugtrack.inc.pl

以下の3個の関数を編集した.

  • sub plugin_bugtrack_pageinfo: 変更
  • sub plugin_bugtrack_list_convert: 変更
  • sub sortfunc: 新規追加

変更とはいうものの,もともとのソースではPHPのコードが記述されていたので,コンパイルすら通らない状態だった. それをPerlに移植したという作業イメージである.

plugin_bugtrack_pageinfo

sub plugin_bugtrack_pageinfo
{
    my ($page, $no) = @_;

    if (@_ == 1) {
        if ($page =~ /\/([0-9]+)$/) {
            $no = $1;
        } else {
            $no = 0;
        }
    }

    $source = $::database{$page};

    if ($source[0] =~ /move\s*to\s*($WikiName|$InterWikiName|\[\[$BracketName\]\])/) {
        return plugin_bugtrack_pageinfo(&::unarmor_name($1), $no);
    }

    $body = join("\n",$source);
    $summary = $name = $priority = $state = $category = 'test';

    @itemlist = ($bugtrack::summary,$bugtrack::name,$bugtrack::priority,
        $bugtrack::state,$bugtrack::category);

    foreach $itemname (@itemlist) {
        if ($body =~ /-\s*$itemname\s*:\s*(.*)\s*/) {
            if ($itemname eq $bugtrack::name) {
                $name = &htmlspecialchars(&::unarmor_name($1));

            } elsif ($itemname eq $bugtrack::summary) {
                $summary = &htmlspecialchars($1);

            } elsif ($itemname eq $bugtrack::priority) {
                $priority = &htmlspecialchars($1);

            } elsif ($itemname eq $bugtrack::state) {
                $state = &htmlspecialchars($1);

            } elsif ($itemname eq $bugtrack::category) {
                $category = &htmlspecialchars($1);
            }
        }
    }

    if ($body =~ /\*([^\n]+)/) {
        $summary = $1;
#       make_heading($summary);
    }

    return join('<>',($page, $no, $summary, $name, $priority, $state, $category));
}

plugin_bugtrack_list_convert

sub plugin_bugtrack_list_convert
{
    $page = $::form{mypage};

# 2004.12.12 エラーが出るので無効化
# Undefined subroutine &main::func_num_args
# そのため,#bugtrack の第1引数(ページ名)は,必ずそのページ自身の
# 名前にする必要があると思う
#
#   if (func_num_args()) {
#       list($_page) = func_get_args();
#       $_page = get_fullname(&::unarmor_name($_page),$page);
#       if ($::database{$_page}) {
#           $page = $_page;
#       }
#   }

    @data = ();
    $pattern = "$page/";

    foreach my $page (sort keys %::database) {
        if (index($page,$pattern) == 0 && substr($page,$pattern_len) =~ /[1-9][0-9]*/) {
            my($line) = &plugin_bugtrack_pageinfo($page);
            push(@data,$line);
        }
    }

    @table = ();
    for ($i = 0; $i < @bugtrack::state_list; $i++) {
        $table[$i] = '';
    }
    foreach $line (@data) {
        ($page, $no, $summary, $name, $priority, $state, $category) = split(/<>/, $line);
        $page_link = make_link($page);

        $state_no = $#bugtrack::state_list;
        for ($i = 0; $i <= $#bugtrack::state_sort; $i++) {
            if ($bugtrack::state_sort[$i] eq $state) {
                $state_no = $i;
            }
        }

        $bgcolor = $bugtrack::state_bgcolor[$state_no];
        $row = <<"EOD";
 <tr>
  <td style="background-color:$bgcolor">$page_link</td>
  <td style="background-color:$bgcolor">$state</td>
  <td style="background-color:$bgcolor">$priority</td>
  <td style="background-color:$bgcolor">$category</td>
  <td style="background-color:$bgcolor">$name</td>
  <td style="background-color:$bgcolor">$summary</td>
 </tr>
EOD
        $table[$state_no] .= "$no<>$row\n\n";
    }

    $table_html = <<"EOD";
 <tr>
  <th>&nbsp;</th>
  <th>$bugtrack::state</th>
  <th>$bugtrack::priority</th>
  <th>$bugtrack::category</th>
  <th>$bugtrack::name</th>
  <th>$bugtrack::summary</th>
 </tr>
EOD

    for ($i = 0; $i <= $#bugtrack::state_list; $i++) {
        my(%rowlist) = {};
        foreach $tab (split(/\n\n/, $table[$i])) {
            my($no, $row) = split(/<>/, $tab);
            $rowlist{$no} = $row;
        }
        my(@newkeys) = sort sortfunc keys(%rowlist);
        foreach $newkey (@newkeys) {
            $table_html .= "$rowlist{$newkey}\n";
        }
    }

    return "<table border=\"1\">\n$table_html</table>";
}

sub sortfunc

sub sortfunc
{$b <=> $a}

カスタマイズ

sub sortfuncは,同一ステータスの投稿を番号でソートするときのソートアルゴリズムの実装である.

今回は私の好みで数値の降順ソート(大きい番号を上とする)を行っているが, 昇順{$a <=> $b}にするのもありだと思う.

また,bugtrack_list.inc.plの上の方にある,

@bugtrack::state_sort = ...
@bugtrack::state_bgcolor = ...
の順番を並べ替えてみるのも,興味深い. ちなみに私の場合は,
@bugtrack::state_sort = ('CVS待ち','着手','保留','提案','完了','却下');
@bugtrack::state_bgcolor = ('#ccccff','#ffcc99','#ccddcc','#ccffcc','#cccccc','#ffccff','#ff3333');
という風に提案と完了を入れ替えて,完了を下に下げるようにした.

Wikiページの作成

例えばこんな具合でBugTrack投稿ページを記述する.

BugTrack

** バグ,新機能への要望

*** バグ,要望の一覧

#bugtrack_list

この一覧に上がっている全てのバグ,要望に,作者が対応するという保証はありません.

----
*** 登録 (作者専用)

連鎖ゲーム掲示板に投稿された内容を元に,作者(かも)がここに登録します.

#bugtrack(BugTrack,連鎖ゲームバグ,連鎖ゲーム欲しい新機能,連鎖シミュレータバグ,連鎖シミュレータ欲しい新機能,その他)
#bugtrackの第1引数
#bugtrackの第1引数はBugTrackページ名の頭に付けられる文字列だが,必ずこのページ自体の名前と同じにすること. (正確には,#bugtrack_list を記述しているページの名前と同じにすること)

そうでないと一覧生成のために投稿を検索する動作がおかしくなる. sub plugin_bugtrack_list_convert の冒頭に書いてあるコメント参照のこと.

これは,今回の作業がうまくいかなかった故の制約です.

#bugtrackの第2引数以降
第2引数以降は,カテゴリーの選択肢として使用される.


その後

これでしばらく運用していたが,荒らし投稿がはびこるようになった...

PyukiWikiのBugTrackでパスワードをかけるへ続く

kamolandをフォローしましょう


© 2017 KMIソフトウェア