Python3:自动发送账单邮件

一、前言

民间借贷,没有信用卡那样,每月会收到账单;为了民间借贷管理更加合理化,写了个还款账单小程序。

二、源码

(1)配置文件代码:

[dbmysql]
ip = localhost
port = 3306
user = root
password = ******
dbname = pythondb [dbtime]
starttime = 220000 [dbemail]
username = ******@qq.com
password = ******
smtp = smtp.qq.com
sender = ******@qq.com
receiver = ******@qq.com sign_company = ******
sign_addr = ******
sign_dept = ******
sign_name =******
sgin_email = ******@qq.com
sign_phone = ******
sign_qq = ******
sign_www = http://www.******.com [dbpath]
logpath = E:\logs\autoemail

(2)程序代码:

# python3
# author:lizm
# date:2018-07-19 10:00:00
# -*- coding: utf-8 -*-
'''
description:自动发送账单邮件
''' import logging
import configparser
import sys
import datetime,time
from smtplib import SMTP_SSL
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import pymysql
from selenium import webdriver
from sqlalchemy import Column, Integer, String, DateTime, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import and_, func class Email(object):
def __init__(self, hkrq, sqjyje, rll, bqyhlx, bqhkje, bqjyje, remark):
self.hkrq = hkrq
self.sqjyje = sqjyje
self.rll = rll
self.bqyhlx = bqyhlx
self.bqhkje = bqhkje
self.bqjyje = bqjyje
self.remark = remark
def __get__(self, instance, cls):
if instance is None:
return self
else:
return instance.__dict__[self.name]
def __set__(self, instance, value):
instance.__dict__[self.name] = value
def __delete__(self, instance):
del instance.__dict__[self.name] # 获取配置文件信息
def dbconfig():
# 生成config对象
cfg = configparser.ConfigParser()
# 读取配置文件(此处是utf-8-sig,而不是utf-8)
cfg.read(sys.path[0]+"\dbconfig.ini",encoding="utf-8-sig")
# dbmysql
ip = cfg.get("dbmysql","ip")
port = cfg.get("dbmysql","port")
user = cfg.get("dbmysql","user")
pwd = cfg.get("dbmysql","password")
dbname = cfg.get("dbmysql","dbname")
# dbtime
starttime = cfg.get("dbtime","starttime")
# dbemail
username = cfg.get("dbemail","username")
password = cfg.get("dbemail","password")
smtp = cfg.get("dbemail","smtp")
sender = cfg.get("dbemail","sender")
receiver = cfg.get("dbemail","receiver")
sign_company = cfg.get("dbemail","sign_company")
sign_addr = cfg.get("dbemail","sign_addr")
sign_dept = cfg.get("dbemail","sign_dept")
sign_name = cfg.get("dbemail","sign_name")
sgin_email = cfg.get("dbemail","sgin_email")
sign_phone = cfg.get("dbemail","sign_phone")
sign_qq = cfg.get("dbemail","sign_qq")
sign_www = cfg.get("dbemail","sign_www")
# dbpath
logpath = cfg.get("dbpath","logpath")
return (ip,port,user,pwd,dbname,starttime,username,password,smtp,sender,receiver,sign_company,sign_addr,sign_dept,sign_name,sgin_email,sign_phone,sign_qq,sign_www,logpath) #邮件定义
mail_info = {
"from": dbconfig()[9],
"to": dbconfig()[10],
"hostname": dbconfig()[8],
"username": dbconfig()[6],
"password": dbconfig()[7],
"mail_subject": "还款账单("+time.strftime("%Y%m%d")+")",
"mail_text": "你好, this is a test email, sended by py",
"mail_encoding": "utf-8",
"sign_all": "签名"
} # 配置日志
logger = logging.getLogger()
# 设置文件
file = logging.FileHandler(sys.path[0]+"\logs"+time.strftime("%Y%m%d")+".log") #file = logging.FileHandler(dbconfig()[11]+"\log"+time.strftime("%Y%m%d")+".log")
# set formatter
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
file.setFormatter(formatter)
logger.addHandler(file)
# set log level
logger.setLevel(logging.NOTSET) #查询最新的数据
def qryData():
try:
# 打开数据库连接
conn = pymysql.connect(host=dbconfig()[0], user=dbconfig()[2],passwd=dbconfig()[3], db=dbconfig()[4], port=int(dbconfig()[1]), charset='utf8')
# 获取一个游标
cursor = conn.cursor()
# 查询数据库中的最新数据
sql_date = """select bqjyje,rll from """+dbconfig()[4]+""".py_email order by hkrq desc limit 1 ;"""
#print('sql_check>>>:%s' %sql_date)
cursor.execute(sql_date)
results = cursor.fetchall()
# 判断是否有记录数
if len(results) != 0:
r_date = results[0]
cursor.close() # 关闭游标
conn.close() # 释放数据库资源
except:
logger.info("Email异常(qryData):获取最新数据失败")
print("Email异常(qryData):获取最新数据失败")
r_bqjyje = r_date[0]
r_rll = r_date[1]
return (r_bqjyje,r_rll) #数据入库处理
def saveData(rp):
r_code = 0
try:
# 打开数据库连接
conn = pymysql.connect(host=dbconfig()[0], user=dbconfig()[2],passwd=dbconfig()[3], db=dbconfig()[4], port=int(dbconfig()[1]), charset='utf8')
# 获取一个游标
cursor = conn.cursor()
sql = """INSERT INTO """+dbconfig()[4]+""".py_email(hkrq,sqjyje,rll,bqyhlx,bqhkje,bqjyje,remark,createtime) VALUES('"""+rp.hkrq+"""','""" + rp.sqjyje + """','"""+rp.rll+"""','""" + rp.bqyhlx + """','""" + rp.bqhkje + """','""" + rp.bqjyje + """','',sysdate());"""
try:
#print('sql>>>:' + sql)
# 执行sql语句
cursor.execute(sql)
# 提交到数据库执行
conn.commit()
r_code = 0
except:
# 如果发生错误则回滚
conn.rollback()
r_code = 1
cursor.close() # 关闭游标
conn.close() # 释放数据库资源
except:
r_code = 1
if r_code ==1:
logger.info("Email异常(saveData):数据入库失败")
print("Email异常(saveData):数据入库失败")
else:
logger.info("还款账单已生成并发送邮件")
print("还款账单已生成并发送邮件")
return r_code def send(rp):
#使用SMTP_SSL就是默认使用465端口
smtp = SMTP_SSL(mail_info["hostname"])
#set_debuglevel()是用来调试的。参数值为1表示开启调试模式,参数值为0关闭调试模式
smtp.set_debuglevel(0) #连接服务器
smtp.ehlo(mail_info["hostname"])
#邮箱登录
smtp.login(mail_info["username"], mail_info["password"]) msg = MIMEMultipart()
#填写正文内容
main_html = """
<html>
<head></head>
<body>
<div font-size:15px;background-color:#FFFFFF;">
<div>
<span style="line-height:3;">------------------------还款账单("""+rp.hkrq+""")------------------------</span>
</div>
<div>
<span style="line-height:1.5;">应还总金额:"""+rp.sqjyje+"""元</span>
</div>
<div>
<span style="line-height:1.5;">本期还款:"""+rp.bqhkje+"""元</span>
</div>
<div>
<span style="line-height:1.5;">本期利息:"""+rp.sqjyje+"""(本金)*"""+rp.rll+"""(万分之三/日)*30(天)="""+rp.bqyhlx+"""元</span>
</div>
<div>
<span style="line-height:1.5;">------------------------</span>
</div>
<div>
<span style="line-height:1.5;">剩余应还总金额:"""+rp.sqjyje+"""(本金)+"""+rp.bqyhlx+"""(利息)-"""+rp.bqhkje+"""(本期还款)="""+rp.bqjyje+"""元</span>
</div>
<p><br/></p>
<div>
<span style="line-height:1.5;">————————————</span>
</div>
</div>
<div style="font-size:13px;background-color:#FFFFFF;">
<div style="font-family:Verdana;">
<div>
<span style="font-size:13px;line-height:1.5;">公司:"""+dbconfig()[11]+"""</span>
</div>
<div>
<span style="font-size:13px;line-height:1.5;">通讯地址:"""+dbconfig()[12]+"""</span>
</div>
<div>
<span style="font-size:13px;line-height:1.5;">"""+dbconfig()[13]+""":"""+dbconfig()[14]+"""</span>
</div>
<div>
<span style="font-size:13px;line-height:1.5;">邮箱:<a href='mailto:"""+dbconfig()[15]+"""' target="_blank">"""+dbconfig()[15]+"""</a></span>
</div>
<div>
<span style="font-size:13px;line-height:1.5;">手机:"""+dbconfig()[16]+"""</span>
</div>
<div">
<span style="font-size:13px;line-height:1.5;">QQ:"""+dbconfig()[17]+"""</span>
</div>
<div>
<span style="font-size:13px;line-height:1.5;">公司网址:<a href='"""+dbconfig()[18]+"""' target="_blank">"""+dbconfig()[18]+"""</a></span>
</div>
</div>
</div>
<p><br/></p>
</body>
</html>
"""
main_msg = MIMEText(main_html, "html", mail_info["mail_encoding"])
msg.attach(main_msg)
#填写邮件标题
msg["Subject"] = Header(mail_info["mail_subject"], mail_info["mail_encoding"])
#发送者邮箱地址
msg["from"] = mail_info["from"]
#接收者邮件地址
msg["to"] = mail_info["to"]
try:
#发送邮件
smtp.sendmail(mail_info["from"], mail_info["to"], msg.as_string())
#退出
smtp.quit()
#入库操作
saveData(rp)
except:
logger.info("还款账单生成失败")
print("还款账单生成失败") if __name__ == '__main__':
bqhkje = input("请输入还款金额:")
print("还款账单生成中...")
hkrq = time.strftime('%Y%m%d')
rdata = qryData()
sqjyje = rdata[0]
rll = rdata[1]
bqhklx = str(float(sqjyje)*float(rll)*30)
#bqhkje = '3500.00'
bqjyje = str(float(sqjyje)+float(bqhklx)-float(bqhkje))
remark = ""
#print("参数%s,%s,%s,%s,%s,%s" %(hkrq,sqjyje,rll,bqhklx,bqhkje,bqjyje))
rp = Email(hkrq,sqjyje,rll,bqhklx,bqhkje,bqjyje,remark)
send(rp)

三、效果

Python3:自动发送账单邮件的更多相关文章

  1. Linux下监控磁盘使用量并在超过阀值后自动发送报警邮件

    最近Linux服务器磁盘使用量经常到100%,直到影响到正常服务出现故障才会去注意,做不到防患于未然,今天在网上搜集了资料,加上自己修改,写了一个shell脚本用于实时监控磁盘使用量并在超过阀值后自动 ...

  2. 【ABAP系列】SAP 如何用ABAP实现自动发送外部邮件

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP 如何用ABAP实现自动发 ...

  3. 使用vmimeNET解析账单邮件

    大概所有做APP的公司都是不愿意做自定义的,哪怕自己的功能再烂也愿意慢慢修补不愿意开源一部分. 卡牛- 51信用卡- 一次次的逾期   自己写个信用卡管理工具,从邮件中提取账单,还款后做个登记,到了还 ...

  4. python3 - pop 接收邮件/ smtp 发送邮件

    以下通过python3 实现接收和发送邮件,网上相关说明文档很多.请自己查阅,这里只写入代码, # 实例:通过poplib 模块接收指定账号的邮件并进行解码处理,结果可视化. #!/opt/pytho ...

  5. Python3发送qq邮件,测试通过

    import smtplib from email.mime.text import MIMEText # 收件人列表 mail_namelist = ["10402852@qq.com&q ...

  6. python3 发送QQ邮件

    from email.header import Headerfrom email.mime.text import MIMETextfrom smtplib import SMTP_SSL emai ...

  7. python3 发邮件 smtplib & email 库

    嗨 实现了用163发送到qq的功能,遗留了两个问题: 1. 接收者list会报错:update:因为list[]会传递过去一个真的[]list,改成如下就可以了: before: maillist=[ ...

  8. Delphi - Indy 创建邮件自动发送服务

    服务器自动邮件线程 功能:此程序主要实现对Oracle数据库表tableName(存放需要发送邮件的相关信息)里面相关信息的邮件发送. 优点:开发人员可以直接再数据库后台对tableName表进行插入 ...

  9. pytest+requests+Python3.7+yaml+Allure+Jenkins+docker实现接口自动化测试

    接口自动化测试框架(用例自动生成) 项目说明 本框架是一套基于pytest+requests+Python3.7+yaml+Allure+Jenkins+docker而设计的数据驱动接口自动化测试框架 ...

随机推荐

  1. js 自定义类

    将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...

  2. 蓝桥杯 第四届C/C++预赛真题(1) 高斯日记(数学题,年份处理)

    题目标题: 高斯日记 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯 ...

  3. Python_selenium之获取当前页面的href属性,id属性,图片信息和截全屏

    Python_selenium之获取当前页面的href属性,id属性,图片信息和截全屏 一.  获取当前页面的全部信息 1. 图片信息包括图片名称.图片大小等信息 2. 只需将图片信息打印出来(ima ...

  4. ASP.NET Web API 2中的属性路由(Attribute Routing)

    如何启用属性路由并描述属性路由的各种选项? Why Attribute Routing? Web API的第一个版本使用基于约定的路由.在这种类型的路由中,您可以定义一个或多个路由模板,这些模板基本上 ...

  5. Android 扁平化button

    View 创建 colors.xml 文件定义两个颜色 1. <resources> 2.     <color name="blue_pressed">@ ...

  6. Redis 连接失败redis Can't init enough connections amount!

    Can't init enough connections amount! Only 0 from 10 were initialized. Server: IP:6379 无法初始化足够的连接数量! ...

  7. boost::interprocess::managed_shared_memory(2)(std::deque)

    struct shareDataEx : shareData { int index; int total_size; }; typedef managed_shared_memory::segmen ...

  8. Google I/O 2013 – Volley: Easy, Fast Networking for Android

    1.什么是volley          Volley是Ficus Kirpatrick在Gooogle I/O 2013发布的一个处理和缓存网络请求的库,能使网络通信更快,更简单,更健壮.Volle ...

  9. docker 从容器中拷文件到宿主机器中

    sudo docker cp 1d051604e0ea:/root/data /home/developer/zhanghui/data

  10. 《从零开始学Swift》学习笔记(Day 55)——使用try?和try!区别

    原创文章,欢迎转载.转载请注明:关东升的博客 在使用try进行错误处理的时候,经常会看到try后面跟有问号(?)或感叹号(!),他们有什么区别呢? 1.使用try? try?会将错误转换为可选值,当调 ...