AU用文字化け解消メーラスクリプト その1

この間合宿に行っている間,自分の携帯(AU)にメールを転送するようにしたのだが,gmailとかからのUTF-8なメールが文字化けしてしまい,困った.具体的にはAUISO-2022-JPしか対応していないのが原因.むかついたので,文字化けを直すスクリプトを書いてみた.研究室のメールサーバの自分の.forwardに無断で*1仕込んで終了.少しはテストしたけど,バグがないかどうかは定かではないので,以下に変換スクリプトをさらしておきますが,使うなら自己責任で.

#!/usr/bin/python

import sys
import email
import os
import codecs
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.Header import Header
from email.Charset import Charset
from email.Header import decode_header

### Setting
FORWARDTO = "my-keitai-addr@au.example.com"
ME = "my-pc-addr@pc.example.com"
ENCODING = "iso-2022-jp"
SEND_COMMAND = "/usr/sbin/sendmail " + FORWARDTO
ADDHEADER = "X-AU-CONVERTER"

### FOR DEBUG
#SEND_COMMAND = "/bin/cat"

def convert_header(h):
 dec = decode_header(h)
 enc = list()
 for x in dec:
  if not x[1] == None:
   t = (x[0].decode(x[1]).encode(ENCODING),ENCODING)
   enc.append(t)
  else:
   enc.append(x)
 return email.Header.make_header(enc)

OrgMSG = email.message_from_file(sys.stdin)

## Prevent Loop
if OrgMSG[ADDHEADER] != None:
 sys.exit(0)

## Convert into ISO-2022-JP (not-multipart message only)
done = 0 
body = '' 

MSG = MIMEText('','plain',ENCODING)
if not OrgMSG.is_multipart(): 
 if OrgMSG.get_content_type() == "text/plain": 
  if not OrgMSG.get_content_charset('us-ascii') == ENCODING:
   body = OrgMSG.get_payload().decode(OrgMSG.get_content_charset('us-ascii')).encode(ENCODING)
   MSG.set_payload(body)
   done = 1

## Fail Safe
if done == 0:
 MSG = OrgMSG
else:
 decsub = decode_header(OrgMSG['subject'])
 encsub = list()
 for x in decsub:
  if not x[1] == None:
   t = (x[0].decode(x[1]).encode(ENCODING),ENCODING)
   encsub.append(t)
  else:
   encsub.append(x)
 MSG['Subject'] = convert_header(OrgMSG['Subject'])
 MSG['To'] = FORWARDTO
 MSG['From'] = convert_header(OrgMSG['From'])
 MSG[ADDHEADER] = "TRUE"
 MSG['Date'] = OrgMSG['Date']
 MSG['Content-Type'] = 'text/plain; charset="iso-2022-jp"'

## Send mail to FORWARDTO
p = os.popen(SEND_COMMAND,'w')
p.write(MSG.as_string())
p.close()

sys.exit(0)

追伸:研究室で使いたい人は,管理者の人に言ってください.

*1:今管理者じゃないのよね自分.