邮件自动发送程序GUI版
2017-03-02 00:34
501 查看
使用场景
当使用者需要群发内容框架一致而只有少许内容不同的邮件时,会因为频繁地修改琐碎的细节而浪费大量时间,这样一来一个可供配置和扩展的自动邮件程序就十分有必要。比如说我作为课程助教需要发送邮件给每个考试了的同学他的课程成绩,那么邮件中不同的地方就只有接收者的名字、学号以及成绩。
这些信息通常记录在Excel表中,一个自动邮件发送程序应当可以匹配不同的姓名、学号对应的成绩。这样一来,就可以将邮件发送者从繁琐而无意义的体力劳动中解放出来,而且减少了成绩输入错误这种可能情况的发生。
GUI设计版
一个简易的Python写的邮件自动发送程序可以参考我的上一篇文章,介绍了发送邮件的基本框架。这一次我进一步简化了用户对程序的依赖程度。他只需要运行程序,根据各项文字提示输入必要信息,点击两个按钮即可完成邮件的批量个性化定制发送操作。
首先来看程序源码如下:
# 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, E import datetime import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage from email.header import Header class Automailor: def __init__(self, master): self.master = master master.title("AutoMailor") # Guest object self.guest = Guest() # Change words printed while click "Run" button self.my_text = StringVar() self.my_text.set("Hello, master!") self.my_label = Label(master, textvariable = self.my_text) # Label Added self.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 added self.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 added self.upload_button = Button(master, text = "Upload", command = lambda: self.update("upload")) self.run_button = Button(master, text = "Run", command = lambda: self.update("run")) # Text added self.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") # LAYOUT self.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 cleared self.entered_number = 0 return True try: self.entered_number = int(new_text) return True except ValueError: return False def validate2(self, new_text): if not new_text: # the field is being cleared self.my_entry = "Hello, master!" return True try: self.my_text = str(new_text) return True except ValueError: return False def 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_number elif method == "subtract": self.total -= self.entered_number elif method == "reset": self.total = 0 elif method == "upload": self.transfer() print self.guest else : # run print "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 object self.sender = 'xxx@163.com' self.pwd = '********' self.receivers = [] # empty set self.port_num = 25 self.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 instance smtp.connect(self.host_addr, self.port_num) # connect to mail server smtp.login(self.sender, self.pwd) # Login with a correct account multi_send(self, smtp); # call sendemail one after another for different receivers smtp.quit() # Unlink the connection and exit print("Sending successfully!") def host_name_match(sender): host_name = 'smtp.' + sender.split("@")[1] return host_name def 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 receivers for 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 time for i in range(1, len(info_set)): # temp_content = guest.content; temp_content = guest.frame_content for 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 flag all_specified_content.append(temp_content); # Send emails with different contents one by one send_seq = 0; for single_receiver in guest.receivers: msg = MIMEMultipart('mixed') # Message type, always "mixed" msg['Subject'] = guest.subject # Subject of you email msg['From'] = guest.sender # Sender email info msg['To'] = single_receiver # Receiver email(s) info msg['Date'] = str(datetime.date.today()) # Sending Time text_plain = MIMEText(all_specified_content[send_seq], 'plain', 'utf-8') # An necessary transform msg.attach(text_plain) # Add text to message lib smtp.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
运行实例
运行程序初始界面填写内容完毕
依次点击Upload,Run按钮
注意,点击Run按钮后下方提示文字由“Hello, master!”变成了“Send emails automatically!”。当然也可以替换成其他的文字,只要你找得到我是在代码第多少行写得这个~
邮件是可以发送的,在本地邮箱服务器发件箱中可以查看,但是我测试用的地址估计是收不到的。大家如果使用这个AutoMailor记得把数据最后一列地址列填写成正确的收件邮箱。
导出成可执行文件
有时间我再研究一下将其制作成exe文件的方法。另外,这个代码考虑的异常情况不够多,如果不按照标准输入操作的话,发送是不会成功的。后面我会继续维护这个一时兴起写的小软件,有兴趣的童鞋可以多交流哈!
相关文章推荐
- 后台自动发送邮件的程序(Java Mail,WEB版)
- 自动发送邮件程序开发
- 后台自动发送邮件的程序(Java Mail,WEB版)
- 后台自动发送邮件的程序(java mail,web版)①
- 自动邮件发送程序Python版本
- VC自动发送邮件程序
- 后台自动发送邮件的程序(java mail,web版)②
- matlab自动运行完程序发送邮件知会我
- 我有个javamail自动发送邮件的程序,哪位高手帮我看看,为什么发出去的都是中文乱码?
- 后台自动发送邮件的程序-转载
- [置顶] Android程序崩溃异常处理之自动发送邮件
- Android程序崩溃异常处理之自动发送邮件
- JavaBean邮件自动发送程序带附件
- 后台自动发送邮件的程序(Java Mail,WEB版)
- java程序监控tomcat实现项目宕机自动重启并发送邮件提醒
- windows service(windows 服务程序应用于自动发送邮件)
- 用Jmail实现ASP程序自动发送邮件
- Linux下自动发送邮件程序
- IOS自动捕获程序崩溃日志再发送邮件提示开发者
- 在程序中实现邮件发送,电话拨打,sms,以及浏览器功能能的方法整理