i-mode用にページをコンバートする(2)


i-modeはパケット課金である。
従って余計なタグやリターンコードは取り除いてやった方が親切と言うモンだ。
と言う話はここで書いたとおりなので、今回はサイズの巨大な雑記のバックナンバーを分割送信する方法を紹介しよう。
毎日の雑記はスクリプトによって自動連結され、一つの大きなファイルとして保存されている。
だいたい1ヶ月分の雑記の容量は100Kバイトを少し越える程度。
これを一日ごとに分割して端末に送り出そうというわけだ。
いや、最初は一日ごとのファイルを沢山作って..とも考えたが、それをやるのもcgiを書くのも似たようなものなのでcgi方式にする事にした。
まずはソースを見ていただこう。
#!/usr/bin/perl
#
$DEBUG=0;
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$reload = 'http://www.cds.co.jp/ff/imode.cgi';
read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
@pairs = split(/&/,$buffer);
foreach $pair (@pairs) { ($name,$value) = split(/=/,$pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$value =~ s/\&/&/g;
$value =~ s/\"/"/g;
$value =~ s/</&lt;/g;
$value =~ s/>/&gt;/g;
$value =~ s/\t//g;
$value =~ s/\r\n/\r/g;
$value =~ s/\n/\r/g;
if ($name eq 'target') { push(@RM,$value); }
else { $FORM{$name} = $value; }
}
$TUKI = $FORM{'tuki'};
$FNEN = $year - 100 ;
$FMON = $mon + 1 ;
$FDAY = $mday + 0 ;
$BNEN = $FNEN - 1;
$BMON = $BMON - 1;
if ($TUKI ne $FMON){
if ($TUKI eq 12){
$BMON = 12 ;
$FNEN = 0 ;
}
}
#if ($FMON < 10){$FMON = "0$FMON";}
if ($PAGE eq ""){$PAGE = 1; }
if ($DISP eq ""){$DISP = 1; }
if ($TUKI eq ""){$TUKI = $FMON; }
$FTUKI = $TUKI;
if ($TUKI < 10 ){$FTUKI = "0$TUKI";}
$FNAME = "i0$FNEN$FTUKI.htm";
open(READ,"/home/www/docs/ff/$FNAME");
while (<READ>) {
$TEXT = $_;
$SW0=0;
$SW2=0;
$COUNT="$COUNT$TEXT";
if ($TEXT =~ /<HR WIDTH=\"100%\">/) {
$SW0=1;
if ((($FDAY - $PAGE) eq 0) && ($TUKI eq $FMON)){
$TUKI = $TUKI -1 ;
$SW0=2;
if ($TUKI eq 0){ $TUKI = 12; }
$PAGE = 0 ;
$FORM{'back'} = 0 ;
&next;
}
if ( $ENV{'REQUEST_METHOD'} eq "POST" ){
$SW0=3;<BR> $PAGE = $FORM{'back'} + 1;
if ((($FDAY - $PAGE) eq 0) && ($TUKI eq $FMON)){
$SW0=4;<BR> $TUKI = $TUKI -1 ;
$PAGE = 0;<BR> $FORM{'back'} = 0;
}
} else { &next; }
if ($PAGE eq $DISP) { &next; $SW0=5;}
$DISP = $DISP + 1;
}
$COUNT = "";
}
&next;
exit;
sub next {
close(READ);
if ($COUNT eq "" || $PAGE eq 0){$COUNT = "\前月分に行きます"; }
if ($DEBUG){$len = length($COUNT)+262;}else{$len = length($COUNT)+162;}
print "Content-type text/html\n";
print "Content-length $len\n";
print "\n";
print $COUNT;
print "<form method=POST action=\"$reload\">\n";
print "<input type=hidden name=\"tuki\" value=$TUKI>\n";
print "<input type=submit name=\"back\" value=$PAGE次のページ>\n";
print "</FORM>\n";
if ($DEBUG){
print "page=$PAGE<BR>";
print "disp=$DISP<BR>";
print "tuki=$TUKI<BR>";
print "file=$FNAME<BR>";
print "day =$FDAY<BR>";
print "ftuki=$FTUKI<BR>";
print "fmon=$FMON<BR>";
print "sw0=$SW0<BR>";
}
print "</BODY>";
print "</HTML>";
exit;<BR> }
寄せ集めなので悪しからず。
(笑)実際にリターンを入れる部分はこれ#!/usr/bin/perl
while (<STDIN>) {
$_ =~ s/<HR WIDTH=\"100%\">/<HR WIDTH=\"100%\">\n/g;
print;
}
毎回リアルタイムにデータを作り直さないのは、巨大データ処理にかかる時間とCPUパワーを節約するためである。
後は区切れ目にリターンコードが入っているので、そこまでを送り出すようにすればいい。
実はこれ、その月内の一つのファイルのみを送り出そうと作ったもので、後から前月分まで遡れるようにしたので処理が汚くなっている。
この前月分までサポートするというのが結構たいへんな作業なのだ。
元々F&Fの雑記やバックナンバは、そのファイル名が日付で出来ているので上記のようなcgiになった。
なので、これをこのまま移植して動くケースなどほとんど無いだろう。
理屈としては、リターンコードの入っているところまでを送り出すと言うところと、日付とページ数を比較して前月分にファイルを交換する所、送り出すデータの長さを予め送出する(
モードでは必須)部分があれば良い。