Hatena::ブログ(Diary)

備忘録とか あと あれとか それとか

2012-01-31

Matlab/Octaveからメールを送る

Matlabにはsendmailというコマンドがあって,Matlabからメールを送信することができる.

アドレス リストに電子メールを送信 - MATLAB

初心者によるMATLABメモ | sendmail

しかし,Octaveにこの機能は無い.

なのでPython + Gmail + systemコマンドを使ってつくることにする.

Windowsじゃ使えないけどね.

Pythonを使ったメール送信 via Gmail

以下からZIPファイルをダウンロード

gmailsend.py, send_notify.py, & mail_notify.m

解凍後,send_notify.pyの50行目

sg = sendGmail('utf-8', subject, body, 'xxx@gmail.com', to_addr, 'xxx@gmail.com', 'xxxxxxx')

という感じに書き換える.

これらの解説は,

Pythonを使ってGmail経由でメールを送る

にあります.

gmailsend.pyとsend_notify.pyを適当なフォルダに移動(これ以降の例だと,~/scripts/notify_py).

メールを送信するMatlab/Octaveスクリプト

mail_notify.mを呼び出すことでメールを送信する.

function status = mail_notify(ads, sbj, body)

input = '';
if nargin > 0
	input = sprintf('%s "%s"', input, ads);
end

if nargin > 1
	input = sprintf('%s "%s"', input, sbj);
end

if nargin > 2
	input = sprintf('%s "%s"', input, body);
end

cmd = sprintf('python ~/scripts/notify_py/send_notify.py %s', input);
[output status] = system(cmd);
disp(status)

使い方は,

>> mail_notify_py('xxx@xxx.xx', 'matlab/octave', 'scripts finished');

実行すると

  • 宛先: xxx@xxx.xx
  • 件名: [Nortification] matlab/octave 01/31/12-13:19:10
  • 送信元: xxx@gmail.com
  • 本文:

scripts finished

From hostname.com

/dev/pts/12

/hoge/users/dir1/dir2

01/31/12-13:19:10

といった感じのメールがくる.

Pythonを使ってGmail経由でメールを送る

「計算が終わった」とか「スクリプトが終わった」とか「コンパイルが終わった」とか,そういうときに通知が欲しい.

そこで,メールを使って通知させることにする.

作業が終わったら,サーバからメールを送ってそれをメーラで受け取ることで通知になるわけだ.


メールを送るといったらmailコマンドなのだけど,mailコマンドを使って外部にメールを飛ばすにはサーバを立ち上げないといけない.

それだとどこでも使えないので(そもそも職場や研究室ネットワークを勝手にいじれないし),sendmailで外部のSMTPサーバ,今回はGmail,を使って送信できるようにする.

このようなことは,Pythonでできるらしいので,以下のページを参考にやってみる.

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

#junki::acoustic: PythonでGmailを送信

ウノウラボ by Zynga Japan: Pythonでメールを送信したい人のためのサンプル集


gmailsend.pyとsend_notify.pyをまとめてダウンロード

PythonGmail送信スクリプト

まずは,Gmailでメールを送るための関数などを定義.

ココのを参考にした.

解説はココに詳しい.

ダウンロード - gmailsend.py

#!/usr/bin/python

import smtplib
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate

class sendGmail:
  def __init__(self, encoding, subject, body, from_addr, to_addr, login_addr, passwd):
	self.date = formatdate()
	self.encoding = encoding
	self.subject = subject
	self.body = body.encode('utf-8')
	self.from_addr = from_addr
	self.to_addr = to_addr
	self.login_addr = login_addr
	self.passwd = passwd

  def sendMail(self):
    msg = MIMEText(self.body, 'plain', self.encoding)
    msg['Subject'] = Header(self.subject, self.encoding)
    msg['From'] = self.from_addr
    msg['To'] = self.to_addr
    msg['Date'] = self.date

    s = smtplib.SMTP('smtp.gmail.com', 587)
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login(self.login_addr, self.passwd)
    s.sendmail(self.from_addr, self.to_addr, msg.as_string())
    s.close()

これらの関数を読みこめば,以下のようにメールを送信することが出来るはず(Macで実行した場合).

$ python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import gmailsend *
>>> sg = sendGmail(encoding, subject, body, 'from_address@gmail.com', to_address@xxx.xxx, 'gmail_account@gmail.com', passwd)

解説すると

という感じ.


gmailsend.pyを使った通知スクリプト

gmailsend.pyを使って,作業が終わったら呼び出されて通知メールを送るスクリプト

ダウンロード - send_notify.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys

argvs = sys.argv # 引数のリスト
argc = len(argvs) # 引数の数

# 本文をつくるなど
import commands
pwd = commands.getoutput("pwd")
host = commands.getoutput("hostname")
date = commands.getoutput("date +%D-%T")

subject = '[Notification]'
if (argc < 2): # 宛先がない場合はエラー
	print 'Usage: python send_notify.py address subject body'
	quit()
if (argc < 3): # 件名なし
	subject = subject + ' ' + date
else:
	subject = subject + ' ' + argvs[2]  + ' ' + date 

print subject

if (argc < 4): # 本文なし
	lbody = ''
else:
	lbody = argvs[3]

body = lbody + '\nFrom ' + host + '\n' +  pwd + '\n' +  date

to_addr = argvs[1]
print 'Notify to %s.' % to_addr
print 'Subject: ' + subject
print body

# メールの送信
from sendgmail import *
sg = sendGmail('utf-8', subject, body, 'xxx@gmail.com', to_addr, 'xxx@gmail.com', 'passwd')
sg.sendMail()

最後から2番目の行の'xxx@gmail.com'と'passwd'には,送信に用いるGmailのアドレス,ユーザ名,パスワードをあらかじめ書いておく.

send_notify.pyの使い方は,

$ python send_notify.py to_addr@xxx.xx test "send notification, thank you."

というふうに,送信先アドレス,件名,本文の順に引数として渡します.

送信先アドレスだけ必須.

これを実行すると,

  • 宛先: to_addr@xxx.xx
  • 件名: [Nortification] test 01/31/12-13:19:10
  • 送信元: xxx@gmail.com
  • 本文:

send notification, thank you.

From hostname.com

/dev/pts/12

/hoge/users/dir1/dir2

01/31/12-13:19:10

というメールが来ます.

本文は

  • 1行目: 3番目の引数(ない場合は改行のみ)
  • 2行目: 送信元サーバのホストネーム
  • 3行目: 端末の名前
  • 4行目: 送信元のカレントディレクトリ
  • 5行目: 現在時間

という構成になっている.

commands.pyを使うとシェルコマンドの返り値を簡単に本文に入れられるので,けっこう便利だと思う.


Pythonはかなり素人なので,多分突っ込みどころ満載だと思う.

一応MacSnow leopard)とLinuxCentOS 5.5とUbuntu 11.10)で動作確認済み.