Python +crontab定时备份目录发送邮件

公司有一台静态页面展示服务器仅供给客户展示我们做的项目,当时买的时候是最低配,也就是磁盘空间为20G的系统盘,考虑到代码量很小所以没有另加磁盘,后来项目多了,就写了个crontab 定时备份目录。

就这样,这台服务器稳健运行着。过了大半年,突然有一天挂在该服务器上的wordpress登陆不了了。找了好久找不到问题。不经意之间看来下磁盘利用率才发现了问题。

使用命令:

df -h

发现磁盘/dev/xvdal没空间了!

 导致缓存与session无法保存。想起来可能是备份目录导致的,10几个项目,一个项目10Mb左右每天备份一次,半年时间:10*10*150=15GB(项目是逐渐加进去的),删除某一天的备份,重新登录wordpress真给登录上去了。

如果知道了是备份的问题,定期删除备份文件也行。但爱折腾的人肯定是闲不下来的。干嘛要备份到服务器中呢,完全可以打包把备份文件通过邮件进行备份呀。就这样定时Python备份目录发送邮件功能变成了“现实”。

一.crontab定时

 

crontab  -e
30 1 * * *   /root/crontab-save-code.py                           #每天凌晨1点30分执行备份目录 

 

二.打包目录

# 压缩目录toZip
def DirToZip(dirname, zipfilename):
    filelist = []
    if os.path.isfile(dirname):
        filelist.append(dirname)
    else:
        for root, dirs, files in os.walk(dirname):
            for name in files:
                filelist.append(os.path.join(root, name))

    try:
        zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED)
        for tar in filelist:
            arcname = tar[len(dirname):]
            try:  # 异常出现在文件名为中文
                zf.write(tar, arcname)
            except:
                zf.write(tar, repr(arcname)[1:-1])
        zf.close()
        return True
    except Exception as e:
        return False

生成ZIP压缩文件时有个问题,压缩到一半报错:

'utf-8' codec can't encode character '\udcb8' in position 41: surrogates not allowed

编码的问题,文件使用中文名导致的,参考: http://python3-cookbook.readthedocs.io/zh_CN/latest/c05/p15_printing_bad_filenames.html

 

三.发送带附件的邮件

# 发送邮件
def sendMail():
    print(ZipName)
    # 输入Email地址和口令:
    from_addr = 'admin@****.com'
    password = '123456'
    # 输入收件人地址:
    to_addr = '*****@163.com'
    # 输入SMTP服务器地址:
    smtp_server = 'smtp.exmail.qq.com'

    # 邮件对象:
    msg = MIMEMultipart()
    msg['From'] = _format_addr('自动备份项目代码 <%s>' % from_addr)
    msg['To'] = _format_addr('Web管理员 <%s>' % to_addr)
    msg['Subject'] = Header('来自SMTP-定时备份……', 'utf-8').encode()

    # 邮件正文是MIMEText:
    msg.attach(MIMEText('自动备份项目代码 file...', 'plain', 'utf-8'))

    # 添加附件就是加上一个MIMEBase,从本地读取一个图片:
    with open(filePath, 'rb') as f:
        # 设置附件的MIME和文件名,这里是png类型:
        mime = MIMEBase('image', 'png', filename='test.png')
        # 加上必要的头信息:
        mime.add_header('Content-Disposition', 'attachment', filename=ZipName)
        mime.add_header('Content-ID', '<0>')
        mime.add_header('X-Attachment-Id', '0')
        # 把附件的内容读进来:
        mime.set_payload(f.read())
        # 用Base64编码:
        encoders.encode_base64(mime)
        # 添加到MIMEMultipart:
        msg.attach(mime)
    try:
        server = smtplib.SMTP(smtp_server, 25)
        # server.set_debuglevel(1)
        server.login(from_addr, password)
        a = server.sendmail(from_addr, [to_addr], msg.as_string())
        return True
    except Exception:
        return False

 

四. 发送成功,删除压缩包

# 删除文件
def delFile():
    if os.path.exists(filePath):
        os.remove(filePath)

 

经测试,在windows很开就收到了,但上传到服务器又报错了:

/usr/bin/python^M: bad interpreter: No such file

是因为windows行结尾和linux行结尾标识不同造成的。使用notepad++把文件转换为UNIX格式。

 

完整代码:

#!/usr/bin/python
# coding=utf-8
import os, os.path
import zipfile
from email import encoders
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
import smtplib
import datetime
import os

ZipName = datetime.datetime.now().strftime('%Y-%m-%d@%H.%M') + '.zip'
filePath = "/home/wwwroot/tools/backup/" + ZipName


# 压缩目录toZip
def DirToZip(dirname, zipfilename):
    filelist = []
    if os.path.isfile(dirname):
        filelist.append(dirname)
    else:
        for root, dirs, files in os.walk(dirname):
            for name in files:
                filelist.append(os.path.join(root, name))

    try:
        zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED)
        for tar in filelist:
            arcname = tar[len(dirname):]
            try:  # 异常出现在文件名为中文
                zf.write(tar, arcname)
            except:
                zf.write(tar, repr(arcname)[1:-1])
        zf.close()
        return True
    except Exception as e:
        return False


# 格式字符串
def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))


# 发送邮件
def sendMail():
    print(ZipName)
    # 输入Email地址和口令:
    from_addr = 'admin@****.com'
    password = '123456'
    # 输入收件人地址:
    to_addr = '****@163.com'
    # 输入SMTP服务器地址:
    smtp_server = 'smtp.exmail.qq.com'

    # 邮件对象:
    msg = MIMEMultipart()
    msg['From'] = _format_addr('自动备份项目代码 <%s>' % from_addr)
    msg['To'] = _format_addr('Web管理员 <%s>' % to_addr)
    msg['Subject'] = Header('来自SMTP-定时备份……', 'utf-8').encode()

    # 邮件正文是MIMEText:
    msg.attach(MIMEText('自动备份项目代码 file...', 'plain', 'utf-8'))

    # 添加附件就是加上一个MIMEBase,从本地读取一个图片:
    with open(filePath, 'rb') as f:
        # 设置附件的MIME和文件名,这里是png类型:
        mime = MIMEBase('image', 'png', filename='test.png')
        # 加上必要的头信息:
        mime.add_header('Content-Disposition', 'attachment', filename=ZipName)
        mime.add_header('Content-ID', '<0>')
        mime.add_header('X-Attachment-Id', '0')
        # 把附件的内容读进来:
        mime.set_payload(f.read())
        # 用Base64编码:
        encoders.encode_base64(mime)
        # 添加到MIMEMultipart:
        msg.attach(mime)
    try:
        server = smtplib.SMTP(smtp_server, 25)
        # server.set_debuglevel(1)
        server.login(from_addr, password)
        a = server.sendmail(from_addr, [to_addr], msg.as_string())
        return True
    except Exception:
        return False


# 删除文件
def delFile():
    if os.path.exists(filePath):
        os.remove(filePath)


if __name__ == '__main__':
    zipfile = DirToZip(r'/home/wwwroot/www',  filePath)
    if zipfile:
        sending = sendMail()
        if sending:
            delFile()

 

成功发送邮件:

 

转载于:https://www.cnblogs.com/dcb3688/p/4608027.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值