Return to Snippet

Revision: 9925
at November 30, 2008 17:49 by mjsmagalhaes


Updated Code
# BACKUP.PY
#    Examples:
#
#    python backup.py
#
#    Help:
#    python backup.py --help
#
#    Custom config file:
#    python backup.py -c custom.xml
#    python backup.py --configFile=custom.xml
#
#    Author: mjsmagalhaes
#    E-mail: mjsmagalhaes (\at) gmail (\dot) com

import getopt
import os
import sys
import smtplib
import tarfile
import time
import zipfile

import xml.dom.minidom as xml

from email import MIMEBase
from email import MIMEMultipart
from email import Encoders

#####################################
def usage():
    print 'BACKUP.PY    Automatic backup script'
    print '    Options:'
    print ''
    print '    -c, --config-file :  Load a xml file with backup settings'
    print '              default :  config.xml'
    print ''
    print '    -C, --compression :  bzip2 or zip(future)'
    print '              default :  gzip'
    print ''
    print '    -h, --help        :  Display program usage'
    print ''
    print '    ______________________________________________'
    print '    Settings Files:'
    print ''
    print '    -- BACKUP Nodes --'
    print '    Multiplicity: 0 or more'
    print '    Attributes:'
    print '        pathToCompress  -  File or directory to include in compressed file'
    print '        file_prefix     -  Compressed filename prefix'
    print '        file_suffix     -  Compressed filename suffix. Google dont like .tar.gz'
    print '        send            -  Indicates if the compressed file should be attached or not'
    print ''
    print '    Compressed file names are file_prefix + timestamp + file_suffix'
    print ''
    print '    -- MAIL Nodes --'
    print '    Multiplicity: 0 or more'
    print '    Attributes:'
    print '        from            -  email sender'
    print '        to              -  email receiver'
    print '        subject_prefix  -  messages\'subject are subject_prefix + timestamp'
    print ''
    print '    Child Nodes:'
    print '        -- FILE Nodes --'
    print '        Multiplicity: 0 or more'
    print '        Attributes:'
    print '            path        -  Points to a path to be attached in the message'
    print ''
    print ''
    print "    Author: mjsmagalhaes
    print "    E-mail: mjsmagalhaes (\\at) lps (\\dot) ufrj (\\dot) br"

#####################################

def calcDirSize(arg, dir, files):
    for file in files:
        stats = os.stat(os.path.join(dir, file))
        size = stats[6]
        arg.append(size)

def getDirSize(dir):
    sizes = []
    os.path.walk(dir, calcDirSize, sizes)
    total = 0
    for size in sizes:
        total = total + size
    return total
       
def forHumans(total):
    if total > 1073741824:
        return (round(total/1073741824.0, 2), 'GB')
    if total > 1048576:
        return (round(total/1048576.0, 2), 'MB')
    if total > 1024:
        return (round(total/1024.0, 2), 'KB')
    return (total, 'bytes')

def compress(pathToCompress, fileName, compressionMethod):
   
    if compressionMethod in ('bz2','gz'):
        tar = tarfile.open(fileName, 'w:'+compressionMethod)
       
    elif compressionMethod == 'zip':
        print 'Not supported yet'
        print 'Using gzip'
           
        compressionMethod = 'gz'
        #tar = zipfile.ZipFile(fileName,'w')
        tar = tarfile.open(fileName, 'w:'+compressionMethod)
    else:
        compressionMethod = 'gz'
        tar = tarfile.open(fileName, 'w:'+compressionMethod)
       
   
    print 'Compressing ...'
    print pathToCompress
    print 'in ' + fileName + ' with ' + compressionMethod
   
    #print 'Compression Method - ' + compressionMethod
   
    r_rawSize = 0;
   
    for path in pathToCompress:
       
        if compressionMethod == 'bz2':
            tar.add(path)
           
        elif compressionMethod == 'zip':
            tar.write(path)
           
        else:
            tar.add(path)
        #end - else
   
        if os.path.isdir(path):
            r_rawSize += getDirSize(path)
        else:
            r_rawSize += os.path.getsize(path);
       
    # end - for
   
    tar.close();
   
    print r_rawSize
   
    r_tarSize = os.stat(fileName)[6]
   
    rawSize = forHumans(r_rawSize);
    tarSize = forHumans(r_tarSize);
   
    #print 'Compressed: ' + pathToCompress + ' in ' + fileName
    print '  Compressed size: ' + str(tarSize[0]) + tarSize[1]
    print '  Original Size: ' + str(rawSize[0]) + rawSize[1]
    print '  Compression Rate: ' + str(100 - 100*r_tarSize/r_rawSize) + '%'

def mail(email, att):
    msg = MIMEMultipart.MIMEMultipart();

    msg['subject']=email['subject']
    msg['from']=email['from']
    msg['to']=email['to']
   
    for path in att:
        print 'Attaching ' + path
        fp = open(path, 'rb')
        att_file = MIMEBase.MIMEBase('application','octet-stream')
        att_file.set_payload(fp.read())
        fp.close()
        Encoders.encode_base64(att_file)
        att_file.add_header('Content-Disposition', 'attachment', filename=path)
        msg.attach(att_file)
   
    print 'Sending mail - ' + msg['subject']
    print 'from: ' + msg['from']
    print 'to: ' + msg['to']
   
    s = smtplib.SMTP()
    s.connect(email['server'], email['port'])
   
    s.ehlo()
   
    if not(email['tls'] in ('no', 'No', 'NO')):
        s.starttls()
        s.ehlo()
        s.login(email['user'],email['passwd'])
   
    s.sendmail(msg['from'],msg['to'],msg.as_string())
    s.quit()

def main(argv):
    #####################################
    # Resolve config
   
    pathToCompress = []
    fileToSend = []
   
    #####################################
    # Defaults
    settingsFile = 'config.xml'
    compressionMethod = 'gzip'
   
    #####################################
    # Parse cmd line options
    try:
        opts, args = getopt.getopt(argv, "c:hC:", ["config-file=",'help','compression='])
    except getopt.GetoptError:
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
        elif opt in ("-c", "--config-file"):
            settingsFile = arg
        elif opt in ("-C", "--compression"):
            compressionMethod = arg
   
    #####################################
    # Timestamp
    t = time.localtime()
    str_t = str(t[0]) + '_' + str(t[1]) + '_' + str(t[2])
   
    #####################################
    # Parse settings
    doc = xml.parse(settingsFile)
   
    #0 ->
    for node in doc.getElementsByTagName('BACKUP'):
        # transform unicode to ascii
        fileName = str(node.getAttribute('file_prefix') + str_t + node.getAttribute('file_suffix'))
       
        #0 ->
        for fileNode in node.getElementsByTagName('COMPRESS'):
            pathToCompress.append(str(fileNode.getAttribute('path')))
       
        #####################################
        # Compress
       
        compress(pathToCompress, fileName, compressionMethod)
   
        if not(node.getAttribute('send') in ('no','No','NO')):
            fileToSend.append(fileName);
           
        del pathToCompress[:]
   
    #####################################
    # Mail
   
    #0 ou 1
    for node in doc.getElementsByTagName('MAIL'):
        message = {}
        files = []
       
        message['from'] = str(node.getAttribute('from'))
        message['to'] = str(node.getAttribute('to'))
        message['subject'] = str(node.getAttribute('subject_prefix')) + str_t
       
        for serverNode in node.getElementsByTagName('SERVER'):
            message['server'] = str(serverNode.getAttribute('addr'))
            message['port'] = str(serverNode.getAttribute('port'))
            message['tls'] = str(serverNode.getAttribute('use_tls'))
            message['user'] = str(serverNode.getAttribute('login'))
            message['passwd'] = str(serverNode.getAttribute('password'))
       
        ## Juntar server + port
       
        #0 ->
        for fileNode in node.getElementsByTagName('FILE'):
            files.append(str(fileNode.getAttribute('path')))
       
        mail(message, fileToSend)
       
        print 'Done.'


if __name__ == "__main__":
    main(sys.argv[1:])

Revision: 9924
at November 30, 2008 14:48 by mjsmagalhaes


Initial Code
# BACKUP.PY
#    Examples:
#
#    python backup.py
#
#    Help:
#    python backup.py --help
#
#    Custom config file:
#    python backup.py -c custom.xml
#    python backup.py --configFile=custom.xml
#
#    Author: mjsmagalhaes
#    E-mail: mjsmagalhaes (\at) gmail (\dot) com

import getopt
import os
import sys
import smtplib
import tarfile
import time
import zipfile

import xml.dom.minidom as xml

from email import MIMEBase
from email import MIMEMultipart
from email import Encoders

#####################################
def usage():
    print 'BACKUP2.PY    Automatic backup script'
    print '    Options:'
    print ''
    print '    -c, --config-file :  Load a xml file with backup settings'
    print '              default :  config.xml'
    print ''
    print '    -C, --compression :  bzip2 or zip(future)'
    print '              default :  gzip'
    print ''
    print '    -h, --help        :  Display program usage'
    print ''
    print '    ______________________________________________'
    print '    Settings Files:'
    print ''
    print '    -- BACKUP Nodes --'
    print '    Multiplicity: 0 or more'
    print '    Attributes:'
    print '        pathToCompress  -  File or directory to include in compressed file'
    print '        file_prefix     -  Compressed filename prefix'
    print '        file_suffix     -  Compressed filename suffix. Google dont like .tar.gz'
    print '        send            -  Indicates if the compressed file should be attached or not'
    print ''
    print '    Compressed file names are file_prefix + timestamp + file_suffix'
    print ''
    print '    -- MAIL Nodes --'
    print '    Multiplicity: 0 or more'
    print '    Attributes:'
    print '        from            -  email sender'
    print '        to              -  email receiver'
    print '        subject_prefix  -  messages\'subject are subject_prefix + timestamp'
    print ''
    print '    Child Nodes:'
    print '        -- FILE Nodes --'
    print '        Multiplicity: 0 or more'
    print '        Attributes:'
    print '            path        -  Points to a path to be attached in the message'
    print ''
    print '    ______________________________________________'
    print '    Version: 6'
    print '    Last Modification: Thursday, November 8, 2007 8:44:31 AM BRST'
    print ''
    print "    Author: Marcos Jose Sant\'Anna Magalhaes"
    print "    E-mail: mjsmagalhaes (\\at) lps (\\dot) ufrj (\\dot) br"

#####################################

def calcDirSize(arg, dir, files):
    for file in files:
        stats = os.stat(os.path.join(dir, file))
        size = stats[6]
        arg.append(size)

def getDirSize(dir):
    sizes = []
    os.path.walk(dir, calcDirSize, sizes)
    total = 0
    for size in sizes:
        total = total + size
    return total
       
def forHumans(total):
    if total > 1073741824:
        return (round(total/1073741824.0, 2), 'GB')
    if total > 1048576:
        return (round(total/1048576.0, 2), 'MB')
    if total > 1024:
        return (round(total/1024.0, 2), 'KB')
    return (total, 'bytes')

def compress(pathToCompress, fileName, compressionMethod):
   
    if compressionMethod in ('bz2','gz'):
        tar = tarfile.open(fileName, 'w:'+compressionMethod)
       
    elif compressionMethod == 'zip':
        print 'Not supported yet'
        print 'Using gzip'
           
        compressionMethod = 'gz'
        #tar = zipfile.ZipFile(fileName,'w')
        tar = tarfile.open(fileName, 'w:'+compressionMethod)
    else:
        compressionMethod = 'gz'
        tar = tarfile.open(fileName, 'w:'+compressionMethod)
       
   
    print 'Compressing ...'
    print pathToCompress
    print 'in ' + fileName + ' with ' + compressionMethod
   
    #print 'Compression Method - ' + compressionMethod
   
    r_rawSize = 0;
   
    for path in pathToCompress:
       
        if compressionMethod == 'bz2':
            tar.add(path)
           
        elif compressionMethod == 'zip':
            tar.write(path)
           
        else:
            tar.add(path)
        #end - else
   
        if os.path.isdir(path):
            r_rawSize += getDirSize(path)
        else:
            r_rawSize += os.path.getsize(path);
       
    # end - for
   
    tar.close();
   
    print r_rawSize
   
    r_tarSize = os.stat(fileName)[6]
   
    rawSize = forHumans(r_rawSize);
    tarSize = forHumans(r_tarSize);
   
    #print 'Compressed: ' + pathToCompress + ' in ' + fileName
    print '  Compressed size: ' + str(tarSize[0]) + tarSize[1]
    print '  Original Size: ' + str(rawSize[0]) + rawSize[1]
    print '  Compression Rate: ' + str(100 - 100*r_tarSize/r_rawSize) + '%'

def mail(email, att):
    msg = MIMEMultipart.MIMEMultipart();

    msg['subject']=email['subject']
    msg['from']=email['from']
    msg['to']=email['to']
   
    for path in att:
        print 'Attaching ' + path
        fp = open(path, 'rb')
        att_file = MIMEBase.MIMEBase('application','octet-stream')
        att_file.set_payload(fp.read())
        fp.close()
        Encoders.encode_base64(att_file)
        att_file.add_header('Content-Disposition', 'attachment', filename=path)
        msg.attach(att_file)
   
    print 'Sending mail - ' + msg['subject']
    print 'from: ' + msg['from']
    print 'to: ' + msg['to']
   
    s = smtplib.SMTP()
    s.connect(email['server'], email['port'])
   
    s.ehlo()
   
    if not(email['tls'] in ('no', 'No', 'NO')):
        s.starttls()
        s.ehlo()
        s.login(email['user'],email['passwd'])
   
    s.sendmail(msg['from'],msg['to'],msg.as_string())
    s.quit()

def main(argv):
    #####################################
    # Resolve config
   
    pathToCompress = []
    fileToSend = []
   
    #####################################
    # Defaults
    settingsFile = 'config.xml'
    compressionMethod = 'gzip'
   
    #####################################
    # Parse cmd line options
    try:
        opts, args = getopt.getopt(argv, "c:hC:", ["config-file=",'help','compression='])
    except getopt.GetoptError:
        usage()
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-h", "--help"):
            usage()
            sys.exit()
        elif opt in ("-c", "--config-file"):
            settingsFile = arg
        elif opt in ("-C", "--compression"):
            compressionMethod = arg
   
    #####################################
    # Timestamp
    t = time.localtime()
    str_t = str(t[0]) + '_' + str(t[1]) + '_' + str(t[2])
   
    #####################################
    # Parse settings
    doc = xml.parse(settingsFile)
   
    #0 ->
    for node in doc.getElementsByTagName('BACKUP'):
        # transform unicode to ascii
        fileName = str(node.getAttribute('file_prefix') + str_t + node.getAttribute('file_suffix'))
       
        #0 ->
        for fileNode in node.getElementsByTagName('COMPRESS'):
            pathToCompress.append(str(fileNode.getAttribute('path')))
       
        #####################################
        # Compress
       
        compress(pathToCompress, fileName, compressionMethod)
   
        if not(node.getAttribute('send') in ('no','No','NO')):
            fileToSend.append(fileName);
           
        del pathToCompress[:]
   
    #####################################
    # Mail
   
    #0 ou 1
    for node in doc.getElementsByTagName('MAIL'):
        message = {}
        files = []
       
        message['from'] = str(node.getAttribute('from'))
        message['to'] = str(node.getAttribute('to'))
        message['subject'] = str(node.getAttribute('subject_prefix')) + str_t
       
        for serverNode in node.getElementsByTagName('SERVER'):
            message['server'] = str(serverNode.getAttribute('addr'))
            message['port'] = str(serverNode.getAttribute('port'))
            message['tls'] = str(serverNode.getAttribute('use_tls'))
            message['user'] = str(serverNode.getAttribute('login'))
            message['passwd'] = str(serverNode.getAttribute('password'))
       
        ## Juntar server + port
       
        #0 ->
        for fileNode in node.getElementsByTagName('FILE'):
            files.append(str(fileNode.getAttribute('path')))
       
        mail(message, fileToSend)
       
        print 'Done.'


if __name__ == "__main__":
    main(sys.argv[1:])

Initial URL


Initial Description
This source code uses the xml file posted here(http://snipplr.com/view/4138/backup-script2--confg-file/) to know which file should be sent and mailing configuration.

Initial Title
Backup and File Mailing

Initial Tags
mail, backup, xml

Initial Language
Python