2019独角兽企业重金招聘Python工程师标准>>>

开发环境:centos7

基于:python3.5

调用库:tkinter smtplib email

linux中类outlook的GUI界面邮件发送程序,可以带附件,解决了windows中outlook不能添加linux中附件的问题。

当然有很多其他现成的程序可以实现类似的功能,本程序主要是基于练习使用python图形界面和smtplib/email库的目的。

mailSender.py

#!/usr/local/bin/python3.5  -u

import os
import re
from tkinter import *
from tkinter import messagebox
import smtplib
import email.mime.multipart
import email.mime.text

titleBarName = 'mailSender'

class sendMail:
    def __init__(self):
        self.smtp = smtplib.SMTP()
        self.msg = email.mime.multipart.MIMEMultipart()
        self.defaultEmailServerName = '163'

# Get the email you want to login.
    def getEmailFrom(self, emailAddress):
        self.emailAddress = emailAddress

# Get the password of the login email.
    def getEmailPassword(self, password):
        self.emailPassword = password

# Connect the smtp server, you can get the smtp server from the email.
    def smtpConnect(self):
        fromMatch = re.match('.*@(.*).com', self.emailAddress)
        self.smtpServerName = fromMatch.group(1)
        self.smtpServer = 'smtp.' + str(self.smtpServerName) + '.com'
        self.defaultEmailServerName = self.smtpServerName
        try:
            self.smtp.connect(self.smtpServer)
            self.smtp.ehlo()
            print('*Info*: Connect to ' + str(self.smtpServer) + ' pass!')
            return 0
        except Exception as e:
            print('*Error*: Failed to connect email server ' + self.smtpServer + ', ' + str(e))
            messagebox.showerror(titleBarName, '*Error*: Failed to connect email server ' + self.smtpServer + ', ' + str(e))
            return 1

# Login the smtp server, but notice that there is no need to login outlook email server.
    def smtpLogin(self):
        try:
            self.smtp.login(self.emailAddress, self.emailPassword)
            print('*Info*: login ' + str(self.emailAddress) + ' pass!')
            return 0
        except Exception as e:
            print('*Error*: Failed to login smtp server ' + object.smtpServer + ', ' + str(e))
            messagebox.showerror(titleBarName, '*Error*: Failed to login smtp server ' + object.smtpServer + ', ' + str(e))
            return 1

# Specify the email receiver, the parameter "to" must be a string
    def getEmailTo(self, to):
        self.toString = ''
        self.toList = []
        for receiver in to.split():
            if not re.match('.*@.*.com', receiver):
                receiver = receiver + '@' + self.defaultEmailServerName + '.com'
            self.toList.append(receiver)
            if self.toString == '':
                self.toString = receiver
            else:
                self.toString = self.toString + ' ' + receiver

# Subject is the email subject, it must be a string
    def getEmailSubject(self, subject):
        self.subject = subject

# Specify the email attach files, it must be a list
    def getEmailAttach(self, attachFiles):
        self.attachFiles = attachFiles

# Specify the email content
    def getMsgContent(self, content):
        self.content= email.mime.text.MIMEText(content)
        self.msg.attach(self.content)

# Use MIMEText to add attach file
    def msgAttach(self, attachFile):
        attachFileName = os.path.basename(attachFile)
        self.attach = email.mime.text.MIMEText(open(attachFile, 'rb').read(), 'base64', 'gb2312')
        self.attach["Content-Type"] = 'application/octet-stream'
        self.attach["Content-Disposition"] = 'attachment; filename="' + attachFileName + '"'
        self.msg.attach(self.attach)

# It must specify "From", "To" and "Subject"
    def msgConfig(self):
        self.msg['From'] = self.emailAddress
        print('*Info*: From    : ' + self.msg['From'])
        self.msg['To'] = self.toString
        print('*Info*: To      : ' + self.msg['To'])
        self.msg['Subject'] = self.subject
        print('*Info*: Subject : ' + self.msg['Subject'])

# For the email attach files, attach them one by one
    def msgAttachs(self):
        for attachFile in self.attachFiles:
            if not re.match('^[ ]*$', attachFile):
                self.msgAttach(attachFile)

# Quit the smtp connection
    def smtpQuit(self):
        print('*Info*: quit smtp connection.')
        self.smtp.quit()

# Send mail
    def smtpSendMail(self):
        self.msgConfig()
        self.msgAttachs()
        try:
            self.smtp.sendmail(self.emailAddress, self.toList, self.msg.as_string())
            print('*Info*: Send email to ' + str(self.toString) + ' pass!')
            messagebox.showinfo(titleBarName, 'Send email pass!')
            return 0
        except Exception as e:
            print('*Error*: Failed to send email, ' + str(e))
            messagebox.showerror(titleBarName, '*Error*: Failed to send email, ' + str(e))
            return 1

class loginEmailGUI(object):
    def __init__(self, object):
        self.root = Tk()
        self.root.geometry('800x600+200+200')
        self.root.title(titleBarName)

# Label, "Email:"
        self.emailAddressLabel = Label(self.root, text='Email:')
        self.emailAddressLabel.grid(row=1, column=1, sticky=W, ipadx=20, ipady=10)

# Label, "Password:"
        self.passwordLabel = Label(self.root, text='Password:')
        self.passwordLabel.grid(row=2, column=1, sticky=W, ipadx=20, ipady=10)

# Entry, for "Email:", save the content on variable self.emailAddressEntryVar
        self.emailAddressEntryVar = StringVar()
        self.emailAddressEntry = Entry(self.root, textvariable=self.emailAddressEntryVar, bg='white')
        self.emailAddressEntry.grid(row=1, column=2, sticky=W, ipadx=250, ipady=10)

# Entry, for "Password:", save the content on variable self.passwordEntryVar
        self.passwordEntryVar = StringVar()
        self.passwordEntry = Entry(self.root, textvariable=self.passwordEntryVar, show='*', bg='white')
        self.passwordEntry.grid(row=2, column=2, sticky=W, ipadx=250, ipady=10)

# Button, "Login", click it to click the email server and login
        self.loginButton = Button(self.root, text='Login', command=self.loginEmail, bg='blue')
        self.loginButton.grid(row=3, column=2, ipadx=50, ipady=10)

self.root.mainloop()

# call class senMail to connet email server and login.
    def loginEmail(self):
        if re.match('^[ ]*$', self.emailAddressEntryVar.get().strip()):
            print('*Error*: Email address cannot be empty!')
            messagebox.showerror(titleBarName, '*Error*: Email address cannot be empty!')
            return 1
        elif not re.match('.*@.*.com', self.emailAddressEntryVar.get().strip()):
            print('*Error*: Email format is wrong, it must be "***@***.com".')
            messagebox.showerror(titleBarName, '*Error*: Email format is wrong, it must be "***@***.com".')
            return 1
        elif re.match('^[ ]*$', self.passwordEntryVar.get().strip()):
            print('*Error*: Email password cannot be empty!')
            messagebox.showerror(titleBarName, '*Error*: Email password cannot be empty!')
            return 1
        else:
            object.getEmailFrom(self.emailAddressEntryVar.get().strip())
            object.getEmailPassword(self.passwordEntryVar.get().strip())
            if not object.smtpConnect():
                if not object.smtpLogin():
                    object.smtpQuit()
                    self.root.destroy()
                    return 0
                else:
                    object.smtpQuit()
                    return 1
            else:
                object.smtpQuit()
                return 1

class sendEmailGUI(object):
    def __init__(self, object):
        self.root = Tk()
        self.root.geometry('800x600+200+200')
        self.root.title(titleBarName)

# Button, "Send", click it to execut sendMail.sendMail to send email
        self.sendButton = Button(self.root, text='Send', command=self.sendMail, bg='blue')
        self.sendButton.grid(row=1, rowspan=4, column=1, sticky=W, ipadx=10, ipady=50, padx=5, pady=5)

# Label, "From:"
        self.fromLabel = Label(self.root, text='From:')
        self.fromLabel.grid(row=1, column=2, sticky=W, ipadx=20, ipady=10)

# Label, "To:"
        self.toLabel = Label(self.root, text='To:')
        self.toLabel.grid(row=2, column=2, sticky=W, ipadx=20, ipady=10)

# Label, "Subject:"
        self.subjectLabel = Label(self.root, text='Subject:')
        self.subjectLabel.grid(row=3, column=2, sticky=W, ipadx=20, ipady=10)

# Label, "Attach:"
        self.attachLabel = Label(self.root, text='Attach:')
        self.attachLabel.grid(row=4, column=2, sticky=W, ipadx=20, ipady=10)

# Entry, for "From:", email address is saved on variable self.fromEntryVar, the default value is the email you login, but you can re-specify it.
        self.fromEntryVar = StringVar()
        self.fromEntry = Entry(self.root, textvariable=self.fromEntryVar, bg='white')
        self.fromEntry.grid(row=1, column=3, sticky=W, ipadx=215, ipady=10)
        self.fromEntryVar.set(object.emailAddress)

# Entry, for "To:", receiver list is saved on variable self.toEntryVar, you can specify several receivers, split them with space.
        self.toEntryVar = StringVar()
        self.toEntry = Entry(self.root, textvariable=self.toEntryVar, bg='white')
        self.toEntry.grid(row=2, column=3, sticky=W, ipadx=215, ipady=10)

# Entry, from "Subject:", subject is saved on variable self.subjectEntryVar, it is the email title.
        self.subjectEntryVar = StringVar()
        self.subjectEntry = Entry(self.root, textvariable=self.subjectEntryVar, bg='white')
        self.subjectEntry.grid(row=3, column=3, sticky=W, ipadx=215, ipady=10)

# Entry, from "Attach:", attach file list is saved on variable self.attachEntryVar, split them with space.
        self.attachEntryVar = StringVar()
        self.attachEntry = Entry(self.root, textvariable=self.attachEntryVar, bg='white')
        self.attachEntry.grid(row=4, column=3, sticky=W, ipadx=215, ipady=10)

# Email content, get the content with self.contentText.get().
        self.contentText = Text(self.root, bg='white')
        self.contentText.grid(row=5, column=1, columnspan=3, sticky=W, ipadx=108, ipady=46)
 
        # scrll bar
        self.contentTextSbY = Scrollbar(self.root)
        self.contentTextSbY.grid(row=5, column=4, sticky=W, ipadx=2, ipady=197)
        self.contentText.configure(yscrollcommand=self.contentTextSbY.set)
        self.contentTextSbY.configure(command=self.contentText.yview)

self.root.mainloop()

# Split receiver list to a list
    # Split attach file list to a list
    # Send email with sendMail.smtpSendMail
    def sendMail(self):
        # There must be at least one email receiver
        if re.match('^[ ]*$', self.fromEntryVar.get().strip()):
            print('*Error*: Email address cannot be empty!')
            messagebox.showerror(titleBarName, '*Error*: Email address cannot be empty!')
            return 1
        # Check email format, it must be '.*@.*.com'
        elif not re.match('.*@.*.com', self.fromEntryVar.get().strip()):
            print('*Error*: Email format is wrong, it must be "***@***.com".')
            messagebox.showerror(titleBarName, '*Error*: Email format is wrong, it must be "***@***.com".')
            return 1
        # Should not change the email from setting.
        elif self.fromEntryVar.get().strip() != object.emailAddress:
            print('*Error*: The send email is changed from "' + object.emailAddress + '" to "' + self.fromEntryVar.get().strip() + '", it may cause sending mail fail!')
            messagebox.showerror(titleBarName, '*Error*: The send email is changed from "' + object.emailAddress + '" to "' + self.fromEntryVar.get().strip() + '", it may cause sending mail fail!')
            return 1
        # There must be at least one email receiver
        elif re.match('^[ ]*$', self.toEntryVar.get().strip()):
            print('*Error*: Email receiver list cannot be empty, you must specify at least one receiver!')
            messagebox.showerror(titleBarName, '*Error*: Email receiver list cannot be empty, you must specify at least one receiver!')
            return 1
        # There must be email title
        elif re.match('^[ ]*$', self.subjectEntryVar.get().strip()):
            print('*Error*: Email subject cannot be empty!')
            messagebox.showerror(titleBarName, '*Error*: Email subject cannot be empty!')
            return 1
        else:
            object.getEmailFrom(self.fromEntryVar.get().strip())
            object.getEmailTo(self.toEntryVar.get().strip())
            object.getEmailSubject(self.subjectEntryVar.get().strip())
            # If there is not attach file, set attachNewList first element to ' ', so sendMail will not attach any file.
            attachList = self.attachEntryVar.get().strip()
            attachNewList = []
            if re.match('^[ ]*$', attachList):
                attachNewList.append(' ')
            else:
                for attach in attachList.split():
                    if os.path.exists(attach):
                        attachNewList.append(attach)
                    else:
                        print('*Error*: ' + attach + ': No such file!')
                        messagebox.showerror(titleBarName, '*Error*: ' + attach + ': No such file!')
                        return 1
            object.getEmailAttach(attachNewList)
            # If email content is empty, set variable content to ' ', so sendMail will send an empty email.
            content = self.contentText.get(1.0, END).strip()
            if re.match('^[ ]*$', content):
                content = ' '
            object.getMsgContent(content)
            # Call sendMail.sendMail to send email.
            if not object.smtpConnect():
                if not object.smtpLogin():
                    if not object.smtpSendMail():
                        object.smtpQuit()
                        self.root.destroy()
                        return 0
                    else:    
                        object.smtpQuit()
                        return 1
                else:
                    object.smtpQuit()
                    return 1
            else:    
                object.smtpQuit()
                return 1

def main():
    object=sendMail()
    if loginEmailGUI(object):
        sendEmailGUI(object)

###################
## Main Function ##
###################
if __name__ == '__main__':
    main()

实际使用如下图demo所示:

1. 登陆自己邮箱,输入帐号密码。

2. 输入相关内容,发件人,收件人,标题,附件地址,邮件内容。

3. 点击发送。

4. 去收件邮箱验证。

请注意这种使用方式主要是用于个人邮箱,比如163邮箱。如果想用自己outlook邮箱帐号来发送邮件,程序需要修改,因为outlook邮箱的协议和配置与我们常用的个人邮箱不太一样。

转载于:https://my.oschina.net/liyanqing/blog/789407

基于python的图形化邮件发送程序(支持添加附件)相关推荐

  1. 邮件发送程序(添加附件发送)

    目标:实现一个基于Web的可以发送附件的邮件程序.(涉及的知识点:文件上传+邮件发送) 知识点引入: 文件上传:开发的Web应用是基于HTTP协议的,工作在Request/Response模式下.在这 ...

  2. 基于python的毕业论文邮箱收发系统_基于python语言的自动化邮件发送总结

    发邮件功能 有很多种,我目前 使用的是python的smptlib 模块提供的发邮件功能,可以使用里面的SMTP对象的sendmail方法发邮件. # -*- coding: utf-8 -*- '' ...

  3. python最强实训程序(增删改查)机房收费管理系统-基于tkinter的图形化界面(附详细代码)

    python最强实训程序(增删改查)机房收费管理系统-基于tkinter的图形化界面(附详细代码) 最近学校实训,用两天时间做了一个python小程序*机房收费管理系统*,一款基于tkinter使用p ...

  4. 麦昆mciro:bit开发板机器人小车——支持makecode图形化编程,支持基于Mind+的图形化编程及python编程

    麦昆4.0中文版 随着时代发展的趋势,以及各个政策的出台,市场上的机器人兴趣班.编程兴趣班越来越火爆,编程课也慢慢走进了学校的课堂.但是作为工薪阶层的普通家庭来说连续数年的学习一定有很大的经济压力.所 ...

  5. 基于PyQt5的图形化界面开发——Windows内存资源监视助手[附带编译exe教程]

    基于PyQt5的图形化界面开发--Windows内存资源监视助手[附带编译exe教程] 0. 前言 1. 资源信息获取函数--monitor.py 2. UI界面--listen.py 3. main ...

  6. python制作图形化小游戏_创意编程|Python的GUI简易界面设计测测你的反应力

    Python的GUI简易界面设计案例 测测你的反应力      作为初次接触代码编程的你,是不是觉得Python程序除了"码"就是"字"即使是有趣的程序除了烧烧 ...

  7. python画球鞋_基于Python爬虫原理的篮球鞋选择程序的设计与实现

    基于 Python 爬虫原理的篮球鞋选择程序的设计与实现 张世元 [期刊名称] <通讯世界> [年 ( 卷 ), 期] 2019(026)002 [摘要] 伴随着篮球鞋工艺的进步及产业升级 ...

  8. 基于PyQt5的图形化界面开发——模拟医院管理系统

    基于PyQt5的图形化界面开发--模拟医院管理系统 0. 前言 1. 需求分析 2. 挂号界面的思路.UI界面代码及相应触发函数 2.1 思路分析 2.2 ui_guahao.py 2.3 相应的触发 ...

  9. 基于JAVA_Swing的图形化GUI漏洞扫描工具开发的编程思维

    文章目录 前言 一.工具外观整体设计 二.漏洞检测类模块 总结 2022年6月27日更新此篇 前言 CSDN博客有很长一段时间没有更新,漏洞复现的文章也没有经常发了,原因是因为我这段时间在做一件大事, ...

最新文章

  1. 用C语言编程 限定输入的年月日,C语言程序设计: 输入年月日 然后输出是星期几...
  2. 链表线性表及其操作c语言代码大全,用链表实现线性表的各种操作(C语言)
  3. Spark(2)——小用RDD
  4. GitBucket管理员添加人员
  5. 杭电2100Lovekey
  6. 自定义View以及事件分发总结
  7. 【codeforces 534B】Covered Path
  8. java关键字有多少?
  9. Excel自学详细视频教程百度网盘分享
  10. 应届生HR面试需要准备的六大类问题
  11. jquery获取元素索引值index()
  12. 我用最独特的方式为情人节准备了这些。。。
  13. 基于ssm外卖点餐系统源码
  14. java response excel_java-返回在servlet中创建的excel文件作为响应
  15. 全局vue中修改字体样式 苹方字体 微软雅黑 亲测可用
  16. 运行javac 报告javac不是内部或外部命令,但是运行java、java-version正常
  17. zbb20180930 设计模式-单例模式
  18. static 的用法
  19. js运算符优先级和~~运算符
  20. Java学习之路--计算圆形的面积和周长

热门文章

  1. javaweb:servlet
  2. 前端三十二:超链接(a标签)
  3. javascript模块化简介
  4. 【顾连科普】健康生活的10个小常识,请收下
  5. 我的Java开发之路
  6. 采用dlopen、dlsym、dlclose dlopen dlerror加载动态链接库【总结】
  7. 安装ipvsadm 用make编译出现错误解决方法
  8. 如何配置Windows Live Writer
  9. 微信小程序 长按属性
  10. 华为系统鸿蒙假的,鸿蒙系统只是噱头?华为董事长:不是噱头,必要时也能用于手机 - 区块网...