基于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. 登陆自己邮箱,输入帐号密码。

06225439_w6xE.png

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

06225439_DSw8.png

3. 点击发送。

06225439_QLDF.png

4. 去收件邮箱验证。

06225439_Xw6P.png

 

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值