Perlの最近のブログ記事

某会員管理システム(うちで作ったものではない)の話。

金融機関からのデータとの連係を始めたところ、更新画面でカナ氏名やカナ住所がエラーチェックに引っかかってしまってデータの更新が出来ないとのこと。

どうも、金融機関のデータというのが、ホストマシン上の半角カナデータを単純に全角に変換しただけで、例えば「ダ」が「タ」+「゛」、「ポ」が「ホ」+「゜」で送られてきている。で、この「゛」や「゜」が「全角カタカナではない」と判断されてエラーになっているようだ。

ソースを見てみると、

if ($kana_name !~ /^(([\xA3][\xB0-\xB9])|([\xA5][\xA1-\xF6])|([\xA3][\xC1-\xDA])|([\xA3][\xE1-\xFA])|([\xA1][\xA1])|([\xA1][\xA6])|([\xA1][\xBC])|([\xA1][\xDD]))*$/) {
 &error_proc('全角カナ以外の文字有り'); # エラー処理へ
}

ってなってる。

EUC コードで、

[\xA3][\xB0-\xB9] 1~9
[\xA5][\xA1-\xF6] ァアィイ~ヵヶ
[\xA3][\xC1-\xDA] A~Z
[\xA3][\xE1-\xFA] a~z
[\xA1][\xA1] <全角スペース>
[\xA1][\xA6] ・(中点)
[\xA1][\xBC] ー(長音符号(音びき符号))
[\xA1][\xDD] -(マイナス(ハイフン))

なので、これに、

[\xA1][\xAB-\xAC] ゛(濁音)、゜(半濁音)

を追加する必要があるね。

if ($kana_name !~ /^(([\xA3][\xB0-\xB9])|([\xA5][\xA1-\xF6])|([\xA3][\xC1-\xDA])|([\xA3][\xE1-\xFA])|([\xA1][\xA1])|([\xA1][\xA6])|([\xA1][\xBC])|([\xA1][\xDD])|([\xA1][\xAB-\xAC]))*$/) {
 &error_proc('全角カナ以外の文字有り'); # エラー処理へ
}

にすればOKだ。

まあ、会員情報をカナで検索することを考えると、登録時に「タ゛」は「ダ」に、「ホ゜」は「ポ」に変換してしまった方がきれいだと思うが・・・

メール解析のプログラムを作成してて気づいたのだが、SoftBank の携帯(テストで使ってたのは、俺の 810T だが)のメールヘッダって、Content-Type ヘッダの後ろに空白を入れないんだな。

例えば、PC のメールソフト(Outlook とか EDMax とか AL-Mail とか諸々)だと、Content-Type ヘッダは、

Content-Type: multipart/mixed;

こんな感じで、'Content-Type:' の後ろに半角スペースがひとつ入ってる。
でも、810T のメールは、

Content-Type:multipart/mixed;

なんだよ。
他にも、コンテンツの属性を示すヘッダ関係は軒並み、

Content-Type:text/plain;charset=ISO-2022-JP
Content-Disposition:attachment;filename="HOGEHOGE.JPG"
Content-Transfer-Encoding:base64

みたいな感じで全て半角スペースは含まれてない。

他のヘッダ(To とか From とか Subject とか)は、全て半角スペースが含まれているのに・・・である。

変な実装。(^^;
いや、RFC にどう書かれているのかわからないが、半角スペースが無いなら無いで全然かまわんのやけど、他のヘッダと、Content 関係だけがフォーマットに違いがあるのが何か気持ち悪いよなあ。

PC から出したメールに添付した画像は抜き出せるのに、携帯メールに添付した画像が抜けないので、何でかいな?と調べたらそういうことで、

if ($data =~ /Content-Type\:\s+(\S+[^\;]*?)/i) {

という正規表現を使った条件をすり抜けてた。

if ($data =~ /Content-Type\:\s*(\S+[^\;]*?)/i) {

とすればOK。

Foma とか AU の端末もこんなんかなあ?

Perl で、POP3 サーバからメールを受信する処理を書かないといけなくなった。

今までだと、直接 Socket の確立から、実際の POP3 コマンドの発行部分まで自分で書いてたんだけど(その方が無駄な処理を省いてシンプルなソースが書けるんでねぇ)、しかし、今回は納期も予算も少ない案件なので、Mail::POP3Client モジュールを使ってみることにした。
(例しに CPAN モジュールでインストールしてみたら、珍しくスコっと入ったし(笑))

use Mail::POP3Client;

して、受信処理の書き方は

 my $pop = new Mail::POP3Client(
  USER => $Muser,
  HOST => $Mhost,
  PASSWORD => $Mpass,
  DEBUG => 0
 );

こんな感じで $pop を Mail::POP3Client クラスのオブジェクトとして宣言し、後は、

 受信メールの件数取得
 $pop->Count

 ヘッダ部の受信
 $pop->Head(メッセージ番号)

 ボディ部の受信
 $pop->Body(メッセージ番号)

 メッセージの削除
 $pop->Delete(メッセージ番号)

 POP3接続の切断
 $pop->Close

などのメソッドを適時使ってソースを書けばいいだけ。
(もちろん、Subject を MIME decode したり、添付ファイルを切り出したりといった処理は自分で書く必要あり)

なのに、実行すると、

Use of uninitialized value in pattern match (m//) at /usr/lib/perl5/site_perl/5.8.5/Mail/POP3Client.pm line 1078, <GEN0> line 2.

なエラーが出てしまい、処理が中断されてしまう。なぜ???

DEBUG 表示を ON にして(DEBUG => 1)実行してみると、

# ./get_pop3_mail.pl
POP3 <- +OK <20028.1242047733@serv.exsample.com>
 at ./get_pop3_mail.pl line 97
POP3 -> APOP mail_test@exsample.com feb4f975bc9cd0c24151ac7ceea4dc1f
 at ./get_pop3_mail.pl line 97
POP3 <- -ERR authorization failed
 at ./get_pop3_mail.pl line 97
POP3 -> NOOP
 at ./get_pop3_mail.pl line 97
Use of uninitialized value in pattern match (m//) at /usr/lib/perl5/site_perl/5.8.5/Mail/POP3Client.pm line 1078, <GEN0> line 2.

となる。
ああ、APOP 未対応の POP3 サーバに対して、APOP 認証しようとしてるのね。で、エラーになってるんだ。
そこで Connection closed by foreign host. になっちゃうので、その後 NOOP コマンドを投げても何のレスポンスも返ってこないから(空値に対してパターンマッチを行おうとして)、そういうエラーを吐いちゃうんだ・・・

しかし、それで Perl のエラーが発生するというのはどういう実装よ。(^^;
なんとかハンドリング出来んのかいな。Socket 接続が切れてたらコマンド送らないとか。むーん・・・

どうも微妙に気持ち悪いんだが、今回は APOP 認証を止めればエラーは出ないので、それで良しとする。

普通にプレーンパスワードで認証をするように、

 my $pop = new Mail::POP3Client(
  AUTH_MODE => 'PASS',
  USER => $Muser,
  HOST => $Mhost,
  PASSWORD => $Mpass,
  DEBUG => 1
 );

という具合に、AUTH_MODE => 'PASS' を追加してやる。

これで、

# ./get_pop3_mail.pl
POP3 <- +OK <23657.1242048016@serv.exsample.com>
 at ./get_pop3_mail.pl line 97
POP3 -> USER mail_test@exsample.com
 at ./get_pop3_mail.pl line 97
POP3 <- +OK
 at ./get_pop3_mail.pl line 97
POP3 -> PASS hogehoge
 at ./get_pop3_mail.pl line 97
POP3 <- +OK
 at ./get_pop3_mail.pl line 97
POP3 -> STAT
 at ./get_pop3_mail.pl line 97
POP3 <- +OK 1 998
 at ./get_pop3_mail.pl line 97
POP3 -> TOP 1 0
 at ./get_pop3_mail.pl line 112
POP3 <- +OK
 at ./get_pop3_mail.pl line 112
POP3 <- Return-Path: <exsample@gmail.com>
<以下略>

という具合に、正常に POP3 によるメール受信が成功する。バッチリ。

おお、DEBUG 出力を無効(DEBUG => 0)にしとかなきゃ。

MT4i を動かそうと思ったらエラーが出ちゃった。

[Mon Apr 20 18:21:26 2009] [error] [client 10.**.**.**] Can't locate HTML/Template.pm in @INC (@INC contains: /usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi
<略>
[Mon Apr 20 18:21:26 2009] [error] [client 10.**.**.**] Premature end of script headers: mt4i.cgi

HTML/Template.pm が無いってさ。

あれれ?以前、MovableType のバージョンが古い時は動いてたのに。
ああ、あの時は手動で mt4i.cgi と同じディレクトリに、手持ちの HTML/Template.pm をアップしたんだ。

今回は、手持ちの古いやつじゃなく、最新版を CPAN からインストールしてみる。いや、単にそういう気分なので。(^^;

# perl -MCPAN -e shell

と CPAN モジュールを実行して、

cpan> install HTML::Template

とな。

そしたら、ftp://ftp.dti.ad.jp に接続出来ないって異常終了しちゃうの。CPAN モジュールが。

なんだよ、DTI。使えねえなあ。(^^;
もしかして、親会社がフリービット(株)になって、こういう社会貢献は辞めちゃったのかねえ。情けねえ。

ということで、最新の ftp://ftp.perl.org/pub/CPAN/MIRRORED.BY を落としてきて、日本のサイトをチェック。
fetch 先を、ftp.dti.ad.jp から ftp.ring.gr.jp に変更した。

# vi /usr/lib/perl5/5.8.5/CPAN/Config.pm
# diff /usr/lib/perl5/5.8.5/CPAN/Config.pm /usr/lib/perl5/5.8.5/CPAN/Config.pm_20090420
40c40
<   'urllist' => [q[ftp://ftp.ring.gr.jp/pub/lang/perl/CPAN/]],
---
>   'urllist' => [q[ftp://ftp.dti.ad.jp/pub/lang/CPAN/]],

で、再度インストールの実行。

# perl -MCPAN -e shell
Terminal does not support AddHistory.

cpan shell -- CPAN exploration and modules installation (v1.7601)
ReadLine support available (try 'install Bundle::CPAN')

cpan> install HTML::Template
CPAN: Storable loaded ok
Going to read /root/.cpan/Metadata
  Database was generated on Mon, 20 Apr 2009 06:26:58 GMT
Running install for module HTML::Template
Running make for S/SA/SAMTREGAR/HTML-Template-2.9.tar.gz
CPAN: LWP::UserAgent loaded ok
Fetching with LWP:
  ftp://ftp.ring.gr.jp/pub/lang/perl/CPAN/authors/id/S/SA/SAMTREGAR/HTML-Template-2.9.tar.gz
CPAN: Digest::MD5 loaded ok
Fetching with LWP:
  ftp://ftp.ring.gr.jp/pub/lang/perl/CPAN/authors/id/S/SA/SAMTREGAR/CHECKSUMS
CPAN: Compress::Zlib loaded ok
Checksum for /root/.cpan/sources/authors/id/S/SA/SAMTREGAR/HTML-Template-2.9.tar.gz ok
Scanning cache /root/.cpan/build for sizes
HTML-Template-2.9/
HTML-Template-2.9/Makefile.PL
HTML-Template-2.9/FAQ
<略>
HTML-Template-2.9/templates/global-loops.tmpl
HTML-Template-2.9/MANIFEST
HTML-Template-2.9/ARTISTIC

  CPAN.pm: Going to build S/SA/SAMTREGAR/HTML-Template-2.9.tar.gz

Checking if your kit is complete...
Looks good
Writing Makefile for HTML::Template
cp Template.pm blib/lib/HTML/Template.pm
Manifying blib/man3/HTML::Template.3pm
  /usr/bin/make  -- OK
Running make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01-bad-args..............ok
t/01coderefs...............ok
t/02-parse.................ok
        2/7 skipped: doesn't do the check yet
t/02random.................ok
<略>
t/11-non-file-templates....ok
t/99-old-test-pl...........ok
        2/80 skipped: Skipping shared memory cache test.  See README to enable
All tests successful, 4 subtests skipped.
Files=20, Tests=457,  2 wallclock secs ( 0.86 cusr +  0.22 csys =  1.08 CPU)
  /usr/bin/make test -- OK
Running make install
Manifying blib/man3/HTML::Template.3pm
Installing /usr/lib/perl5/site_perl/5.8.5/HTML/Template.pm
Installing /usr/share/man/man3/HTML::Template.3pm
Writing /usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi/auto/HTML/Template/.packlist
Appending installation info to /usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/perllocal.pod
  /usr/bin/make install  -- OK

cpan> exit
Terminal does not support GetHistory.
Lockfile removed.

よし、OK! MT4iも無事動きました。:-)

MTOS に MailPack plugin を入れるのに、いくつかの Perl モジュールもインストールしないといかん。

WebARENA SuitePRO V2 のサーバ(CentOS 4.7 x86_64)の場合、以下のようなモジュールのインストールが必要だった。(この順にインストールしていけばいい)

IO-stringy-2.110
Pod-Escapes-1.04
Pod-Simple-3.07
Test-Simple-0.81_02
Test-Pod-1.26
TimeDate-1.16
MailTools-2.04
MIME-Base64-3.07
MIME-tools-5.420_02

あと、おまけで、
IO-1.2301

IOがらみのトラブルの話は
http://blog.netandfield.com/shar/2009/01/iofilebinmode.html
にて。

MovableType の MailPack plugin のメール取得処理で、

[MailPack] listner.pm Can't locate object method "binmode" via package "IO::File" at /usr/lib/perl5/site_perl/5.8.5/MIME/Body.pm line 437.

というエラーが出てしまう。
確かに、/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/IO/File.pm を見てみると、binmode なんてメソッドは無い。

なので、CPAN から最新のソース(http://search.cpan.org/CPAN/authors/id/G/GB/GBARR/IO-1.2301.tar.gz)を取ってきてインストールしてみた。(最新つっても、2006/3/26 fix ですよ。枯れてるなぁ(^^;)

# grep binmode /usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/IO/File.pm
<略>
sub binmode {
    ( @_ == 1 or @_ == 2 ) or croak 'usage $fh->binmode([LAYER])';
<略>

をを、ちゃんと binmode が存在してるじゃないすか。グー。

CentOS 4.7 の File.pm は相当古いんじゃねえ。

携帯から MovableType にエントリを投稿したいというニーズがあるので、うちのテストサーバで、MailPack プラグイン on MTOS 4.22-ja な環境で試行してみた。

引っかかった点は以下の2点。

・MIME-tools のバージョンが 5.420 でないと駄目なのは本当なのねえ。
 インストールの注意に「5.420 でないと駄目。最新の 5.425 じゃあきまへん」と書いてあるんだけど、うちのサーバはさらに新しい 5.427 なんでいけるやろ!と強行したら、やっぱり駄目だった。(^^;
 File::Temp version 0.18 required--this is only version 0.12 at /usr/lib/perl5/site_perl/5.8.5/MIME/Tools.pm line 14.
 とか出ちゃって。依存関係かよ・・・
 しかたないので、泣く泣くバージョンダウン・・・とほほ。(今のところ、他のシステムへの影響は出てないが・・・)

・投稿するメールアドレスが登録されたユーザ作っとかないと駄目なのねえ。
 いやあ、MovableType も個人利用しかしたことないんで、基本的に細かいユーザ設定は知らなかったんだけど、「送信アドレスのユーザーが見つかりません」「ユーザーに投稿権限がありません」と散々怒られ、ユーザ登録、権限の付加などを行いやっと投稿に成功。
 ま、これがセキュリティになってるわけだから仕方ないわな。

つーことで、一応、うちの環境では携帯からのエントリー投稿に(写真付きエントリーも含めて)成功。

むはぁ、夕べは思いのほか手間がかかった・・・

お客さんのサーバの移行を行なったのだが、一部のDBテーブルの移行がうまくいかなくて。
後日対応でもかまわないテーブルだったのだが、状況が謎だらけでその確認だけでもずいぶん時間をとってしまった。

状況としては、varchar(1024) で指定されているレコード項目に、旧サーバでは 2000バイトを超えるデータが登録されているというもの。
そのため、それをそのまま新サーバに移そうとすると当然のごとくエラーとなってしまうわけだ。
DBMS は PostgreSQL。

DB登録を行なう Perl プログラムの中でも、length($hoge) > 1024 なら・・・というチェックをかけているのだが、ここも旧サーバのほうでは 2000バイトを超える文字列がエラーにならず突破してまっている。(EUC の文字数でいうと、1000文字くらい))
もちろん、まったく同じソースを新サーバに持っていくと、このエラーチェックに 2000バイトの文字列は引っかかる。

むーん・・・

もしかして、これがずいぶん昔に話題になった「日本語化パッチの弊害」なのか?

Shift_JIS を扱えるようにする日本語化パッチを Perl に当てると、length や substr が「バイト数ではなく文字数(ダブルバイト文字も 1)でカウントされるようになる」というアレ。
Perl の問題は知ってたんだけど(確か、昔の Turbo Linux の Perl がそういうパッチが当たってる奴じゃなかったっけ?)、PostgreSQL でもエラーにならないってことは、そういうパッチがあるってこと?

旧サーバのほうは、もうずいぶん古いサーバで、僕が管理をしているわけではないので PostgreSQL や Perl にそういうパッチがあたっているかは知らないのだが、とりあえず他に原因が思いつかんし・・・

・・・ということで、昨日は久しぶりの午前様となったのであった。とほほ。

うちの会社で Perl の CGI 作成時にいつも使う自前のテキスト変換関数集があるのだが、その中で MIME B エンコード(メールの Subject とかね)で MIME::Words モジュールを使っている。
MIME-tools に含まれているんだけど、これがまた、たいがいのレンタルサーバで入ってないんだよね。

で、CPAN モジュールを使ったインストールにたいがい失敗するんだよね、MIME-tools・・・

ということで、案の定、NTTPC の WebARENA Suite2 サーバ(CentOS)にもディフォルトじゃ入ってなかった・・・

MIME-tools-5.427 を手作業でいれなきゃ・・・

依存関係にあるファイルが無かったり、バージョンが古かったりするやつを、CPAN サイトから落としてきては手動 make を繰り返す。
結局、WebARENA Suite2 では、MIME-tools-5.427 をインストールするために↓これだけのモジュールを入れなきゃ駄目だった・・・(^^;

ExtUtils-Command-1.14
ExtUtils-Install-1.50
ExtUtils-MakeMaker-6.44
ExtUtils-Manifest-1.54
File-Temp-0.20
IO-1.2301
IO-stringy-2.110
MailTools-2.04
Pod-Escapes-1.04
Pod-Simple-3.07
Test-Pod-1.26
Test-Simple-0.81_02
TimeDate-1.16

半日仕事だよ。(^^;
もしかしたら、この月末にお客さんのサーバに MIME-tools 入れなきゃいけないかもしれないのに、見積漏らしてたなあ・・・(^^;

しかし、WebARENA Suite2 なんかディフォルトでも結構 Perl モジュールが充実していたような気がしたが、なんで MIME-tools なんつうメジャーなモジュールが入ってないんじゃろ?
いや、WebARENA だけじゃないんだけど。

もしかして、みんな MIME-tools 使ってないのか???(じゃ、何使ってるんだろ?
MIME B エンコードや、QuotedPrint のデコードはどうしてるんかね?自前のモジュール?
トレンドを教えてほしいわい。

いや、実は、MIME-tools が入ってないサーバ用に、MIME B エンコードの関数を自作したんだけど、何か、時々デコードすると化けるんだよね(^^;・・・その化ける原因が特定できてないんで(といっても、化ける頻度はかなり小さいんで、実用に耐えられないほどじゃないんだけど)、出来れば「出来合のモジュール」を使いたいんだよね。

結局、Makefile.PL の書き換えなどはせず、GD-2.41も GD-SecurityImage-1.66 も make test で鬼のようにエラーを吐いていたが、そのまま make install した。

で、こんな↓Perl スクリプトを実行したら、一応はイメージが作られた・・・

use GD::SecurityImage;

my $image =
    GD::SecurityImage->new(width    => 300,
                           height   => 40,
                           lines    => 1,
                           font     => "/usr/local/src/GD-2.41/t/Generic.ttf",
                           scramble => 2);
      $image->random('hskdwyq9');
      $image->create(ttf => 'default');
      $image->particle;

my($image_data, $mime_type, $random_number) = $image->out;

open (IMG, ">test.png");
print IMG $image_data;
close(IMG);

これで吐き出した画像が↓


502425.png

 

うわ、きたね。
設定を変えたらきれいになるんかいな?
(ちなみに上の画像には '502425' と書かれている。一応、読めるけど・・・(^^;)

このアーカイブについて

このページには、過去に書かれたブログ記事のうちPerlカテゴリに属しているものが含まれています。

前のカテゴリはAIR/Flexです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

  • photo
  • photo2008
  • podcasting
電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら