w9-网络遗书demo
后端邮件服务设计
有了前面关于时间的写法、比较、筛选方法,剩下的就好写了:
还是梳理逻辑,总共两个函数,其一用于筛出心跳确认邮件的发送:
- 获取当前日期,将它输入查询语句
- 根据输入筛选出所有查询到的的数据种抽取:用户名、用户联系邮箱
- 向被筛选出来的对象邮箱发送确认邮件。
另一个用于向亲属发送遗嘱,这个先向后放:
- 获取当前日期,将它输入查询语句
- 根据输入筛选出所有查询到的的数据种抽取:用户名、用户联系邮箱、遗嘱、遗嘱和联系人对应关系、亲属联系邮箱。
- 向北筛选出的对象邮箱发送遗嘱文件。
另外为了专门运行测试,单独设置一个测试用邮箱:
用户名:[email protected] 密码:P@ssw0rdP@ssw0rd
# 导入时间模块
import time
# 获取当前时刻时间戳
timenow = time.time()
# 定义查询时间函数,获取
livecheck = collection.find({"heatbeatSync":{"$lte":timenow},"heatbeatFinal":{"$gte":timenow}},{'userID':1,'name':1,'heatbeatmail':1})
# 显示查询结果
print livecheck
for i in livecheck:
userID = i.get('userID')
name = i.get('name')
mailaddr = i.get('heatbeatmail')
livecheck(userID,name,mailaddr)
# 邮件相关
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
# 邮件服务测试
def livecheck_mail(userID,name,mailaddr):
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
from_addr = 'whenmgonetest'
password = 'P@ssw0rdP@ssw0rd'
to_addr = mailaddr
smtp_server = 'smtp.163.com'
msg = MIMEText('<h2>亲爱的' + name + ',whenmgone向您个安!</h2>'
+ '\n' + '<form action="#" method="POST"><button type="submit">平身罢</button></form>',
'html', 'utf-8')
msg['From'] = _format_addr('whenmgone <%s>' % from_addr)
msg['To'] = _format_addr(name + ' <%s>' % to_addr)
msg['Subject'] = Header('whenmgone定期心跳', 'utf-8').encode()
server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
实验数据
为了能够测试,首先必须设计几条合理的数据格式备用,上回的数据都是凑合的,我打算这回发挥些当年的文艺中二余热,设计几个典型用户试一下:
张向阳,一个山西汉字,北漂一族,在互联网公司coding,独子单身狗,北京有同学无亲人,每年过年回家一次。爱工作,公司环境又好,恨不得吃住都在公司,但平时加班非常狠,生活也极其不规律,比较毕业前明显发福很多。生活比较追求流行,接收新鲜事务很快,最近几年随着各种宝的火热,拿着自己攒的钱开始尝试着到处投资,股票、p2p、余额宝、比特币什么都有尝试,在15年股灾后,虽然嘴上说决心再不进股市,但还是留了一些,账户十分分散,看到朋友有人用网络遗嘱服务觉得有意思,于是自己也注册了一个。
唐晓楠,一个20出头的四川姑娘,性格直爽但精明,敢想又敢干,从小到大做过各种工作,目前在鼓浪屿做导游,虽然收入高但还是月光族。和男朋友异地,准备明年结婚,于是开始逐渐攒钱,主要的钱都是放在余额宝和银行自己的宝里面,微信账户也有一些钱,用来做支付和发红包用,但自己并不清楚到底都有多少,属于赚钱没数,花钱没边的。因为男朋友注册了网络遗书服务,还告诉她注意收遗书,于是图新鲜也注册了个。
宋旭涛,年纪不到40,在银行工作,在一个二线省分行做信贷审批,留学生背景,本来是在总行工作,但因为要照顾家里老人,所以最终留在了家乡。用的银行卡主要是自己行里的,自己的钱主要投的是银行推荐的理财产品,而且也有父母和亲属的钱很多也拜托他一起帮忙投放,有一笔比较大额的是亲朋好友一起拼的信托,找的熟人投出去的。这些钱中,风险最大的是自己一少部分投资的一些超过10%的一年期债权,网络上的p2p什么的觉得根本不靠谱也不想投。自己身体并不很好,而且这些年发福的厉害,又缺乏运动,最近一次体检查出血糖高,自己于是打算开始从饮食上入手开始注意。最近办公室里有人讨论关于网络遗嘱的事,他觉得可行,但对平台的安全性十分质疑,最终还是注册了。
有了这样的背景,可以开始设计他们的平台数据了:
张向阳用例
id: yoga password:P@ssw0rdZXY@whenmgone name:张向阳 phone:18600563873
note01.content:
爸妈,别太难过,这几年在外面漂回家回的可能太少了,没能照顾到您们,您别介意。 我在北京过的挺好的,公司同事对我都不错,如果我挂了那也肯定不是过劳死,妈您可千万别跟公司起误会。 我这个留言主要是想告诉您二老,我有好些钱都投在了一些网络账户上,您拿着我的手机可千万别扔,登录里面好几个App里面都把钱取出来吧,我下面一一告诉您怎么取:
- 支付宝密码是*。。。
- 还有工商银行那个。。。。
- 另外我有个京东账户,这个您把我弟找来,让它告诉您怎么操作,到时候密码您输入**
- 还有个宜信,那个只能到了时候才能取,这个您看*
- 然后有个华泰的账号,这个您找舅舅,让它告诉您怎么把这个兑出来,您千万告诉他里面有个**建议长期持,那个特别好。。。
note01.link:['content01']
contact01.mail:'[email protected]' contact01.phone:'15019371635' contact01.name: '赵慧珍'
heatbeatmail:'[email protected]'
heatbeatRate:7,
heatbeatDelay:7,
heatbeatUpdate:1450110040.0,
heatbeatSync:1450714840.0,
heatbeatFinal:1451319640.0,
唐晓楠用例
id: tangnans password:75643871T name:唐小楠 phone:13800583746
note01.content:
老公,如果你看到了这个,那我可能已经死了,不管咱们结没结婚,对你的好要记挂我一辈子哈。 你要是找别人也行,可千万别太快啊,要不让我爸怎么想。 哎呀,我实在写不下去了,没了我你可怎么活呢,做饭也不会,还天天出去吃的乱七八糟的。 爱你的楠
note01.link:['content01']
contact01.mail:'[email protected]' contact01.phone:'15028376153' contact01.name: '汪大勇'
heatbeatmail:'[email protected]'
heatbeatRate:14,
heatbeatDelay:14,
heatbeatUpdate:1450110040.0,
heatbeatSync:1450714840.0,
heatbeatFinal:1451319640.0,
宋旭涛用例
id: YonySong password:19780921 name:宋旭涛 phone:13276543939
note01.content:
丽芳,最终还是没想到要先走一步,不过好在有个这样的邮件服务,能让我最后还能和你聊些心里话,也算是件挺好的事。 咱们在一起都过了10年了,但是不知道是不是因为工作和生活的压力,反而让我们越来越疏远,再也回不到当初谈理想搞浪漫的状态。虽然我们之间已经沉默到连架都懒得吵了,但对我来讲你永远是最重要的人,和你结婚一起生活这么多年我最终还是不后悔。
没能看着宝婷长大是我最大的遗憾,上次学校活动我没参加确实是我的错,我道歉,千万不要为了这件事再记恨我了。不过我也确实对自己失望,混了这么多年都最终还是没能把宝婷办到更好的学校里面去,但这件事情我还是期望你再想想办法,这对宝婷是很重要的事,千万不要因为不好弄就不办了,学校那边该打点的还是要打点,这不是该省钱的地方,切记!
另外除了咱们家的银行卡之外,我还有一张卡里面存了些货币基金,大概在200w左右,密码是你生日,不到万难时候最好别取,一直存着就行了。还有老舅有一笔40w,你弟的20w,还有咱们家的40w我合在了一起,交给张扬去投信托了,留了张借据就在红木柜子倒数第二层有个牛皮纸袋里,日期到了的时候记得找张扬兑。
真正写遗嘱的时候才发现好多话真应该和你当面说,我期望咱们家都平平安安的谁都看不到这封信是最好的结果,就这些罢!
note01.link:['content01']
contact01.mail:'[email protected]' contact01.phone:'15173649384 contact01.name: '徐丽芳'
heatbeatmail:'[email protected]'
heatbeatRate:30,
heatbeatDelay:30,
heatbeatUpdate:1450110040.0,
heatbeatSync:1450714840.0,
heatbeatFinal:1451319640.0,
这样数据就基本准备好了
封装时间计算
我把时间计算封装在一个类里面集中运算,这样只要返回时间戳就ok了
# -*- coding: UTF-8 -*-
'''
* 用于whenmgone的demo原型测试(时间计算)
* [email protected]
* 2015.12.5
'''
# 引入os模块
import os
# 引入time模块
import time
# 引入datatime模块
from datetime import datetime,timedelta
# 设置时间计算模块儿
class TimeCompute(object):
"""用于计算遗书服务更新时间"""
# 初始化模块儿参数心跳频率和时间时间
def __init__(self, heatbeatrate,heatbeatdelay):
self.heatbeatrate = heatbeatrate
self.heatbeatdelay = heatbeatdelay
self.timenow = datetime.now()
# 最后更新时间戳
def heatbeatUpdate(self):
return time.mktime(self.timenow.timetuple())
# 下次同步时间戳
def heatbeatSync(self):
_timesync = self.timenow + timedelta(days=self.heatbeatrate)
return time.mktime(_timesync.timetuple())
# 最晚延时时间戳
def heatbeatFinal(self):
_timefinal = self.timenow + timedelta(days=self.heatbeatrate+self.heatbeatdelay)
# _timefinal = _timenow + timedelta(days=heatbeatdelay)
return time.mktime(_timefinal.timetuple())
# 时间计算用例
a=TimeCompute(7,7)
print a.heatbeatUpdate()
print a.heatbeatSync()
print a.heatbeatFinal()
这样时间参数的封装也ok了,下一步,我需要把查询和发送邮件想办法连起来
首先我把两种邮件发送函数写好:
# -*- coding: UTF-8 -*-
# 引入sys模块,并将默认字符格式转为utf-8
import sys
sys.path.append("./")
reload(sys)
sys.setdefaultencoding( "utf-8" )
# 邮件相关
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
# 邮件服务测试——心跳检测
def livecheck_mail(userID,name,mailaddr):
def _format_addr(s):
name, addr = parseaddr(s)
return formataddr((Header(name, 'utf-8').encode(), addr))
from_addr = '[email protected]'
password = 'awhhatnazgnrjsya'
to_addr = mailaddr
smtp_server = 'smtp.163.com'
msg = MIMEText('<h2>亲爱的' + name + ',whenmgone向您个安!</h2>'
+ '\n' + '<form action="#" method="POST"><button type="submit">平身罢</button></form>',
'html', 'utf-8')
msg['From'] = _format_addr('whenmgone <%s>' % from_addr)
msg['To'] = _format_addr(name + ' <%s>' % to_addr)
msg['Subject'] = Header('whenmgone定期心跳', 'utf-8').encode()
server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
# 邮件服务测试——遗嘱发送
def notesend_mail(userID,name,contactname,mailaddr):
def _format_addr(s):
contactname, addr = parseaddr(s)
return formataddr((Header(contactname, 'utf-8').encode(), addr))
from_addr = '[email protected]'
password = 'awhhatnazgnrjsya'
to_addr = mailaddr
smtp_server = 'smtp.163.com'
msg = MIMEText('<h2>' + contactname + ':<br>您好,我们受 <b>' + name +'</b> 委托,向您发送他最后的留言,请点击如下链接进行查收!</h2>'
+ '\n' + '<form action="#" method="POST"><button type="submit">留言</button></form>',
'html', 'utf-8')
msg['From'] = _format_addr('whenmgone <%s>' % from_addr)
msg['To'] = _format_addr(contactname + ' <%s>' % to_addr)
msg['Subject'] = Header('whenmgone网络遗嘱', 'utf-8').encode()
server = smtplib.SMTP(smtp_server, 25)
server.set_debuglevel(1)
server.login(from_addr, password)
server.sendmail(from_addr, [to_addr], msg.as_string())
server.quit()
然后做出检查数据库,并获取到对象的模块儿:
# 导入pymongo模块
import pymongo
# 设置数据库地址
client = pymongo.MongoClient('172.16.191.163', 27017)
# 设置数据库名
db = client['demodb']
# 设置表名
collection = db['demotable']
# 导入时间模块
import time
# 获取当前时刻时间戳
timenow = time.time()
# 获取所有的该发送定时心跳的对象
livecheck = collection.find({"heatbeatSync":{"$lte":timenow},"heatbeatFinal":{"$gte":timenow}},{'userID':1,'name':1,'heatbeatmail':1})
# 获取所有的该发送遗嘱的对象
deathcheck = collection.find({"heatbeatFinal":{"$lte":timenow}},{'userID':1,'name':1,'heatbeatMail':1,'contact01':1})
并最终建立检查并发送的循环:
# 检查心跳并发送主循环
for i in livecheck:
userID = i.get('userID')
name = i.get('name')
mailaddr = i.get('heatbeatMail')
print userID,name,mailaddr
livecheck_mail(userID,name,mailaddr)
# 检查无回应并发送主循环
for i in deathcheck:
userID = i.get('userID')
name = i.get('name')
mailaddr = i.get('heatbeatMail')
contact01 = i.get('contact01').get('name')
print userID,name,mailaddr,contact01
notesend_mail(userID,name,contact01,mailaddr)
这样一个可用的检查到期并循环发送邮件模块就写好了,但并不算完美,这个脚本需要每天手动执行一次,相对完善的方式是想办法做一个每天定期的执行查询循环,发送邮件我找到了一个sched模块,这个我打算放在后面在做,我把这个函数封装在daily.py里面,下周主要任务把前端做好看。
最后,我把数据库检查函数设定成能检索到自己的模式,发送邮件做测试
至此,demo版本完全可用,demo成功