Python +crontab定時備份目錄發送郵件

公司有一臺靜態頁面展現服務器僅供給客戶展現咱們作的項目,當時買的時候是最低配,也就是磁盤空間爲20G的系統盤,考慮到代碼量很小因此沒有另加磁盤,後來項目多了,就寫了個crontab 定時備份目錄。html

就這樣,這臺服務器穩健運行着。過了大半年,忽然有一天掛在該服務器上的wordpress登錄不了了。找了很久找不到問題。不經意之間看來下磁盤利用率才發現了問題。python

使用命令:linux

df -h

發現磁盤/dev/xvdal沒空間了!windows

 致使緩存與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壓縮文件時有個問題,壓縮到一半報錯:session

'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.htmlapp

 

三.發送帶附件的郵件

# 發送郵件
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很開就收到了,但上傳到服務器又報錯了:wordpress

/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()

 

成功發送郵件:

相關文章
相關標籤/搜索