iCalのデータを読み込んで、メールで送信
iCalのicsファイルから今日の予定を読み込んで、メールで送信するPythonプログラムを書いてみた。
- icsファイルの取り扱い
Pythonで、icsファイルを取り扱うのに適したモジュールはないかと調べていたら、あった。
iCalendar package for Python, http://codespeak.net/icalendar/
安定版のリリースが、2006年?と思ったが、以下のようにSVNで開発版のソースを取得したらicalendar 2.2が取得できた。
You can also check out the development version of iCalendar from subversion, using a command like:
svn co http://codespeak.net/svn/iCalendar/trunk iCalendar
よく調べたら、pypiに登録されていた。http://pypi.python.org/pypi/icalendar/
こっちだと、githubにソースコードがあった。http://github.com/collective/icalendar
Python2.7で、icalendar 3.0を使ってみたが、最終的に動作させる環境がFreeBSDなので、
portsにicalendarのパッケージがあったが、バージョンが2.1だったので
ひとまず、バージョン2.2でプログラムを組むことにした。
icsファイルに記述されたデータを表示する例。
from icalendar import Calendar from date time import datetime cal = Calendar.from_string(open('schedule.ics', rb').read()) body = "" for ev in cal.walk(): if ev.name == 'VEVENT': start_dt = ev.decoded("dtstart") end_dt = ev.decoded("dtend") summary = ev['summary'].encode('utf-8') print "{start} - {end} : {summary}".format(start=start_dt.strftime("%Y/%m/%d %H:%M"), end=end_dt.strftime("%Y/%m/%d %H:%M"), summary=summary) # body = "{start} - {end} : {summary}".format(start=start_dt.strftime("%Y/%m/%d %H:%M"), end=end_dt.strftime("%Y/%m/%d %H:%M"), summary=summary)
- メールで送信
icalendarモジュールで取り出した今日の予定をメールで送信する。
import smtplib from email.MIMEText import MIMEText from email.Utils import formatdate from email.Header import Header encoding = 'ISO-2022-JP' msg = MIMEText(body.encode(encoding), 'plain', encoding) # bodyはicsファイルから取得したスケジュールの文字列 msg['Subject'] = Header(u'本日の予定', encoding) msg['From'] = 'Hoge<hoge@example.com>' msg['To'] = 'dummy@example.com' msg['Date'] = formatdate() from_addr = 'huge@example.com' to_addr = ['dummy@example.com'] send(from_addr, to_addr, msg)
UTF-8で文字列が格納されているbodyを、MIMETextの第一引数として渡すが、
このとき、UTF-8からISO-2022-JPへencodeしてやらないと、
SubjectはISO-2022-JP、本文はUTF-8ととなり、本文だけ文字化けして読めないという悲しい状況に陥る。
(ぐぐって、参考にしたサイトで変更していないものもあった...)
- HTTP+Basic認証
icsファイルを、WebDavサーバ上に置いている。
スケジュールなので、一応Basic認証をかけている。
urllib2モジュールで、icsファイルを取得する処理は以下の通り。
import urllib2 passman = urllib2.HTTPPasswordMgrWithDefaultRealm() passman.add_password(None, 'webserver_no_FQDN', 'username', 'password') auth_handler = urllib2.HTTPBasicAuthHandler(passman) opener = urllib2.build_opener(auth_handler) urllib2.install_opener(opener) url = "http://example.com/dav/schedule.ics" r = urllib2.urlopen(url) tmp_file = open('/tmp/schedule.ics', 'w') tmp_file.write(r.read()) tmp_file.close()
- UTF-8での文字列処理
スクリプトの文字コードをUTF-8にしたり、スクリプトの最初に #-*- coding: utf-8 -*-と記述しても、
実行すると、以下のようにUTF-8の処理で引っかかる。
techman999@minako:~/dev/git/pyical$ python today_schedule.py File "today_schedule.py", line 40 SyntaxError: Non-ASCII character '\xe5' in file today_schedule.py on line 40, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
結論としては、/usr/lib/python2.6/sitecustomize.py を以下のように追記して対処した。
import sys sys.setdefaultencoding("utf-8")
こんな感じで、トータル4時間で完成。
たまには、お遊びプログラム書いていかないとね:p