やるきなし

2019/12/11 21:32 / MHonArc+Namazu での Namazu の UTF-8 対応

ひさしぶりに MHonArc (2.6.19-2) と Namazu (2.0.21-22) をつかってメール検索システム構築(対象はFMLで送られてきたメール).いろいろ嵌ったのでメモ.

MHonArc が生成する HTML を X-Mail-Count の値(整数)にしたい

mhonarcの出力ファイル名の数字を特定のフィールドから決める場当たり的改造」で紹介されているパッチをあてる.mhonarc 実行時に mhonarc -seqnumfield x-mail-count というオプションをつける.以下念の為の 2.6.19 向け版パッチ.

diff --git a/perl/mhamain.pl b/perl/mhamain.pl
index 7af1fcc..eefca45 100644
--- a/perl/mhamain.pl
+++ b/perl/mhamain.pl
@@ -771,7 +771,7 @@ sub write_mail {
 sub read_mail_header {
     my $handle = shift;
     my($date, $tmp, $i, $field, $value);
-    my($from, $sub, $msgid, $ctype);
+    my($from, $sub, $msgid, $ctype, $seq);
     local($_);
 
     my $index  = undef;
@@ -927,6 +927,14 @@ sub read_mail_header {
     }
     @refs = remove_dups(\@refs);        # Remove duplicate msg-ids
 
+    ##------------------##
+    ## Get seq number   ##
+    ##------------------##
+    if (defined($SEQNUMFIELD)) {
+        $seq = $fields->{$SEQNUMFIELD}[0];
+        $seq =~ s/(\d+)/$1/;
+        print STDOUT "($seq)";
+    }
     ##------------------##
     ## Get Content-Type ##
     ##------------------##
@@ -941,6 +949,10 @@ sub read_mail_header {
     my $t = $index;
     $index .= $X . sprintf('%d',(defined($msgnum)?$msgnum:($LastMsgNum+1)));
 
+    if (defined($SEQNUMFIELD)) {
+        $IndexNum{$index} = $seq;
+    }
+
     ## Set mhonarc fields.  Note how values are NOT arrays.
     $fields->{'x-mha-index'} = $index;
     $fields->{'x-mha-message-id'} = $msgid;
@@ -970,7 +982,11 @@ sub read_mail_header {
    $IndexNum{$index} = $msgnum;
    ++$NumOfMsgs; # Counteract decrement by delmsg
     } else {
-   $IndexNum{$index} = getNewMsgNum();
+   if(defined $SEQNUMFIELD) {
+       &getNewMsgNum();
+   }else{
+       $IndexNum{$index} = getNewMsgNum();
+   }
     }
 
     $Refs{$index} = [ @refs ]  if (@refs);
diff --git a/perl/mhopt.pl b/perl/mhopt.pl
index 939109b..587ccab 100644
--- a/perl/mhopt.pl
+++ b/perl/mhopt.pl
@@ -221,7 +221,8 @@ sub get_resources {
    'readdb',   # Just read db
 
    'v',        # Version information
-   'help'      # A brief usage message
+   'help',     # A brief usage message
+   'seqnumfield=s',    # Sequence number field name
     );
 
     ## Check for help/version options (nothing to do)
@@ -576,6 +577,8 @@ sub get_resources {
 
     $IdxPageNum  = $opt{'pagenum'}   if defined($opt{'pagenum'});
 
+    $SEQNUMFIELD = $opt{'seqnumfield'}   if defined($opt{'seqnumfield'});
+
     $AttachmentDir = $opt{'attachmentdir'}  if defined($opt{'attachmentdir'});
     $AttachmentUrl = $opt{'attachmenturl'}  if defined($opt{'attachmenturl'});
 

MHonArc が抽出する添付ファイルのファイル名を MD5SUM 由来のものにしたい

Default だとランダムな文字列(しかも実行する度に異なる)ファイル名になる.

ということもあって MD5SUM 由来のものにする.以下パッチ.やるきなしなのでオプション切り替え不能なパッチ.ファイルが存在する場合は上書きしないことにしてある.

diff --git a/perl/mhmimetypes.pl b/perl/mhmimetypes.pl
index deb806b..c723ead 100644
--- a/perl/mhmimetypes.pl
+++ b/perl/mhmimetypes.pl
@@ -28,6 +28,7 @@
 package mhonarc;
 
 use File::Basename;
+use Digest::MD5 qw(md5_hex);
 
 $UnknownExt     = 'bin';
 
@@ -336,26 +337,27 @@ sub write_attachment {
    $fname =~ tr/\0-\40\t\n\r?:\57\134*"'<>|\177-\377/_/;
     }
 
-    ## Write to random file first
-    my($fh, $tmpfile) = file_temp($ext.'XXXXXXXXXX', $pathname, '.'.$ext);
-    binmode($fh);
-    print $fh $$sref;
-    close($fh);
-
-    ## Set pathname for file
+    my $target;
     if ($fname) {
-   # need to rename to desired filename
-   $pathname .= $DIRSEP . $fname;
-   if (!rename($tmpfile, $pathname)) {
-       die qq/ERROR: Unable to rename "$tmpfile" to "$pathname": $!\n/;
-   }
+        $target = $pathname . $DIRSEP . $fname;
     } else {
-   # just use random filename
-   $pathname = $tmpfile;
-   $fname    = basename($tmpfile);
+        my $md5 = md5_hex($$sref);
+        $fname = $md5.".".$ext;
+        $target = $pathname . $DIRSEP . $fname;
+    }
+    if(! -e $target) {
+        ## Write to random file first
+        my($fh, $tmpfile) = file_temp($ext.'XXXXXXXXXX', $pathname, '.'.$ext);
+        $pathname = $target;
+        binmode($fh);
+        print $fh $$sref;
+        close($fh);
+        if (!rename($tmpfile, $pathname)) {
+            die qq/ERROR: Unable to rename "$tmpfile" to "$pathname": $!\n/;
+        }
+        file_chmod($pathname);
     }
     $url .= '/' if ($url); $url .= urlize_file_path($fname);
-    file_chmod($pathname);
 
     if ($rel_outdir) {
    $pathname  = $path;

なお m2h_external::filterusename argument (添付ファイル名をそのまま用いる,ただし日本語は_に変換される)は活かしておく.誰も使わないだろうけど.usename を使う場合はrcfileに以下を書いておく(See https://www.mhonarc.org/MHonArc/doc/resources/mimeargs.html).

<MIMEArgs>
m2h_external::filter; usename
</MIMEArgs>

Namazu で PDF が検索対象にならない (pdftotext オプション問題)

PDF ファイルは pdftotext で一旦テキストに変換されてインデックスされるが,日本語環境(LANG=ja_JP mknmz . -O indexとか)だと Unable to convert pdf file (maybe copying protection) と怒られてインデックスされない.これ,Namazu の内部処理文字コードの EUC-JP に変換しようとして pdftotext のオプションの箇所でコケている(copy protection が原因ではない).

手元のpdftotextは version 0.71.0 (poppler)なのだが,mknmz はなぜか pdftotext -eucjp で EUC-JP 出力をしようとする(古いやり方).これをpdftotext -enc EUC-JPに変更する.以下パッチやるきなしなし.どこでバージョンのカウントを間違えたのだろうか?...

diff --git a/perl/pdf.pl b/perl/pdf.pl
index 5d63763..2d12946 100644
--- a/perl/pdf.pl
+++ b/perl/pdf.pl
@@ -61,12 +61,13 @@ sub status() {
         if (util::islang("ja")) {
             if ($pdfconvver >= 1.00) {
                 @pdfconvopts = ('-q', '-raw', '-enc', 'EUC-JP');
             } else {
                 @pdfconvopts = ('-q', '-raw', '-eucjp');
             }
+        @pdfconvopts = ('-q', '-raw', '-enc', 'EUC-JP');
         } else {
             @pdfconvopts = ('-q', '-raw');
         }
         if (defined $pdfinfopath) {
             my @cmd = ("$pdfinfopath");
             my $result = "";

Namazu でエクセルファイルが検索対象にならない

というかxlhtmlって今手に入るの? 問題.xlhtmlでHTMLに変換してそれをインデックスすることになっている.

python-excelerator付属のpy_xls2htmlで代用する.PATHの通っているところにxlhtmlとしてシンボリックリンクを作る(これだけでOK).

MHonArc で日本語をそれなりに...

Default だと UTF-8 ではなく数値文字参照(&#xXXXX;とか)を大量に含む HTML になって極めて感じ悪い.http://www.mhonarc.jp/MHonArc の日本語化 (for v2.6.x)を行う.具体的には以下をrcfileに書いておく.

<Include>
/usr/share/doc/mhonarc/examples/utf-8-encode.mrc
</Include>

<DefCharset>
iso-2022-jp
</DefCharset>

<DecodeHeads>

MHonArc のインデックスファイルと Namazu の連携で文字化け

<IdxPgBegin> に Namazu の form を置いておくと便利かと思ったら,Namazuに適切にクエリが渡らない.これは MHonArc が UTF-8 で Namazu が EUC-JP だから.今どき EUC-JP て...

対策は以下のように別 script (ラッパー)でクエリを一旦受け取り,それを EUC-JP に変換して namazu を呼び出すというもの.

perl で書かれているものは手元では動かず,http://www.ne.jp/asahi/music/marinkyo/namazu/utf8.html.ja の下の方にある ruby 版を利用することにした (真ん中あたりに書いてある iconv 版は,今どきのruby には iconv が付属しないので注意...String#encodeを使うことになる).ほぼ同じだが以下私版.

#!/usr/bin/env ruby

require 'cgi'

cgi = CGI.new
query_str = ""

cgi.params.each{|key, values|
    values.each{|a_value|
        query_str += key + "=" + CGI.escape(a_value.encode("EUC-JP")) + ";"
    }
}
print "Location: https://myn.example.com/namazu/?"+query_str+"\n\n"

MHonArc でインクリメンタルにファイルを追加できない

MHonArc では -add オプションにより,追加されたファイルのみ処理するモードがある.ただし以下でコケる.

% mhonarc -rcfile mhonarc.rc -outdir output -seqnumfield x-mail-count archive -add
This is MHonArc v2.6.19+, Perl 5.028001 linux
Reading database ...

Can't locate output/.mhonarc.db in @INC (@INC contains: lib /usr/share/mhonarc /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.28.1 /usr/local/share/perl/5.28.1 /usr/lib/x86_64-linux-gnu/perl5/5.28 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.28 /usr/share/perl/5.28 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at /usr/share/mhonarc/mhopt.pl line 401.

もうやるきなしなので,以下で @INC. を追加して MHonArc 実行.

% perl -I. `which mhonarc` -rcfile mhonarc.rc -outdir output -seqnumfield x-mail-count archive -add