pythonでGMAIL経由メール送信の時代錯誤で非推奨な方法

「出来るよ」てことを紹介したいわけでもなくて。

結構どうしたもんかなぁ、と言う話であって。スクリプトは例えばこんななの:

send.py
  1 import smtplib
  2 import mimetypes
  3 from email.mime.base import MIMEBase
  4 from email import encoders
  5 from email.MIMEText import MIMEText
  6 from email.MIMEImage import MIMEImage
  7 from email.MIMEMultipart import MIMEMultipart
  8 from email.Header import Header
  9 from email.Utils import formatdate
 10 import glob, time, sys, os
 11 import logging
 12 import shutil
 13 import getpass
 14 
 15 your_gmail_account = 'hogeehageehigee@gmail.com'
 16 sendto_addr = 'harahire@horohire.net'
 17 yourpassword = getpass.getpass("password for %s? " % your_gmail_account)
 18 
 19 def send_via_gmail(msg):
 20     s = smtplib.SMTP('smtp.gmail.com', 587)
 21     s.ehlo()
 22     s.starttls()
 23     s.ehlo()
 24     s.login(your_gmail_account, yourpassword)
 25     s.sendmail(your_gmail_account, [sendto_addr], msg.as_string())
 26     s.close()
 27 
 28 def create_message(archive_basename_desired, encoding='utf-8'):
 29     outer = MIMEMultipart()
 30     outer['Subject'] = Header(archive_basename_desired, encoding)
 31     outer['From'] = your_gmail_account
 32     outer['To'] = sendto_addr
 33     content = MIMEText(archive_basename_desired, 'plain', encoding)
 34     outer.attach(content)
 35 
 36     path = archive_basename_desired
 37 
 38     if path:
 39         # Guess the content type based on the file's extension.  Encoding
 40         # will be ignored, although we should check for simple things like
 41         # gzip'd or compressed files.
 42         ctype, encoding = mimetypes.guess_type(path)
 43         if ctype is None or encoding is not None:
 44             # No guess could be made, or the file is encoded (compressed), so
 45             # use a generic bag-of-bits type.
 46             ctype = 'application/octet-stream'
 47         maintype, subtype = ctype.split('/', 1)
 48         if maintype == 'text':
 49             fp = open(path)
 50             # Note: we should handle calculating the charset
 51             msg = MIMEText(fp.read(), _subtype=subtype)
 52             fp.close()
 53         elif maintype == 'image':
 54             fp = open(path, 'rb')
 55             msg = MIMEImage(fp.read(), _subtype=subtype)
 56             fp.close()
 57         elif maintype == 'audio':
 58             fp = open(path, 'rb')
 59             msg = MIMEAudio(fp.read(), _subtype=subtype)
 60             fp.close()
 61         else:
 62             fp = open(path, 'rb')
 63             msg = MIMEBase(maintype, subtype)
 64             msg.set_payload(fp.read())
 65             fp.close()
 66             # Encode the payload using Base64
 67             encoders.encode_base64(msg)
 68         # Set the filename parameter
 69         msg.add_header('Content-Disposition', 'attachment', filename=path)
 70         outer.attach(msg)
 71 
 72         if not os.path.exists("__DONE"):
 73             os.mkdir("__DONE")
 74         shutil.move(path, "__DONE")
 75 
 76     return outer
 77 
 78 import time, sys, os
 79 if __name__ == '__main__':
 80     pattern = sys.argv[1]
 81 
 82     FORMAT = '%(levelname)-5s - %(asctime)-15s | %(message)s | - %(funcName)s'
 83     logging.basicConfig(stream=sys.stderr, level=logging.INFO, format=FORMAT)
 84 
 85     target_files = sorted(list(glob.glob(pattern)))
 86     for i, fn in enumerate(target_files):
 87         if i > 0:
 88             time.sleep(10)
 89         if not os.path.exists(fn):
 90             continue
 91         logging.info("send '%s'..." % fn)
 92         m = create_message(fn)
 93         try:
 94             send_via_gmail(m)
 95         except:
 96             time.sleep(20)
 97             try:
 98                 send_via_gmail(m)
 99             except:
100                 time.sleep(40)
101                 send_via_gmail(m)
102         logging.info("send '%s' done." % fn)

このスクリプトの場合は、

1 me@host: ~$ python send.py 'abc.zip_a*'

みたいにすれば、複数のバイナリファイルを添付ファイルにして送信する…のだけれど。

なんというかこれはもはや「お勧めです!」と言えるようなもんではなくなっていて。

例えばこんなよ:

この制約を回避するには上のエラーメールの指示に従って、こうね:

つまりは「正規の API を使わざるもの人にあらず」という、まぁ正論ですね。

なんつぅか他人が作るものに対してこうやってガードが固くなるのは喜ばしいことなんだけれど、それによって自分が日常使うものに影響するのは面倒だなぁ、と。