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