前言:

          在实验室里一直存在着一个问题,就是老是有人忘记提醒下一个人值日,然后值日就被迫中断了。毕竟良好的        卫生环境需要大家一起来维护的!没办法只能想出一些小对策了。

     解决思路:

          首先,我想使用python 写个脚本,原因是其拥有众多的库,操作方便。首先实现使用Python 登陆邮箱然后发送        邮件的功能。然后再解决定时发送和对实验室同学轮流发送的问题。在第二步中有两个解决方案:

          1⃣️使用win 2012服务器 的定时任务功能,到指定时间进行自动执行脚本。然后将同学们的邮箱放到一个文件中     ,其中第一行为发送邮件的次数。从第二行开始是同学们的邮箱。每执行一次就增加改变一次数值。通过取余,计         算出应该将邮件发送给谁。

              2⃣️不用那么麻烦,但是需要一直占用些CPU 资源。就是利用while 循环,让脚本在服务器上一直运行。

    当然我选择的是第二种方法做的。(下面新增第一种方式代码)

     脚本源码:

      

# -*- coding: UTF-8 -*-
import sys, os, re, urllib, urlparse
import smtplib
import time
import string
import traceback
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart


def sendmail(subject, msg, toaddrs, fromaddr, smtpaddr, password):
'''''
@subject:邮件主题
@msg:邮件内容
@toaddrs:收信人的邮箱地址
@fromaddr:发信人的邮箱地址
@smtpaddr:smtp服务地址,可以在邮箱看,比如163邮箱为smtp.163.com
@password:发信人的邮箱授权码 注意:是授权码不是密码
'''
mail_msg = MIMEMultipart()
if not isinstance(subject, unicode):
subject = unicode(subject, 'utf-8')
mail_msg['Subject'] = subject
mail_msg['From'] = fromaddr
mail_msg['To'] = ','.join(toaddrs)
mail_msg.attach(MIMEText(msg, 'html', 'utf-8'))
try:
s = smtplib.SMTP()
s.connect(smtpaddr) # 连接smtp服务器
s.login(fromaddr, password) # 登录邮箱
s.sendmail(fromaddr, toaddrs, mail_msg.as_string()) # 发送邮件
s.quit()
print "success"
except Exception, e:
print "Error: unable to send email"
print traceback.format_exc()

group=("864678132@qq.com","1358548208@qq.com","843822062@qq.com","572939586@qq.com")#用来存放每个人的邮箱
i=0 # 用来记录发送次数,然后对人数取余进行判断应该发送给哪个邮箱
while True:
now = time.strftime("%H") # 获取当前时间 小时
now = time.strftime(now) # 转换成字符串
nows = string.atoi(now) # 转换成整数
if nows == 18: # 进行判断 在十八点后进行发送
fromaddr = "发件人邮箱"
smtpaddr = "smtp.163.com"
toaddrs = [group[i]]
subject = "实验室值日邮件"
password = "授权码"
msg = "今天记得打扫卫生哟!"
sendmail(subject, msg, toaddrs, fromaddr, smtpaddr, password)
i=(i+1)%len(group)
time.sleep(6000) #发送完后 等待一小时,避免重复发送
else:
time.sleep(3000)

 

 

 

补充:

在使用上面的一种方法的时候经常在循环一次队列之后就会产生莫名的BUG,所以我才用了定时运行python脚本的方式。

  • 服务器:Centos7 
  • 运行环境:python2.7(python3.6也可)
  • 执行方式:利用centos的定时任务机制,定时执行发送脚本
  • 原理:上面也有讲,将接受人的邮箱放在一个文件中,每行一个。当执行一次脚本后,将第一行内容放到最后一行中。 
  • 文件名:email.txt
  • 脚本名:cleanRoomPro.py
  • 日志文件:RunCleanRoomPro.txt
  • 使用方式
  1. 终端输入: crontab -e
  2. 新增一行内容:59 06 * * * /usr/bin/python ~/cleanRoom/cleanRoomPro.py >> ~/cleanRoom/RunCleanRoomPro.txt(意思是在早晨6:59分 执行~/cleanRoom/目录下的cleanRoomPro.py脚本)

代码:

# coding:utf-8  #强制使用utf-8编码格式
import smtplib # 加载smtplib模块
from email.mime.text import MIMEText
from email.utils import formataddr
import time

#发送邮件函数
def mail(my_sender,my_user):
ret = True
try:
msg = MIMEText('值日小助手提醒:明天早晨记得打扫卫生!扫地、拖地、用水冲卫生间', 'plain', 'utf-8')
msg['From'] = formataddr(["[203宿舍值日提醒:)]", my_sender]) # 括号里的对应发件人邮箱昵称、发件人邮箱账号
msg['To'] = formataddr(["值日啦", my_user]) # 括号里的对应收件人邮箱昵称、收件人邮箱账号
msg['Subject'] = "值日" # 邮件的主题,也可以说是标题

server = smtplib.SMTP("smtp.163.com", 25) # 发件人邮箱中的SMTP服务器,端口是25
server.login(my_sender, "你的授权码") # 括号中对应的是发件人邮箱账号、邮箱授权码
server.sendmail(my_sender, [my_user, ], msg.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
server.quit() # 这句是关闭连接的意思
except Exception: # 如果try中的语句没有执行,则会执行下面的ret=False
ret = False
return ret

# 打开文件
fo = open("email.txt", "r+")
listEmail=[]
while True:
i = 0
line = fo.readline()
if not line:
break
line = line.strip('\n')
listEmail.append(line)
i = i + 1
# 关闭文件
fo.close()
#取出第一个元素 执行发送邮件函数

ret = mail("yanghuo_cx@163.com", listEmail[0])
if ret:
print("接受人:"+listEmail[0]+"时间:"+time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+"状态:ok") # 如果发送成功则会返回ok,稍等20秒左右就可以收到
else:
print("接受人:"+listEmail[0]+"时间:"+time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+"状态:filed") # 如果发送失败则会返回filed

#调换顺序写入文件

fo = open("email.txt", "w")
for i in range(len(listEmail)-1):
fo.write(listEmail[i+1]+'\n')
fo.write(listEmail[0])
fo.close()