zoukankan      html  css  js  c++  java
  • 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()

    成功发送邮件:

  • 相关阅读:
    springMVC系列之(四) spring+springMVC+hibernate 三大框架整合(转)
    Java Web项目运行流程
    唯一识别码——UUID
    Map解析
    前端小技巧总结(三)
    前端小技巧总结(二)
    React学习总结(二)
    前端小技巧总结(一)
    React 学习总结(一)
    关于Java一些好的博客链接:
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4608027.html
Copyright © 2011-2022 走看看