wxPythonでメール受信のまねごと
Pythonでメールの受信ができるようになったので、wxPythonを使ってWindowで表示できるようにしてみた。windowで表示されるとメールアプリケーションらしくなるので不思議だ。
件名をクリックしても本文は表示されない。まだ、作っていないので今後の課題。受信したメールは新しい順に並ぶようにした。「送信日時」をクリックすると、ソートできる。昇順、降順と交互に動作する。あっ、それから、ステータス枠にメッセージも表示するようにもしてみた。ということで、あいかわらずだが、メモしておくことにした。
# -*- coding:utf-8 -*-
import wx
import poplib
import email
import pykf
import time
MAIL_SVR = 'YOUR_POP3_SERVER'
MAIL_USER = 'YOUR_MAIL_ACCOUNT'
MAIL_PSWD = 'YOUR_MAI_PASSWORD'
def parse_subject(msg):
m_subject = msg.get('Subject')
d_subject, enc = email.Header.decode_header(m_subject)[0]
if enc == 'iso-2022-jp':
subject = unicode(pykf.tosjis(d_subject), 'cp932')
elif enc == None:
subject = m_subject
else:
subject = unicode(d_subject, enc)
return subject
def parse_date(msg):
m_date = msg.get('Date')
d_date = email.utils.parsedate(m_date)
return time.strftime("%Y/%m/%d %H:%M:%S",d_date)
def parse_message(msg_string):
msg = email.message_from_string(msg_string)
date = parse_date(msg)
subject = parse_subject(msg)
return date, subject
def rcvmail(tbl, mwin):
mwin.WriteMessage(u"受信を開始します")
m = poplib.POP3(MAIL_SVR)
m.user(MAIL_USER)
m.pass_(MAIL_PSWD)
mwin.WriteMessage(u"受信中です")
numMessages = len(m.list()[1])
for i in range(numMessages):
msg = '\n'.join(m.retr(i+1)[1])
date, subject = parse_message(msg)
print date, subject
tbl.Add(date, subject)
m.quit()
mwin.WriteMessage(u"受信を完了しました")
class MailTable(wx.ListCtrl):
caption = (u"送信日時",u"件名")
data = []
flg_sort = "up"
def __init__(self,parent):
wx.ListCtrl.__init__(self,parent,-1,style = wx.LC_REPORT | wx.LC_VIRTUAL)
self.InsertColumn(0, self.caption[0], width=120)
self.InsertColumn(1, self.caption[1], width=320)
self.items = self.data
#self.SetItemCount(len(self.items))
self.Bind(wx.EVT_LIST_COL_CLICK, self.Sort)
def OnGetItemText(self, line, col):
return self.items[line][col]
def Add(self,data1,data2):
self.data.insert(0,[data1,data2])
self.DeleteAllItems()
self.SetItemCount(len(self.items))
self.Update()
def Sort(self,event):
idx = event.GetColumn()
if not idx == 0:
return
if self.flg_sort == "up":
self.items.sort(lambda x,y: cmp(x[idx],y[idx]))
self.flg_sort = "down"
else:
self.items.sort(lambda y,x: cmp(x[idx],y[idx]))
self.flg_sort = "up"
self.DeleteAllItems()
self.SetItemCount(len(self.items))
class MyWindow(wx.Frame):
def __init__(self,parent,id):
wx.Frame.__init__(self,parent,id, u"メール受信",size=(450,300))
#self.SetBackgroundColour('WHITE')
self.status = self.CreateStatusBar()
ctlPnl = wx.Panel(self)
rcvBtn = wx.Button(ctlPnl, label=u"受信")
self.Bind(wx.EVT_BUTTON, self.onRcvBtn, rcvBtn)
quitBtn = wx.Button(ctlPnl, label=u"終了")
self.Bind(wx.EVT_BUTTON, self.onQuitBtn, quitBtn)
ctlSz = wx.BoxSizer()
ctlSz.Add(rcvBtn)
ctlSz.Add(quitBtn)
ctlPnl.SetSizer(ctlSz)
self.rcvTbl = MailTable(self)
sz = wx.BoxSizer(wx.VERTICAL)
sz.Add(ctlPnl, 0, wx.EXPAND)
sz.Add(self.rcvTbl, 1, wx.EXPAND)
self.SetSizer(sz)
self.Show(True)
def onRcvBtn(self, event):
rcvmail(self.rcvTbl, self)
def onQuitBtn(self, event):
self.Close()
def WriteMessage(self, msg):
self.status.SetStatusText(msg)
if __name__=='__main__':
app=wx.PySimpleApp()
frame=MyWindow(parent=None,id=-1)
app.MainLoop()
スクリプトについて
- 受信したメールがリアルタイムに表示されなかった。
- MailTblクラスのAddメッソドのなかで、Update()をしてやるとリアルタイムに表示されるようになった。似たようなメッソドでReflesh()があるが、すぐに表示はアップデートされない。参考:wx.Windows

