wxpython制作eml文件阅读器
处理eml文件,一般windows下会启用默认的outlook来阅读,实际上python的email模块可以很简单的实现对eml文件的阅读,闲来木事,利用wxpython制作了一个eml文件阅读器,实现了对eml文件正文的阅读和附件的阅读,但由于制作时,在信头读取部分使用了label,在格式处理时未处理好,当信件有多个收件人时,会出现格式混乱。另外,附件如果有多个,只会显示最后一个。哪位感兴趣或者有时间可以自己改一下。
一、email模块对eml文件的读取
首先先来看一个邮件的源文件:
Received: from 192.168.208.56 ( 192.168.208.56 [192.168.208.56] ) by
ajax-webmail-wmsvr37 (Coremail) ; Thu, 12 Apr 2007 12:07:48 +0800 (CST)
Date: Thu, 12 Apr 2007 12:07:48 +0800 (CST)
From: user1 <xxxxxxxx@163.com>
To: user2 <YYYY@163.com>
Message-ID: <31571419.200911176350868321.JavaMail.root@bj163app37.163.com>
Subject: =?gbk?B?u+nJtA==?=
MIME-Version: 1.0
Content-Type: multipart/Alternative;
boundary="----=_Part_21696_28113972.1176350868319"
------=_Part_21696_28113972.1176350868319
Content-Type: text/plain; charset=gbk
Content-Transfer-Encoding: base64
ztLS0b+qyrzS1M6qysfSu7j20MfG2ru70ru0zqOs1K3AtMrH0ru49tTCtffSu7TOztLDx8/W1NrT
prjDysew67XjssXE3MjI1ebC6bezICAg
------=_Part_21696_28113972.1176350868319
Content-Type: text/html; charset=gbk
Content-Transfer-Encoding: quoted-printable
<DIV>=CE=D2=D2=D1=BF=AA=CA=BC=D2=D4=CE=AA=CA=C7=D2=BB=B8=F6=D0=C7=C6=DA=BB=
=BB=D2=BB=B4=CE=A3=AC=D4=AD=C0=B4=CA=C7=D2=BB=B8=F6=D4=C2=B5=F7=D2=BB=B4=CE=
</DIV>
<DIV>=CE=D2=C3=C7=CF=D6=D4=DA=D3=A6=B8=C3=CA=C7=B0=EB=B5=E3=B2=C5=C4=DC=C8=
=C8</DIV>
<DIV>=D5=E6=C2=E9=B7=B3</DIV>
------=_Part_21696_28113972.1176350868319--
从第一行到第一个空行之间的为信件头,后面的是信件体。通过outlook解码后,正文显示为:
我已开始以为是一个星期换一次,原来是一个月调一次
我们现在应该是半点才能热
真麻烦
下面,具体来看看email模块的使用。
(1)打开eml文件,利用open语句,具体与打开其它文件一样,如fileopen=open('AAA.eml','r')。
(2)email.message_from_file()创建message对象,此时会对fileopen内容进行初步解码。如msg = email.message_from_file(fileopen)
(3)获取信件主题subject = msg.get("subject"),此时主题中含有 =?gbk?B?u+nJtA==?=这样的编码,以下代码用来解码
h = email.Header.Header(subject)
dh = email.Header.decode_header(h)
subject = dh[0][0]
解码后,正常显示为“婚纱”
(4)解析发件人和收件人,发件人往往只有一个,所以可以直接用efrom=email.utils.parseaddr(msg.get("from"))[1]进行解析,收件人有时会有多个,可得用以下代码:
for tolines in msg.get("to").splitlines():
findst=tolines.find('<') #从to中找<位置
if findst==-1:#判断是否只有一个收件人,当tolines中不含有'<'时,只存在一个收件人eto=email.utils.parseaddr(msg.get("to"))[1]
else:eto=eto+tolines[findst:]+'\n'
(5)解析时间,etime=msg.get("date"),显示时间格式为Thu, 12 Apr 2007 12:07:48 +0800 (CST),这里可以再根据需要转换为2007年4月12日星期四 12:07。
(6)解析正文和附件,代码如下:
for bodycheck in msg.walk():if not bodycheck.is_multipart(): psname = bodycheck.get_param("name") if psname: psh = email.Header.Header(psname) psdh = email.Header.decode_header(psh) psfname = psdh[0][0] data = bodycheck.get_payload(decode=True) try: f = open(psfname, 'wb')except:# f = open('tempps', 'wb') f.write(data) f.close()else: data=bodycheck.get_payload(decode=True) p=str(data)
这里,邮件正文保存为p,str类型,附件文件名为psfname,并将附件保存在当前文件+下面。如果有多个附件都会保存在这里。
(7)关闭文件fp.close()
二、wxpython制作GUI
(1)self.staticText1、self.textCtrl1、self.button1三个控件完成对eml文件的选取。点击self.button1后,利用wxfiledialog调取文件选择框,限定wildcard = "note source (*.eml)|*.eml",由于路径有时会出现中文错误,所以使用了encode('utf-8')进行编码。
def OnButton1Button(self, event): #浏览dialog = wx.FileDialog(None, "Choose a file", os.getcwd(),"", wildcard, wx.OPEN)if dialog.ShowModal() == wx.ID_OK:aa=dialog.GetPath().encode('utf-8')self.textCtrl1.SetValue(aa.decode('utf-8'))self.reademail()dialog.Destroy()event.Skip()
(2)利用self.htmlWindow1显示邮件正文。邮件正文读取后一般都是html代码,通过htmlWindow1进行正常显示。
(3)实现邮件的另存为txt。邮件另存为txt时,遇到的主要问题是如何将html代码转换为带格式的txt文档,于是利用了正则和字符串的替换,替换为\n换行,然后又去掉了多余的换行,具体代码如下:
def savetotxt(self,filena):#邮件另存为txt文件 resultfile='' read=file('temps').read() readf_con=read.replace(' ','\n') readf_con=readf_con.replace('»','\n') readf_con=re.sub("<!--.+?-->",'\n',readf_con) readf_con=re.sub("<.*?>",'\n',readf_con) readf_con=re.sub('\n+','\n',readf_con)for tt in readf_con.splitlines(): tt=tt.rstrip()+'\n' resultfile=resultfile+tt #去除temps文件中多余的空行 w=open(filena,'w') w.write(resultfile) w.close()
目前该代码存在的主要问题是:
1、收件人很多时,窗口格式会发生错乱
2、附件有多个时,只能显示一个
3、eml另存为时,附件只能保存最后一个
有兴趣的朋友可以自行修改一下。
完整代码如下:
#-*- encoding: gb2312 -*-'''eml阅读器 V1.0小五义:http://www.cnblogs.com/xiaowuyi仍然存在问题:1、收件人很多时,窗口格式会发生错乱2、附件有多个时,只能显示一个3、eml另存为时,附件只能保存一个''' import wximport wx.htmlimport osimport emailimport reimport shutil wildcard = "note source (*.eml)|*.eml"psfname='无' #附件名 def create(parent):return Frame1(parent) [wxID_FRAME1, wxID_FRAME1BUTTON1, wxID_FRAME1PANEL1, wxID_FRAME1STATICTEXT1, wxID_FRAME1STATICLINE1, wxID_FRAME1STATICTEXT2, wxID_FRAME1STATICTEXT3,wxID_FRAME1TEXTCTRL1, wxID_FRAME1HTMLWINDOW1,wxID_FRAME1BUTTON2] = [wx.NewId() for _init_ctrls in range(10)] class Frame1(wx.Frame):def _init_ctrls(self, prnt): wx.Frame.__init__(self, id=wxID_FRAME1, name='', parent=prnt, pos=wx.Point(269, 142), size=wx.Size(899, 599), style=wx.DEFAULT_FRAME_STYLE, title='Eml文件阅读器 V1.0') self.SetClientSize(wx.Size(891, 565)) self.Enable(True) self.SetIcon(wx.Icon(u'mb_4.ico', wx.BITMAP_TYPE_ICO)) #当前目录下放一个名为mb_4.ico的文件做图标 self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1', parent=self, pos=wx.Point(0, 0), size=wx.Size(891, 565), style=wx.TAB_TRAVERSAL) self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1, name='textCtrl1', parent=self.panel1, pos=wx.Point(120, 16), size=wx.Size(632, 23), style=0, value=u'') self.textCtrl1.SetEditable(False) self.button1 = wx.Button(id=wxID_FRAME1BUTTON1, label=u'浏览', name='button1', parent=self.panel1, pos=wx.Point(776, 16), size=wx.Size(75, 23), style=0) self.button1.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False, u'Tahoma')) self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button, id=wxID_FRAME1BUTTON1) self.staticText1 = wx.StaticText(id=wxID_FRAME1STATICTEXT1, label=u'文件名:', name='staticText1', parent=self.panel1, pos=wx.Point(45, 16), size=wx.Size(56, 23), style=0) self.staticText1.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False, u'Tahoma')) self.htmlWindow1 = wx.html.HtmlWindow(id=wxID_FRAME1HTMLWINDOW1, name='htmlWindow1', parent=self.panel1, pos=wx.Point(72, 186), size=wx.Size(747, 300), style=wx.html.HW_SCROLLBAR_AUTO|wx.DOUBLE_BORDER) self.staticText2 = wx.StaticText(id=wxID_FRAME1STATICTEXT2, label=u' 发件人:\n 日 期:\n 收件人:\n 主 题:\n', name='staticText2', parent=self.panel1, pos=wx.Point(72, 80), size=wx.Size(747, 90), style=wx.html.HW_SCROLLBAR_AUTO) self.staticText2.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False, u'Tahoma')) self.staticText3 = wx.StaticText(id=wxID_FRAME1STATICTEXT3, label=u' 附 件:', name='staticText3', parent=self.panel1, pos=wx.Point(72, 496), size=wx.Size(680, 14), style=0) self.staticText3.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False, u'Tahoma')) self.staticLine1 = wx.StaticLine(id=wxID_FRAME1STATICLINE1, name='staticLine1', parent=self.panel1, pos=wx.Point(0, 55), size=wx.Size(891, 2), style=0) self.button2 = wx.Button(id=wxID_FRAME1BUTTON2, label=u'导出', name='button2', parent=self.panel1, pos=wx.Point(776, 496), size=wx.Size(75, 23), style=0) self.button2.SetFont(wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False, u'Tahoma')) self.button2.Bind(wx.EVT_BUTTON, self.OnButton2Button, id=wxID_FRAME1BUTTON2) def __init__(self, parent): self._init_ctrls(parent) def reademail(self):#read email global psfname checkfile=True p='' #记录邮件html正文 txtemail=''#记录邮件txt正文 eto='' filename=self.textCtrl1.GetValue()try: emailfile=open(filename,'rb') msg=email.message_from_file(emailfile) subject=msg.get('subject') head=email.Header.Header(subject) dhead=email.Header.decode_header(head) subject=dhead[0][0] efrom=email.utils.parseaddr(msg.get("from"))[1] etime=msg.get("date")#判断收件人个数 print msg.get("to")for tolines in msg.get("to").splitlines(): findst=tolines.find('<') #从to中找<位置 if findst==-1: eto=email.utils.parseaddr(msg.get("to"))[1]else: eto=eto+tolines[findst:]+'\n' #eto=email.utils.parseaddr(msg.get("to"))[1] ehead=' 发件人:'+efrom+'\n'+' 日 期:'+etime+'\n'+' 收件人:'+eto+'\n'+' 主 题:'+subject+'\n' for bodycheck in msg.walk():if not bodycheck.is_multipart(): psname = bodycheck.get_param("name") if psname: psh = email.Header.Header(psname) psdh = email.Header.decode_header(psh) psfname = psdh[0][0] data = bodycheck.get_payload(decode=True) try: f = open(psfname, 'wb')except:# f = open('tempps', 'wb') f.write(data) f.close()else: data=bodycheck.get_payload(decode=True) p=str(data) emailend=ehead self.staticText2.SetLabel(emailend) self.staticText3.SetLabel(' 附 件:'+psfname) self.htmlWindow1.SetPage(p) txtemail=emailend+'正文:'+p checkfile=Falseexcept: tishi='文件'+'格式错误!' wx.MessageBox(tishi,'注意',wx.OK) tem=open('temps','w') # 临时文件存放 lamp='<DIV>'+txtemail+'</DIV><DIV>'+' 附 件:'+psfname lamp=lamp.replace('\n','</DIV><DIV>') tem.write(lamp) tem.close() def OnButton1Button(self, event): #浏览 dialog = wx.FileDialog(None, "Choose a file", os.getcwd(),"", wildcard, wx.OPEN)if dialog.ShowModal() == wx.ID_OK: aa=dialog.GetPath().encode('utf-8') self.textCtrl1.SetValue(aa.decode('utf-8')) self.reademail() dialog.Destroy() event.Skip() def savetotxt(self,filena):#邮件另存为txt文件 resultfile='' read=file('temps').read() readf_con=read.replace(' ','\n') readf_con=readf_con.replace('»','\n') readf_con=re.sub("<!--.+?-->",'\n',readf_con) readf_con=re.sub("<.*?>",'\n',readf_con) readf_con=re.sub('\n+','\n',readf_con)for tt in readf_con.splitlines(): tt=tt.rstrip()+'\n' resultfile=resultfile+tt #去除temps文件中多余的空行 w=open(filena,'w') w.write(resultfile) w.close() def OnButton2Button(self, event):#eml另存为 wid = "text file (*.txt)|*.txt" savedialog = wx.FileDialog(None, "Choose a file", os.getcwd(),"", wid, wx.SAVE)if savedialog.ShowModal() == wx.ID_OK: fil=savedialog.GetPath().encode('utf-8') savef=fil.decode('utf-8') savedialog.Destroy() savep=os.path.dirname(savef) #将附件另存到该目录下 checkdot=psfname.find('.')if checkdot!= -1:#判断是否存在附件 kzhname='ps'+psfname[checkdot:] psfile=os.path.join(savep,kzhname) shutil.copy(psfname, psfile) self.savetotxt(savef)#存eml正文 event.Skip() class App(wx.App):def OnInit(self): self.main=create(None) self.main.Show() self.SetTopWindow(self.main)return Truedef main(): application=App(0) application.MainLoop() if __name__=='__main__': main()
转载于:https://www.cnblogs.com/xiaowuyi/archive/2012/04/05/2432862.html
wxpython制作eml文件阅读器相关推荐
- wxpython制作桌面悬浮球
介绍 使用wxpython制作一个类似于电脑管家一样的悬浮球. 功能 圆形窗口 自动鼠标离开悬浮球自动贴边 鼠标在悬浮球上自动弹出整个悬浮球 效果 代码 import wxclass myframe( ...
- monkey开源工具Linux,wxPython制作跑monkey工具(Python3)
一. wxPython制作跑monkey工具python文件源代码内容Run Monkey.py如下: #!/usr/bin/env python import wx import os import ...
- wxpython制作表格界面_wxpython入门第二步(布局)
一个典型的应用程序由各种小组件组成.这些组件被放置在容器里面.程序员必须管理应用程序的布局.在 wxPython 中,可以使用绝对定位或使用 sizer 来布局小组件. 绝对定位 程序员以像素为单位指 ...
- wxpython制作表格界面_[Python] wxPython 菜单栏控件学习总结(原创)
1.总结 1.大体创建过程 1.创建一个 菜单栏 : menuBar = wx.MenuBar() 相当于这个白色地方,没有File这个菜单 2.创建 菜单 : fileMenu = wx.Menu( ...
- wxpython制作表格界面_Python wxPython库使用wx.ListBox创建列表框示例
本文实例讲述了Python wxPython库使用wx.ListBox创建列表框.分享给大家供大家参考,具体如下: 如何创建一个列表框? 列表框是提供给用户选择的另一机制.选项被放置在一个矩形的窗口中 ...
- wxpython制作excel表格_怎么做一个精美的excel表格
你还在制作平平无奇的表格吗,是时候做出改变啦.下面为你展示了详细的操作步骤,看完之后就再也不要做普通的表格了,尝试着设计更多的样式来为你的表格添彩吧!一起看下去吧! 制作步骤: 1.整理表格 把字体设 ...
- wxpython制作金山快盘自动签到程序
首先感谢龙昌在http://www.oschina.net/code/snippet_93572_10721发布的金山快盘自动签到程序代码,本人在此基础上,利用wxpython做了一个程序,具体代码如 ...
- wxpython制作抽奖页面
目录 杂话(解释) 全代码 上才艺. 最近需要编写一个抽奖的小玩意,但是查了一下网上使用wxpython的方法似乎不是很多,遂自己研究了一下. 杂话(解释) 以下是需要用到的一些库 import im ...
- 用wxpython 制作出入库 进销存 ERP 仓库管理系统 可导出Excel
借鉴 crazeblade 开发 新增查询库存 登录页面 类别 物品出入库 流水账 报表功能 导出Excel 新增物品库存查询 学习交流QQ 1270879157
最新文章
- android 动画x轴旋转,Android Roate3dAnimation实现围绕y轴竖直方向或者绕x轴方向旋转的3d动画效果...
- svg图片怎么存手机上_一张普通的图片,是怎么让安卓手机死机的?
- java获取年初年末_Java用于取得当前日期相对应的月初,月末,季初,季末,年初,年末时间...
- PHP的抽象类的一段简单代码示例
- SpringIOC容器中Bean的生命周期
- 人的一生能交多少朋友?
- Teleport 开源堡垒机的使用
- bean交个spring和new比较区别
- python中怎么精确20位_Python中的精确处理
- iOS开发 - 抛出异常
- 232 Crossword Answers
- 计算机联锁系统硬件结构,计算机联锁系统各部硬件.ppt
- mac安装旺旺启动台找不到_送修Mac前 万能的两个自救方法:重置 NVRAM(PRAM)与 重置 SMC...
- matlab图片测量尺寸_matlab尺寸测量
- 小米摄像头结合samba共享存储实现视频实时转存
- 学习July博文总结——支持向量机(SVM)的深入理解(下)
- 魔方机器人大赛——魔方步骤转换算法
- c语言上交源代码怎么交啊,C语言问题在线等啊作业提交上交的的内容必须由以下两个部分组成,缺 爱问知识人...
- 【大咖专栏】如何配置CEPH RGW对象存储与公有云同步
- 并发------多线程安全
热门文章
- Pytorch Note1 Pytorch介绍
- threeJs 入门篇
- pg数据库json数据类型_科学网—如何使用PostgreSQL中的JSONB数据类型(PG JSON系列2) - 孙鹏的博文...
- 说说 Spring Bean 的实例化过程?面试必问
- python定义一个复数类complex、内有两个成员变量_python应用(5):变量类型与数据结构...
- IDEA使用EasyCode一键生成CURD
- 百度编辑器上传失败问题--转码问题mb_convert_encoding与iconv
- 一、微信小程序集成Vant Weapp
- 全志V3S嵌入式驱动开发(看原理图)
- typescript往window挂载属性