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

$ service ssh0 start

from everything import *

プロセスの終了時にGmailを送信する【Python】

Python

今回は,少し前にPythonGmailを使う方法を学んだので,それをまとめておきたいと思います.

それから,コマンドを実行し,その結果をGmailで送信するシェルスクリプトも作りましたので,その紹介も.

参考:

ベースとなったもの:unoh.github.com by unoh:

やりたいことそのもの:Pythonでプロセスを監視して終了したらgmailを使ってメール送信する | せかいらぼ:

画像の送信について:独学Linux : Python スクリプトでGmail経由のメールを送信する方法:

SMTPに関して:プログラミングと慶應通信 : Pythonでgmailの送受信:

日本語の扱いについて:Pythonで日本語メールを送る方法をいろいろ試した - Qiita:

Pythonを使ってGmailを送信する

まず,参考にしたコードをコピペしてみて,動くかどうか試しましたが,一応動きました.あとはこれを外から呼び出したりするときに使いやすいようにカスタマイズするだけです.また,日本語のエンコードの問題や,セキュリティ面を考えて,さらにいくつかのサイトを参考にして,改良しました.

とりあえず全部を載せておきます.

sendGmail.py

#!/usr/bin/python

# -*- coding: utf-8 -*-

import smtplib

from email.MIMEText import MIMEText

from email.Header import Header

from email.Utils import formatdate

from platform import python_version

import argparse

import getpass

import codecs

release = python_version()

if release > '2.6.2':

from smtplib import SMTP_SSL

else:

SMTP_SSL = None

def create_message(from_addr, sender_name, to_addr, subject, body, encoding):

msg = MIMEText(body, 'plain', encoding)

msg['Subject'] = Header(subject, encoding)

form_jp = u"%s <%s>" % (str(Header(sender_name, encoding)), from_addr)

msg['From'] = from_addr

msg['To'] = to_addr

msg['Date'] = formatdate()

return msg

def send_via_gmail(from_addr, to_addr, passwd, msg):

if SMTP_SSL:

print "send via SSL..."

s = SMTP_SSL('smtp.gmail.com', 465)

s.login(from_addr, passwd)

s.sendmail(from_addr, [to_addr], msg.as_string())

s.close()

print 'mail sent!'

else:

print "send via TLS..."

s = smtplib.SMTP('smtp.gmail.com', 587)

if release < '2.6':

s.ehlo()

s.starttls()

if release < '2.5':

s.ehlo()

s.login(from_addr, passwd)

s.sendmail(from_addr, [to_addr], msg.as_string())

s.close()

print "mail sent!"

if __name__ == '__main__':

parser = argparse.ArgumentParser(description='Send Gmail.')

parser.add_argument('-t', '--to', dest='to_addr', type=str,

default='デフォルトの送信先',

help='To address')

parser.add_argument('-s', '--subject', dest='subject', type=str,

default='デフォルトのタイトル', help='Title')

parser.add_argument('-b', '--body', dest='body', type=str,

default='no message', help='Body of the mail.')

args = parser.parse_args()

from_addr = "送信元のGmailアドレス"

sender_name=u'送信元の名前'

print "from: %s <%s>" % (sender_name, from_addr)

passwd = getpass.getpass()

to_addr = args.to_addr

title = args.subject

body = args.body

msg = create_message(from_addr, sender_name, to_addr, title, body, 'utf-8')

send_via_gmail(from_addr, to_addr, passwd, msg)

前半のバージョンチェックは必要かわかりませんが,他の環境でも動くためにはこれくらい必要なのかもしれません(コピペですみません).argparseを使えば,オプションの扱いが楽になるようなので,今回導入しました.

ちなみに,ヘルプを表示させることも可能で,

Selection_008.png

のように表示してくれます.

それ以外の基本の部分は,参考にしたサイトのものとほとんど同じです.SSLの方がTLSよりセキュリティ的には良いようです.また,Googleアカウントのパスワードを直で書くのには抵抗があると思うので,直接実行する場合には,キーボードからの入力を受け付け,getpassを使うことで打った内容が表示されないようにしてあります.

プロセスの終了を待って,メールでお知らせ

なぜわざわざPythonからメールを送りたいかというと,時間のかかる計算を研究室のパソコンでさせておいて,自分は家に帰って結果が出てきたらそれを受け取る,ということをしたかったからです.なんで?って,なんかかっこいいじゃないですか!

・・・ということで,今度はその部分をシェルスクリプトで書くことにします.基本的にはPythonスクリプトを対象にしているのですが,汎用性を考えて,コマンド自体を引数に与える形にしました.

コードはこちら.

psWatchMail.sh

if [ $# = 0 ]; then

echo "need argument 'COMMAND'" 1>&2

exit 0

else

COMMAND=$1

fi

subject="command \"${COMMAND}\" done"

result=`${COMMAND}`

wait

sleep 1

python /スクリプトまでのパス/sendGmail.py -t "送信先メールアドレス" -s "${subject}" -b "${result}"

echo "${result}"

exit 0

これにより,

sh psWatchMail.sh "実行するコマンド"

とコマンドを指定することにより,そのコマンドが終了した時点で,スクリプト内で指定した宛先に,

「command "実行するコマンド" done」

という題名で,その標準出力を本文としたメールが送ることができます.最初はPIDなどを指定してプロセスが生きているかどうかの判定を行う方法を考えて,その方面で調べていたのですが,こっちの方がシンプルでわかりやすいので,こちらの方法を使うことにしました.どちらの場合にしろ,欠点はプロセスが完全に終了しないとメールが送れないということで,今まで作ったようなGUIのシミュレーションとは相性が悪いです.まぁ,初めから時間のかかるとわかっている部分があったら,逆にそのPythonスクリプトの内部でsendGmail.pyを呼び出すようにしておけば,任意のタイミングでメールを送ることができるので,それはそれでいいでしょう.もしくは,CPUの使用率をモニターして,ある閾値を下回ったら終了したと判定してもいいかもですね.これはおいおい考えることにします.

実行例は,

Selection_009.png

のようになります.Gmail側からも

Selection_010.png

と,メールが送信されていることが確認できます.

まとめ

PythonGmailを使う方法をまとめました.しかし,これはGmailに限らず,他のメールクライアントからも送ることができます.その場合,メールサーバのアドレスとポート番号を変更してやればいいです.僕の場合,実際に大学のメールアカウントのバージョンも作っていて,ターミナルからメールを打つこともあります.便利かと言われると微妙ですが.でも,いちいちログイン認証とか,重たいサイトを開かないといけなくてイラッとする人には向いてると思います.(これじゃ僕が心の小さい人みたいじゃないか!)ともかく,これで家と研究室,両方のパソコンで放置プレイが可能になりました.重たい計算ももう怖くないですね!