読者です 読者をやめる 読者になる 読者になる

Djangoでメール送信〜文字化け(全角マイナスなどの)対応

djangoでメール送信する時の話。
iso2022jpでメール送信しようとすると全角マイナス('−')などが文字化けするので、これを文字化けしないように対応してやる

id:tokibito@shin_no_sukeにサポートしてもらい、以下ソースコードのsend_mailで対応。

import string
import commands
import re

from django.conf import settings
from django.core import mail
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate, parseaddr, formataddr

class JPMimeText(MIMEText):
    def __setitem__(self, name, val):
        if name.lower() == ('subject'):
             val = Header(val.encode('iso-2022-jp','replace'), 'iso-2022-jp',)
        elif name.lower() == ('to'):
             val = ','.join(val)
        elif name.lower() == ('cc'):
             val = ','.join(val)
        elif name.lower() == ('bcc'):
             val = ','.join(val)
        MIMEText.__setitem__(self, name, val)

def send_mail(subject,body,to_list,from_=None,cc_list=None,bcc_list=None):
    """メール送信"""
    if not from_:
        from_ = settings.MAIL_FROM
    #DjangoのEmailMessageでは適切なSubjectにならないのでPythonのモジュール使う
    # 機種依存文字の対応。
    # 'uff0d' -> '−'
    # 'uff5e' -> '〜'
    # 'u2225' -> '‖'
    # 'uffe0' -> '¢'
    # 'uffe1' -> '£'
    # 'uffe2' -> '¬'
    mapping = {
        u'\uff0d': u'\u2014',
        u'\uff5e': u'\u301C',
        u'\u2225': u'\u2016',
        u'\uffe0': u'\u00A2',
        u'\uffe1': u'\u00A3',
        u'\uffe2': u'\u00AC',
    }
    re_jis = re.compile(ur'[%s]' % ''.join(mapping))
    body = re_jis.sub(lambda m:mapping[m.group()], body)
    msg = JPMimeText(body.encode('iso-2022-jp','replace'), \
               'plain', 'iso-2022-jp')
    msg['Subject'] = subject
    msg['From'] = from_
    msg['To'] = to_list
    if cc_list: msg['Cc'] = cc_list
    if bcc_list: msg['Bcc'] = bcc_list
    msg['Date'] = formatdate()
    c = mail.SMTPConnection()
    c.open()

使い方例

send_mail_basic(u'タイトル',u'ぼでぃー―〜‖¢£¬', ['to@example.com'], ['from@example.com'], ['cc@example.com'], ['bcc@example.com'])