前些天在gae上部署了一个定时往手机发送天气预报的小python程序,原理很简单,就是抓取天气网站,然后解析页面得到天气信息,再利用gae的邮件功能往自己的139邮箱发送电子邮件,手机就能免费接收天气预报了。
后来发现gae上有邮件发送次数限制,一个月只能发送100封电子邮件,假如给我爸,妈和我一天发一封的话,一个月就90多条了,我测试已经费了几条了,如果还想给其他亲朋好友发送天气预报,或者自己接收一些其他电子邮件信息的话,怎么够用?问题就这样来了。。。
本来想在gae上直接调用python的smtplib 模块发送邮件,发现不能用。囧rz....
于是乎,苦寻各种解决方案-_-
方案1:直接解析邮箱登录页面,登录并发送邮件---->太麻烦,依赖于服务网站
方案2:利用”消息速递“往手机上推送---->只能在智能手机上用,不能推广
方案3:寻求免登录直接发送邮件的网站,类似于十分钟邮箱的东西,但是这种邮箱一般只能接收邮件,不能发送邮件,即使能发送的话也容易被识别为垃圾邮件,不靠谱。
方案4:利用飞信发送发送---->飞信协议变化很快,现在网上流行的飞信模块一般都需要输入验证码,不知道哪位大仙能把验证码直接识别出来?(wap飞信主页)
方案5: 利用gmail,163,QQ等提供的邮件列表群发---->群发可以,但如果给每个人发的邮件内容不同的话就不行了
方案6:绞尽脑汁,继续想~~~~
纠结了好一阵后,一个神奇的想法诞生了:为何不在自己的服务器上搭建一个发送邮件的环境呢?我需要的仅仅是发送邮件的功能,要让外部最方便地使用这个发送邮件的功能,怎样算是最简单呢?直接在浏览器地址栏上输入一个网址就执行发送邮件命令是不是很简单?我设计了一下,当然网址里面要有必要的信息,如收件人,邮件主题,内容等。像这样的网址”http://XXX.com/mailto/aaaa@163.com/bbbb/cccc“,翻译过来就是给aaaa@163.com发送一封主题为bbbb,正文为cccc的邮件,是不是很简单?到时候只要让gae上的程序去访问这个网址,就实现发邮件的功能啦!或许你会说,这样直接GET网址太不安全了,里面的信息都明文显示出来了。嘿嘿,无所谓啦,反正我不用这个发送私密信息,像天气预报这样的信息黑客想截就截吧。如果您有兴趣改成post也行哈!
想法有了,接下来就是去实现这个想法啦!我选择了python里面最简单的web模块:web.py来接收外部请求,然后对请求进行解析,得到邮箱,主题和正文,然后调用发送邮件的函数去发送邮件,汗~这么简单,看看代码吧
#coding=utf-8
import web
import urllib
import logging
from sendmail import send_mail
urls = (
# '/(.*)','hello',
'/mailto/(.*)','webmail'
)
app = web.application(urls,globals())
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('webmail.log')
fh.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
class webmail:
__doc__ ='''
Send Mail to Anyone!
usage:
http://xxx.com/mailto/{mail_address}/{subject}/{body}
example:
http://xxx.com/mailto/aaaa@qq.com/subject/body/
multi-address:
http://xxx.com/mailto/aaaa@qq.com/bbbb@163.com/subject/body/
'''
def GET(self,name):
logger.info(name)
info = urllib.unquote(name).split('/')
info = [i for i in info if i != '']
if len(info) < 3:
return webmail.__doc__
try:
send_mail(info[:-2],info[-2],info[-1])
except:
return 'Failed Send Mail'
print info
render = web.template.render('./')
return render.pages(info[:-2],info[-2],info[-1])
if __name__=='__main__':
app.run()
application = app.wsgifunc()
web.py就是简单,小巧。代码中,用get来接收外部请求,得到的请求在name中,然后转换编码,再按’/‘来对网址进行划分,这样得到的info列表里面就有我们需要的信息啦,为了放止info列表中存在空的元素,用一个列表的内建循环来删除空元素,很酷吧!哈哈!接下来判断信息是否完整,如果小于3,肯定不全啊,看看说明吧,把”__doc__“返回。信息正确的话,那就发呗,为了方便进行群发,我又对信息进行了简单定义,定义最后一个信息就是正文,倒数第二个信息就是主题,倒数第二个往前的都是收件人地址!哈哈,怎么样,很简单吧?然后就调用发送邮件函数进行发送呗,为了方便使用,我对sendmail函数进行了简单封装:
def send_mail(to_list,sub,content):
import smtplib
from email.mime.text import MIMEText
mail_host="smtp.163.com" #设置服务器
mail_user="" #用户名
mail_pass="" #口令
mail_postfix="163.com" #发件箱的后缀
me="groupmail"+"<"+mail_user+"@"+mail_postfix+">"
msg = MIMEText(content,_subtype='plain',_charset='gb2312')
msg['Subject'] = sub
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
server = smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_pass)
server.sendmail(me, to_list, msg.as_string())
server.close()
return True
except Exception, e:
raise str(e)
如果你也想做这么个小东西的话,可能需要在sendmail模块里面填上自己邮箱的用户名和密码。
接下来要判断是否发送成功,失败的话给个错误信息就是了,成功的话也返回个信息,我想了想,直接把用户提交的发送邮件请求输出来吧,这样方便用户核对是否发送正确,于是,web.py里面的小巧又强大的模板引擎就派上用场了:
<META charset='utf-8'>
<p>Send Success!</p>
<p>to:
$for c in to:
$c,
</p>
<p>subject:$sub</p>
<p>body:$body</p>
信息无须太多,界面不用太炫,简简单单,把该显示的显示就是了。web.py模板里面可以写入类似python的语句,例如上面的for循环,就是把列表里面的每个邮件地址输出来,这样实现起来很酷!感觉貌似比django的模板引擎好用呢!
这样就算基本实现功能了,接下来,还有一个重头戏,嘿嘿,部署!网上搜了一下,web.py可以和apache或者nginx部署在一块,然后找教程,然后比着做,弄了半天,愣是没部署上!悲剧!也不知道是神马原因。反正我记得部署很麻烦。写这个程序还不如部署的时间长呢!这怎么行?!我喜欢python的简单,我希望部署python程序也是简单的,再去找,果然找到了一种方法,很简单,和大家共享一下。我是用uwsgi进行部署,这个程序可以这样安装:sudo easy_install uwsgi,安装过程如果提示缺少python.h,则需要安装python-dev,直接apt-get安装就可以。安装完后,就可以执行了,用这个命令:uwsgi --http :8080 -w test -p 4 --enable-threads ,这个命令的意思是把test这个python程序部署到本地的8080端口上,并发四个线程和一个主控进程,支持python线程调试,大体就这个意思,想具体了解的可以参考网上资料。上面的命令这么长,不太容易记,写到start.sh脚本里面吧!
后来想想,再增加一个记录日志的功能吧,把所有的请求都用logging模块保存起来,毕竟这个邮箱是公开的,万一有什么异常的话可以去查看日志。
这个任务就算基本完成啦,用强大的markdown写个说明放到github上共享一下!https://github.com/ma6174/webmail,想下载安装的友友可以去看看。
然后再写个博客推广一下http://www.cnblogs.com/ma6174/archive/2012/08/06/2625477.html
最后再写个总结吧: 上面的小程序仅仅实现了一个小工能,或许大家可以对这个程序进行拓广,比如增加简单的认证,不然的话任何人只要知道网址就能发送,这样的话垃圾邮件又满天飞啦!哈哈,这不是我们希望的。再有的话,可以实现一些其他功能,比如远程遥控?只要让服务器解析出你的命令然后去执行就可以啦!或者说,某天你想给好友发电子邮件,又懒得登邮箱,直接在浏览器地址栏里面输入就行啦,一敲回车,立即发送!更多精彩,由你创造!
下面是一些参考资料,在网上找的,保存到我的麦库记事了,有兴趣的朋友可以去深入研究一下。(顺便说一下,麦库记事是个好东西!)
web.py模板系统:https://note.sdo.com/u/ma6174/n/M5cEN~k1Z0PVnM1XI001CA
python的logging模块:https://note.sdo.com/u/ma6174/n/M5cEN~k1ZT4FnM1XI001-K
用uwsgi快速部署web.py应用:http://note.sdo.com/u/ma6174/n/M5cEN~k1ZBgpnM1XI001TH
web.py新手指南:http://note.sdo.com/u/ma6174/n/M5cEN~k14rcMLX0TQ000za
(如果感觉麦库还不错的话可以去注册一个奥,我有邀请码634687868481358385)