#!/usr/bin/env python #email_back.py was written by Rusty Japikse, 2006. #This program backs up a directory into a tar archive with bz2 compression #and then emails the archive to a list of email addresses. #The maximum email size can be set (currently 9meg) and the resulting archive will #split into sub-archives using the 'split' command. These archives are then #emailed to the list of recipeints. After they are sent, the archive(s) are then #deleted. This script is ideal for backing up a simple website (see www.shamrock5k.com) #at a predefined interval (using cron). # #As this script will likely contain user credentials (username and password for #sending emails), the script should be placed above the root of your website # #This and additional scripts may be found at www.japikse.com class archive: def __init__(self): #########CONFIGURATION PARAMETERS############################################ #message info self.desc='acme.com' self.from_email='Road Runner ' #alternately, a list of email addresses may be used #to_email=['backup@acme.com','Willie Coyote '] self.to_emails=['rusty@japikse.com'] self.subject='%s backup' %self.desc self.message='''This is an automatic backup of the $DESC website. This backup is $INSTANCE of $SUM emails, containing the files from $DESC. If there is more than one file, the attached files may be rejoined to form a single compressed archive (.tbz). To rejoin the files, use the 'cat' command on a Linux or Unix (Mac OS X will work) computer. This command should be used such as: cat backup_aa backup_ab backup_ac backup_ad backup_ae > backup.tbz This will then result in a single compressed archive file named, backup.tbz. This file can then be uncompressed using the tar command (tar -xjf backup.tbz). The tar command can be run from a Linux / Unix computer (again, a Mac will do this) or it may be possible in this case to extract the files using Winzip on a windows computer. The archived files should contain everything needed to recreate the original files. Rusty '''.replace('$DESC',self.desc) self.chunk_size=9 #in megabytes, the maximum file size allowed before the files are broken into chunks (*nix split command) for emailing self.archive_prefix='backup' #server specifics self.username='road.runer@acme.com' self.password='delayed_gravity' self.server='smtp.acme.com' #directory to be backed up self.backup_dir='./acme.com' ############################################################################# import time, os t=time.gmtime() t='-'.join([str(t[1]),str(t[2]),str(t[0])]) self.subject+=' ($INSTANCE of $SUM %s)' %t def email(self): #email the archives num_files=len(self.__back_files) for i in range(num_files): f_name=self.__back_files[i] f_contents=open(f_name,'r').read() self.subject=self.subject.replace('$INSTANCE',str(i+1)).replace('$SUM',str(num_files)) self.message=self.message.replace('$INSTANCE',str(i+1)).replace('$SUM',str(num_files)) for j in self.to_emails: self.__mailer(j, f_name, f_contents) def __mailer(self, to_email, f_name, f_contents): #note: this function was mostly cribbed from the internet import StringIO, MimeWriter, smtplib, base64 message = StringIO.StringIO() writer = MimeWriter.MimeWriter(message) writer.addheader('MIME-Version', '1.0') writer.addheader('Subject', self.subject) # writer.addheader('To', to_email) # get ready to send attachment writer.startmultipartbody('mixed') # start off with a text/plain part part = writer.nextpart() body = part.startbody('text/plain') body.write(self.message) # ............................ # add backup attachment # ............................ part = writer.nextpart() part.addheader('Content-Transfer-Encoding', 'base64') body = part.startbody('application/tbz; name=%s' % f_name) # attached archive body.write(base64.encodestring( f_contents )) # finish off writer.lastpart() # .................................................. # send the mail # . if user supplied userid/password then deal w/it # .................................................. smtp = smtplib.SMTP(self.server) if self.username: smtp.ehlo() smtp_userid64 = base64.encodestring(self.username) smtp.docmd("auth", "login " + smtp_userid64[:-1]) if self.password: smtp_pass64 = base64.encodestring(self.password) smtp.docmd(smtp_pass64[:-1]) for to_email in self.to_emails: smtp.sendmail(self.from_email, to_email, message.getvalue()) #smtp.sendmail( from address, to address, message body) smtp.quit() def make_archives(self): #make the archives, split them into predefined chunks if needed (see chunk_size variable) from stat import ST_SIZE import os os.popen('tar -cjf %s.tbz %s' %(self.archive_prefix, self.backup_dir)) #create a tbz archive of the website if float(os.stat('%s.tbz' %self.archive_prefix)[ST_SIZE])/(1024*1024) >= self.chunk_size: os.popen('split -b %im %s.tbz %s_' %(self.chunk_size, self.archive_prefix, self.archive_prefix)) #split the archive into chunks (for emailing) import glob os.remove('%s.tbz' %self.archive_prefix) self.__back_files=glob.glob('./%s_*' %self.archive_prefix) else: self.__back_files=['%s.tbz' %self.archive_prefix] def remove_archives(self): #remove the newly created archives import os for i in self.__back_files: os.remove(i) if __name__=='__main__': a=archive() a.make_archives() a.email() a.remove_archives()