MAN HIMAZINE INTERFACE-II

DARK SERVER

最近の独り言
  1. zetamatta: そこで RATE の設定ですよ
  2. zetamatta: あの記事以来、モッチーの評判は急降下やね
  3. zetamatta: オバマ対クリントン。いつまでやっとんねん
  4. zetamatta: JavaScript でトリプルクリックを拾う方法は無いじゃろか?
  5. zetamatta: 冷蔵庫の「動くん棚」の CM の CV は、もしかして…能登麻美子???
  6. zetamatta: Internal Server Error になったから投稿しなおしたら、かぶった。Twitter こんちくしょう
  7. zetamatta: プロンプトに「大儀である」と表示する嫌なサーバ
  8. zetamatta: プロンプトに「大儀である」とか言う、嫌なサーバ

(2008.05.11)

$ [wifky] 「最近更新されたセクション」プラグイン

えーと「プラグイン作ってみた」シリーズ第二弾。 別名「作ってみたら、意外と簡単でした。できへん言うてすみませんでした」 シリーズとも言うw

package wifky::recentsec;

# use strict; use warnings;

$::inline_plugin{recentsec} = sub{
    my (undef,$number)=@_;
    my @entry;
    foreach my $p ( &::ls_core( { t=>1 , r=>1 , number=>($number||3)} ) ){
        my $text=&::read_object($p->{title});
        my @outline;
        foreach( split(/\r?\n\r?\n/,$text) ){
            if( /\A\s*\<\<([^<].*?)\>\>\s*\Z/s || /\A\s*\!\!\!([^\!].*)\Z/s ){
                my $midashi = &::preprocess($1);
                $midashi =~ s/\<[^\>]*\>//g;
                push( @outline ,
                      &::anchor( $midashi , 
                          { p=>$p->{title} },
                          {},
                          "#p".(2+$#outline) 
                      )
                );
            }
        }
        push(@entry,
            &::anchor($p->{title} ,
                      { p=>$p->{title} }). &mklist( \@outline ,
                      'recentsec1')
        );
    }
    &mklist( \@entry , 'recentsec' );
};

sub mklist{
    my ($entry,$class)=@_;
    if( @{$entry} ){
        qq'<ul class="$class"><li>'.join('</li><li>',@{$entry}).'</li></ul>';
    }else{
        '';
    }
}

recentsec.pl で保存して、プラグインマネージャで、うp。 ページのどこかで「((recentsec ページ数))」(省略時は3ページ)とする。 表示の例は、うちのサイドバーをご覧のこと。 (そのうち外すかもしれんけど)

  • ソースを見てのとおり、最近更新されたページのソースの解析をしなおしているので、 サーバに優しい作りではない。
    • とは言え「段落ごとに文法を解釈するという作り」のおかげで、 「本文表示」の時に通す解析ロジックの数の 10分の1くらいしか 所要コストがかかっていないはず。
  • wifky.sourceforge.jp で正式に公開しないのは、仕様にまだ検討の余地があるため。

$ 今週の篤姫

「どうして、将軍生母が御台所より下座なのじゃ?」 (いえさだ調)

八代将軍 吉宗の時は:

 先代将軍(大御所)の側室(の筆頭) >>>> 現将軍の御台所

というシーンがあったような記憶が。中期と幕末で風習が変わったのか? それに現将軍の側室も、廊下の角で平伏しなきゃならんほど身分が低いようにも思えん。

教えて、偉い人!(エロい人でも構わんよ)


ところで、徳川家定公は結構いいキャラしてると思うのは、ワシだけであらふか?

$ [wifky] 管理者モードで画面をダブルクリックすると、即編集モードになるプラグイン

もう、ノリノリだぜ! 「時を止めるプラグイン」でも書けそうな勢いだ。

package wifky::dblclick;

# use strict; use warnings;

if( defined &::is_signed && &::is_signed() ){
    (*::print_page , *wifky::dblclick::orig_print_page ) =
        (*wifky::dblclick::new_print_page,*::print_page );
}

sub new_print_page{
    my %arg=@_;
    my $url = &::myurl( { p=>$arg{title} , a=>'edt' } );
    $url =~ s/'/\\'/g;
    &::putenc(q|<div ondblclick="JavaScript:window.location.href='%s'">|,$url);
    &wifky::dblclick::orig_print_page;
    &::puts('</div><!-- dblclick -->');
}

サイドバーとかヘッダを編集したい時、画面遷移が面倒だなぁとか思うわけだが、 これを入れれば、編集したい付近をダブルクリックするだけ! (ただし、プレビュー時にうっかりクリックすると、 編集中のドラフトを廃棄してしまう罠)

ところで本機能は、実は標準機能として入れるべきかなぁとか思ってる。 上のコード、大半は関数を横取りする処理なので、 wifky.pl 本体に組み込めば、たかだか 2〜3行のみの追加で終わるんじゃよ。

- さっそくバグが出たので、修正

package wifky::dblclick;

# use strict; use warnings;

if( defined &::is_signed && &::is_signed() ){
    (*::print_page , *wifky::dblclick::orig_print_page ) =
        (*wifky::dblclick::new_print_page,*::print_page );
}

sub new_print_page{
    my %arg=@_;
    my $url = &::myurl( { p=>$arg{title} , a=>'edt' } );
    $url =~ s/'/\\'/g;
    &::putenc(q|<div ondblclick="JavaScript:window.location.href='%s'">|,$url);
    my $result=&wifky::dblclick::orig_print_page;
    &::puts('</div><!-- dblclick -->');
    $result;
}

ページが存在しない時、print_page() 関数が 0 を戻すという仕様を すっかり忘れておったわい、てへ。 (それでデフォルトヘッダファイルを表示するロジックが動いちゃった)

$ ただ今、ServicePack 3 をインストール中なんですが

それに先だって、ライセンス確認ツールを導入させられたんだが:

Windows Genuine Advantage 確認ツール (KB892130) をダウンロード中 (更新プログラム 1 個中 1 個)... 完了しました。
インストールの開始中... 完了しました。
Windows Genuine Advantage 確認ツール (KB892130) をインストール中 (更新プログラム 1 個中 1 個)... 

一瞬、なんじゃこりゃと。 「開始」が完了しましたって、どんだけ、フェイズを細分化してるねん。

Comment

amano さっそく自分の所にも設置してみました。ありがとうございます。 (2008/05/11 23:12:32)

iyahaya 遅くなりまして恐縮です。まだ正式版ではないので、何か要調整箇所がありましたら、なんなりと (2008/05/11 23:17:02)

(2008.05.10)

$ [wifky] Wiki の URL を短くする試み

を読んで、wifky も URL をもうちょっと短くできないかなーと思い始めた。 で、punycode にまず興味をもった。

  • Python だと、標準装備の "〜".encode("punycode") だけで出来るみたい *1
    • さすが「バッテリ入ってます」の Python だぜ。
  • Perlでは、IDNA::Punycodeや Encode::Punycode というライブラリがあるらしい
    • IDNA::Punycode の 0.03 はバグがあって、先頭に余分な - がついてしまうらしい *2

wifky は性質上あまりホイホイとライブラリを使えないので、 自前で組んでしまおうかとアルゴリズムの方を調べたが、 日本語で説明されたものはないらしい。 英語の RFC を「見た」けれども、結構本気のアルゴリズムっぽくて、 PurePerl で組むと結構な処理コストがかかりそうな雰囲気がムンムンとしていた (注意:内容をほとんど読まず、行数だけで判断している)。

で、そこまで時間かけるなら、改造uuencode で胡麻化してもいいんちゃうかと 思ったのが、これ。 以前、fancyurl.plg という、wifky の URL を静的URL風にしてくれるプラグインを 作ったのだけれども、それを改造してページ名部分を短かくするようにしてみたわけだ。

package wifky::fancyurl;

# use strict;use warnings;

$::version ge '1.2' or die('!fancyurl.plg requires wifky 1.2 or later!');

if( defined $ENV{PATH_INFO} ){
    my (undef,$p,$f)=split(/\//,$ENV{PATH_INFO});
    if( defined $p ){
	$p =~ s/\.html$//;
	$::form{p}=&decode($p);
    }
    if( defined $f ){
	$f =~ s/\.\w\w\w$//;
	$::form{f}=&decode($f);
    }
}
(*wifky::fancyurl::org_myurl ,*::myurl)=(*::myurl,*wifky::fancyurl::new_myurl);

sub new_myurl{
    my ($cgiparam,$sharp)=@_;
    local $::me=$ENV{SCRIPT_NAME};
    if( defined(my $p=delete $cgiparam->{p}) ){
        $::me .= '/' . &encode($p) ;
        if( defined(my $f=delete $cgiparam->{f}) ){
            $::me .= '/' . &encode($f) ;
            if( $f =~ /\.(jpg|png|gif)$/ ){
                $::me .= $&;
            }
        }else{
            $::me .= '.html';
        }
    }
    &wifky::fancyurl::org_myurl($cgiparam,$sharp);
}

sub encode{
    my $text=pack('u*',shift);
    $text =~ tr|`!"#\$%&'()*+,./:;<=>?@\[\\\]^|abcdefghijklmnopqrstuvwxyz|;
    $text =~ s/[^-_0-9a-zA-Z]//g;
    $text;
}
sub decode{
    my $text=shift;
    $text =~ tr|abcdefghijklmnopqrstuvwxyz|`!"#\$%&'()*+,./:;<=>?@\[\\\]^|;
    unpack('u*',$text);
}

uuencode だと、URL に使えない記号が登場するんだけれども、 それらは tr で uuencode で通常使っていない英小文字に置換する。 これぞ base64 でも uuencode でも punycode でもない、 オレオレエンコーディング。 メリットはどの Perl 環境でも動っていうことだけ。 真似するなよ!

さて、これで URL の長さを比較してみた!

素の URL (URLに使えない文字(1バイト)を %nn で表記)
http://127.0.0.1:8001/cgi-bin/wifky.pl?p=%282008.05.11%29+%BB%E4%C5%AA%CF%BF%B2%BB%CF%BF%B2%E8%CA%E4%BD%FE%B6%E2%C0%A9%C5%D9
URL圧縮サービス (punycode ベース)
http://swiki.jp/-/127.0.0.1:8001/cgi-bin/wifky.pl?p=(2008.05.11)+-j022fv4uus5mxxuk17nalp4bkq1nl74dyeqaa9961e
オレオレエンコーディング方式 (uuencode ベース)
http://127.0.0.1:8001/cgi-bin/wifky.pl/CkdiPmdvNmd4Nm3eIilODQpKoOwkwSwzRZmKDOuZVXLcIQsDa.html

わずかに勝っているかのように見えるけど、それは URL圧縮サービスにはプリフィックスの swiki.jp/-/ がついているから。 実際のページ名部分は URL圧縮サービスの方が縮んでいる。

事実上 punycode が勝っている理由は

  • URL使用可能文字は、そのまま URL に乗せている
  • 単純にビットを再配置する(8bit×3オクテット分→6bit×4文字)ではなく、 真面目な圧縮処理を入れている(どんなんかは知らん!)

からでしょうね。

結論として、 punycode変換を標準で搭載している Python や、 ライブラリを自由に導入してもよい環境では、 URL を短くするために punycode を使うべきといったところでしょう。