2012年10月23日火曜日

Perlで文字コード判別

たまにnkf入っていないサーバーとかあるので、そんな時はPerlで文字コードを調べる。。こともあるかも。

今こんな感じで書いているけど、おかしいorもっと簡潔にかけるなら修正する。
#!/usr/bin/perl
use Encode::Guess qw/shift-jis euc-jp 7bit-jis/;
local $/ = undef;
my @data = <STDIN>;
close(IN);
my $enc = Encode::Guess->guess(@data);
ref($enc) || die "Can't guess: $enc";
print "Encode => ". $enc->name;
print "\n";
view raw guess.pl hosted with ❤ by GitHub
と、見せかけnkfがないならpiconv使えばいいじゃない!

PerlでQuotedPrintをデコード/エンコードするワンライナー

MIME::QuotedPrintを使う

QuotedPrintにエンコード

$ echo "エンコード文字" | perl -M'MIME::QuotedPrint' -e 'while (<STDIN>) { print encode_qp($_); }'
=E3=82=A8=E3=83=B3=E3=82=B3=E3=83=BC=E3=83=89=E6=96=87=E5=AD=97

QuotedPrintのデコード

$ echo "=E3=82=A8=E3=83=B3=E3=82=B3" | perl -M'MIME::QuotedPrint' -e 'while (<STDIN>) { print decode_qp($_); }'
エンコ

Base64操作はコマンドで

Base64は、Linuxのcoreutilsに含まれているので素直にそれ使う。方が楽だと思う。

Base64エンコード

$ echo "べーすろくよん" | base64
44G544O844GZ44KN44GP44KI44KTCg==

Base64デコード

$ echo 44G544O844GZ44KN44GP44KI44KTCg== | base64 -d
べーすろくよん

ついでにヘッダーで使うエンコードのフォーマット

=?{charset}?{B or Q}?{Encoded String}?=

例.
=?utf8?B?44G544O844GZ44KN44GP44KI44KTCg==?=

結果.
「べーすろくよん」と表示される。

ワンライナー

っていいね!

2012年10月22日月曜日

PerlでGmailのメールをAppendする

Net::IMAP::Clientを使ってメールをAppend。

#!/usr/bin/env perl
use Net::IMAP::Client;
use Data::Dumper;
use strict;
use warnings;
# 引数チェック
if (@ARGV != 4){
print "Usage: file.pl <Server> <User> <Pass> <InputMail> \n";
die;
}
my $imap = Net::IMAP::Client->new(
server => $ARGV[0],
user => $ARGV[1],
pass => $ARGV[2],
ssl => 1,
port => 993
) or die "Could not connect to IMAP server";
# ログイン
$imap->login or die($imap->last_error);
# メールをAppend
my $eml = readEml($ARGV[3]);
$imap->append('INBOX', \$eml);
# 終了
$imap->quit;
print "Append end.\n";
# emlファイル読み込み
sub readEml {
my $path = shift;
open(IN, "<", $path);
read (IN, $eml, (-s $path));
close IN;
return $eml;
}
view raw imapAppend.pl hosted with ❤ by GitHub

PerlでGmailのメールを保存

とりあえず貼っておきます。

#!/usr/bin/env perl
use Net::IMAP::Client;
use Data::Dumper;
use strict;
use warnings;
my $imap = Net::IMAP::Client->new(
server => $ARGV[0],
user => $ARGV[1],
pass => $ARGV[2],
ssl => 1,
port => 993
) or die "Could not connect to IMAP server";
# ログイン
$imap->login or die($imap->last_error);
# INBOXを選択
$imap->select('INBOX') or die($imap->last_error);
# メールをFetch
my $data = $imap->fetch('*', 'BODY.PEEK[]');
# 配列の場合
if( ref($data) eq 'ARRAY' ){
foreach my $mail (@$data) {
print $mail->{'UID'};
print $mail->{'BODY[]'};
createEml($mail->{'UID'}, $mail->{'BODY[]'});
}
# 配列じゃない場合
} else{
print $data->{'UID'};
print $data->{'BODY[]'};
createEml($data->{'UID'}, $data->{'BODY[]'});
}
# 終了
$imap->quit;
# emlファイル生成
sub createEml {
my $uid = shift;
my $body = shift;
# 保存フォルダ作成
if (!-d $ARGV[3]){
mkdir $ARGV[3];
}
my $emlDir = $ARGV[3] . '/' . $ARGV[1];
if (!-d $emlDir){
mkdir $emlDir;
}
# eml保存先
my $eml = $emlDir . '/' . "${uid}.eml";
open( my $FH, ">", $eml )
or die "Cannot open file for write: $!";
print $FH $body;
close $FH;
}
view raw imapFetch.pl hosted with ❤ by GitHub