邮件自动发送程序GUI版

使用场景
当使用者需要群发内容框架一致而只有少许内容不同的邮件时,会因为频繁地修改琐碎的细节而浪费大量时间,这样一来一个可供配置和扩展的自动邮件程序就十分有必要 。
比如说我作为课程助教需要发送邮件给每个考试了的同学他的课程成绩,那么邮件中不同的地方就只有接收者的名字、学号以及成绩 。
这些信息通常记录在Excel表中,一个自动邮件发送程序应当可以匹配不同的姓名、学号对应的成绩 。这样一来,就可以将邮件发送者从繁琐而无意义的体力劳动中解放出来,而且减少了成绩输入错误这种可能情况的发生 。
GUI设计版
一个简易的写的邮件自动发送程序可以参考我的上一篇文章,介绍了发送邮件的基本框架 。
这一次我进一步简化了用户对程序的依赖程度 。他只需要运行程序,根据各项文字提示输入必要信息,点击两个按钮即可完成邮件的批量个性化定制发送操作 。

邮件自动发送程序GUI版

文章插图
首先来看程序源码如下:
# coding:utf-8# author: Meditator_hkx#!/usr/bin/env python# GUI AutoMailor'a GUI version for auto_email implementation'from Tkinter import Tk, Label, Button, Entry, Text, IntVar, StringVar, END, W, Eimport datetimeimport smtplibfrom email.mime.multipart import MIMEMultipartfrom email.mime.text import MIMETextfrom email.mime.image import MIMEImagefrom email.header import Headerclass Automailor:def __init__(self, master):self.master = mastermaster.title("AutoMailor")# Guest objectself.guest = Guest()# Change words printed while click "Run" buttonself.my_text = StringVar()self.my_text.set("Hello, master!")self.my_label = Label(master, textvariable = self.my_text)# Label Addedself.account_label = Label(master, text = "Sender account: ")self.pwd_label = Label(master, text = "Sender password: ")self.port_label = Label(master, text = "Mail server port: ")self.flag_label = Label(master, text="Replacement flag character: ")self.subject_label = Label(master, text="Mail subject: ")self.frame_content_label = Label(master, text = "Framework words:")self.individual_info_label = Label(master, text = "Ordered information:")vcmd2 = master.register(self.validate2) self.my_entry = Entry(master, validate = "key", validatecommand = (vcmd2, '%P'))# Entry addedself.account_entry = Entry(master)self.pwd_entry = Entry(master)self.port_entry = Entry(master)self.flag_entry = Entry(master)self.subject_entry = Entry(master)# Button addedself.upload_button = Button(master, text = "Upload", command = lambda: self.update("upload"))self.run_button = Button(master, text = "Run", command = lambda: self.update("run"))# Text addedself.frame_content_text = Text(master, width = 30, height = 20 ,bg = "black" ,fg = "white")self.individual_info_text = Text(master, width = 60, height = 20, bg = "black", fg = "white")# LAYOUTself.account_label.grid(row = 3, column = 0, sticky=W)self.account_entry.grid(row = 4, column = 0, columnspan = 8, sticky=W+E)self.pwd_label.grid(row = 5, column = 0, sticky=W)self.pwd_entry.grid(row = 6, column = 0, columnspan = 8, sticky=W+E)self.port_label.grid(row = 7, column = 0, sticky=W)self.port_entry.grid(row = 8, column = 0, columnspan = 8, sticky=W+E)self.flag_label.grid(row = 9, column = 0, sticky=W)self.flag_entry.grid(row = 10, column = 0, columnspan = 8, sticky=W+E)self.subject_label.grid(row = 11, column = 0, sticky=W)self.subject_entry.grid(row = 12, column = 0, columnspan = 8, sticky=W+E)self.upload_button.grid(row = 13, column = 0, sticky = W + E)self.run_button.grid(row = 13, column=3, sticky=W + E)self.my_label.grid(row = 14, column = 0, columnspan=2, sticky=E)self.frame_content_label.grid(row = 15, column = 0, sticky = W)self.frame_content_text.grid(row = 16, column = 0, sticky = W)self.individual_info_label.grid(row = 15, column = 2, sticky=W)self.individual_info_text.grid(row = 16, column = 2, sticky = W)def validate(self, new_text):if not new_text: # the field is being clearedself.entered_number = 0return Truetry:self.entered_number = int(new_text)return Trueexcept ValueError:return Falsedef validate2(self, new_text):if not new_text: # the field is being clearedself.my_entry = "Hello, master!"return Truetry:self.my_text = str(new_text)return Trueexcept ValueError:return Falsedef transfer(self):self.guest.sender = self.account_entry.get()self.guest.pwd = self.pwd_entry.get()self.guest.flag = self.flag_entry.get()self.guest.port_num = self.port_entry.get()self.guest.subject = self.subject_entry.get()self.guest.host_addr = host_name_match(self.guest.sender)self.guest.frame_content = self.frame_content_text.get("1.0", END)self.guest.individual_content = self.individual_info_text.get("1.0", END)def update(self, method):if method == "add":self.total += self.entered_numberelif method == "subtract":self.total -= self.entered_numberelif method == "reset":self.total = 0elif method == "upload":self.transfer()print self.guestelse : # runprint "Running the program"self.my_text.set("Send emails automatically!")self.guest.run()# self.total_label_text.set(self.total)# self.entry.delete(0, END)class Guest(object):def __init__(self): # Define basic elements for Guest objectself.sender = 'xxx@163.com'self.pwd = '********'self.receivers = [] # empty setself.port_num = 25self.host_addr = 'smtp.163.com'self.individual_content = ''self.flag = 'XX'self.frame_content = ''self.subject = "Score Result Inform"def run(self):print("Running process...")smtp = smtplib.SMTP()# Create a smtp instancesmtp.connect(self.host_addr, self.port_num) # connect to mail serversmtp.login(self.sender, self.pwd) # Login with a correct accountmulti_send(self, smtp); # call sendemail one after another for different receiverssmtp.quit() # Unlink the connection and exitprint("Sending successfully!")def host_name_match(sender):host_name ='smtp.' + sender.split("@")[1]return host_namedef multi_send(guest, smtp):line_set = guest.individual_content.split('\n')info_set = []for line in line_set:line = line.strip(" ")ele_set = line.split('\t')if len(ele_set) > 1:info_set.append(ele_set)print info_set# Get all receiversfor i in range(1, len(info_set)):guest.receivers.append(info_set[i][-1]);all_specified_content = []replacement_flag = guest.flag# Get specified content each timefor i in range(1, len(info_set)):# temp_content = guest.content;temp_content = guest.frame_contentfor j in range(0, len(info_set[1])-1):temp_content = temp_content.replace(replacement_flag, info_set[i][j], 1); # each time replace one flagall_specified_content.append(temp_content);# Send emails with different contents one by onesend_seq = 0;for single_receiver in guest.receivers:msg = MIMEMultipart('mixed')# Message type, always "mixed"msg['Subject'] = guest.subject# Subject of you emailmsg['From'] = guest.sender# Sender email infomsg['To'] = single_receiver# Receiver email(s) infomsg['Date'] = str(datetime.date.today())# Sending Timetext_plain = MIMEText(all_specified_content[send_seq], 'plain', 'utf-8')# An necessary transformmsg.attach(text_plain) # Add text to message libsmtp.sendmail(guest.sender, single_receiver, str(msg))send_seq += 1;root = Tk()my_mailor = Automailor(root)root.mainloop()# Use a loop to promise that I can send mails again and again in batch