「
PythonでEvernoteへメールを送る」で載せたプログラムへ、ファイル添付機能を追加しました。
合わせてクラス設計を見直しました。
# -*- coding: utf-8 -*-
# ---- CONFIGURATIONS ----
EVERNOTE_MAIL_ADDRESS = 'evernote_mail_address'
FROM_ADDRESS = 'from_address'
SMTP_HOST = 'smtp_host'
SMTP_PORT = 25
# ---- CONFIGURATIONS ----
import datetime
import mimetypes
import optparse
import os.path
import smtplib
import sys
from email import encoders
from email.header import Header
from email.mime.audio import MIMEAudio
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
class EverMailClient(object):
def __init__(self, smtp):
assert isinstance(smtp, smtplib.SMTP)
self._smtp = smtp
def send(self, mail):
assert isinstance(mail, EverMail)
msg = mail.as_MIME()
mail_from = msg['From']
mail_to = msg['To']
self._smtp.sendmail(mail_from, mail_to, msg.as_string())
class EverMail(object):
def __init__(self, title, from_address, to_address, body, attached_files):
assert isinstance(title, EverMailTitle)
assert isinstance(body, EverMailBody)
self._title = title
self._from_address = from_address
self._to_address = to_address
self._body = body
self._attached_files = attached_files
def as_MIME(self):
msg = MIMEMultipart()
msg['Subject'] = Header(str(self._title), 'utf-8')
msg['From'] = self._from_address
msg['To'] = self._to_address
msg.attach(self._body.as_MIME())
for attached_file in self._attached_files:
msg.attach(attached_file.as_MIME())
return msg
class EverMailTitle(object):
def __init__(self, title, notebook, tags):
self._title = title if title else str(datetime.datetime.now())
self._notebook = notebook if notebook else ''
self._tags = tags if tags else []
def __str__(self):
result = self._title
if 0 < len(self._notebook):
result += ' @' + self._notebook
for tag in self._tags:
result += ' #' + tag
return result
class EverMailBody(object):
def __init__(self, stdin):
assert hasattr(stdin, 'read')
self._stdin = stdin
def as_MIME(self):
body = sys.stdin.read()
msg = MIMEText(bytes(body))
msg.set_charset('utf-8')
return msg
class AttachedFile(object):
def __init__(self, path):
self._path = path
def as_MIME(self):
ctype, encoding = mimetypes.guess_type(path)
if ctype is None or encoding is not None:
ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
msg = None
with open(self._path, 'rb') as f:
if maintype == 'text':
msg = MIMEText(f.read(), _subtype=subtype)
elif maintype == 'image':
msg = MIMEImage(f.read(), _subtype=subtype)
elif maintype == 'audio':
msg = MIMEAudio(f.read(), _subtype=subtype)
else:
msg = MIMEBase(maintype, subtype)
msg.set_payload(f.read())
encoders.encode_base64(msg)
file_name = os.path.basename(self._path)
msg.add_header('Content-Disposition', 'attachment', filename=file_name)
return msg
class EverMailOptionParser(optparse.OptionParser):
def __init__(self):
optparse.OptionParser.__init__(self)
self.add_option('--notebook', '-n', action='store')
self.add_option('--tag', '-t', action='append')
def create_smtp_client():
smtp = smtplib.SMTP(SMTP_HOST, SMTP_PORT)
smtp.set_debuglevel(1)
return smtp
if __name__ == '__main__':
option_parser = EverMailOptionParser()
(options, args) = option_parser.parse_args()
note_title = args[0] if args and 0 < len(args) else ''
title = EverMailTitle(note_title,
options.notebook,
options.tag)
body = EverMailBody(sys.stdin)
attached_files = []
if 2 <= len(args):
attached_files = [AttachedFile(path) for path in args[1]]
mail = EverMail(title,
FROM_ADDRESS,
EVERNOTE_MAIL_ADDRESS,
body,
attached_files)
smtp = None
try:
smtp = create_smtp_client()
client = EverMailClient(smtp)
client.send(mail)
finally:
if smtp: smtp.close()
複数ファイルを添付するとうまくいかないところが問題です。
また時間のあるときに対応したいと思います。