Skip to content

Instantly share code, notes, and snippets.

@pypeach
Last active July 23, 2018 13:09
Show Gist options
  • Save pypeach/4fae76e373861d87e6a972cb67e62c41 to your computer and use it in GitHub Desktop.
Save pypeach/4fae76e373861d87e6a972cb67e62c41 to your computer and use it in GitHub Desktop.
メール送信のユーティリティ
# coding:utf-8
import email
import email.header
import imghdr
import logging
import mimetypes
import os
import smtplib
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate, make_msgid
import chardet
import dateutil.parser
from app.util import app_config, message_access
"""
メール送信を制御する
"""
__author__ = "t.ebinuma"
__version__ = "1.1"
__date__ = "25 March 2018"
def get_mail_template_text(file_name):
"""
メールテンプレートのテキストを読み込む
"""
with open(os.path.join(app_config.get_value('mail_template_path'), file_name), 'r', encoding='UTF-8') as f:
mail_template_text = f.read()
return mail_template_text
def send(mail_from, mail_to_list, mail_subject, mail_body, mail_attachment_file_list):
"""
メール送信を行う
"""
logger = logging.getLogger(__name__)
try:
mail_message = MIMEMultipart()
# 宛先を設定する(複数の宛先が存在する場合、カンマ区切りにする)
mail_message['To'] = ",".join(mail_to_list)
# 送信元を設定する
mail_message['From'] = mail_from
# 送信日時を設定する
mail_message['Date'] = formatdate()
# 件名を設定する
mail_message['Subject'] = mail_subject
# メッセージIDを設定する
mail_message['Message-ID'] = make_msgid()
# 本文を設定する
mail_message.attach(MIMEText(mail_body, _subtype='plain', _charset='utf-8'))
# 添付ファイルを設定する
for mail_attachment_file_item in mail_attachment_file_list:
mail_message.attach(_add_attachment_file(mail_attachment_file_item))
if app_config.get_value('mail_debug_mode') is False:
# SMTPサーバの接続を開始する
mail_connect = smtplib.SMTP(app_config.get_value('mail_host'), app_config.get_value('mail_port'))
# 認証する
mail_connect.login(app_config.get_value('mail_user'), app_config.get_value('mail_password'))
# SMTPメール送信する
mail_connect.sendmail(mail_from, ",".join(mail_to_list), mail_message.as_string())
# SMTPサーバの接続を終了する
mail_connect.close()
# デバック用にメール内容を出力する
# Fromを出力する
logger.debug("From={}".format(mail_message['From']))
# Toを出力する
logger.debug("To={}".format(mail_message['To']))
# 件名を出力する
logger.debug(
"Subject={}".format(email.header.make_header(email.header.decode_header(mail_message['Subject']))))
# 送信日時を出力する
logger.debug("Date={}".format(dateutil.parser.parse(mail_message.get('Date')).strftime("%Y/%m/%d %H:%M:%S")))
body = ""
attach_file_list = []
for part in mail_message.walk():
# ContentTypeがmultipartの箇所は読み飛ばす
if part.get_content_maintype() == 'multipart':
continue
attach_file_name = part.get_filename()
# 添付ファイルかを判定する
if attach_file_name:
image_type = imghdr.what(None, h=part.get_payload(decode=True))
if image_type is None:
# 添付ファイルが画像以外の場合、データ読み込みを行う
charset = chardet.detect(part.get_payload(decode=True))
attach_file_list.append({
"name": attach_file_name,
"data": part.get_payload(decode=True).decode(charset['encoding'])
})
else:
# 添付ファイルが画像の場合、ファイル名のみを設定する
attach_file_list.append({
"name": attach_file_name,
})
else:
# 本文を読み込む
body = part.get_payload(decode=True).decode(part.get_content_charset())
# 本文を出力する
logger.debug("Body={}".format(body))
# 添付ファイルを出力する
logger.debug("Attach_File={}".format(attach_file_list))
except Exception as e:
raise e
# メール送信完了をメッセージ出力する
logger.info(message_access.get_message('I905'))
return
def _add_attachment_file(file_path):
"""
添付ファイルの追加を行う
"""
try:
mime_type, mime_encoding = mimetypes.guess_type(file_path)
if mime_encoding or (mime_type is None):
mime_type = 'application/octet-stream'
main_type, sub_type = mime_type.split('/')
if main_type == 'text':
with open(file_path, mode='rb') as f:
fb = f.read()
charset = chardet.detect(fb)
attachment_file = MIMEText(fb, _subtype=sub_type, _charset=charset['encoding'])
else:
with open(file_path, mode='rb') as f:
fb = f.read()
attachment_file = MIMEBase(main_type, sub_type)
attachment_file.set_payload(fb)
email.encoders.encode_base64(attachment_file)
attachment_file.add_header('Content-Disposition', 'attachment', filename=os.path.basename(file_path))
except Exception as e:
raise e
return attachment_file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment