Author Topic: [Python] backup downloader  (Read 467 times)

0 Members and 1 Guest are viewing this topic.

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
[Python] backup downloader
« on: September 07, 2015, 09:11:08 pm »
I have several places to grab backups from and one place to store them – I don’t use mainstream cloud services (maybe I should…?), instead I store those onto my external drive.
Some of those places include web hosts, so I made this python script to grab ready-made backup archives and mirror some of the sites for me.
I wrote about my backup process on my blog here.
And here's a script I made for this:

Code: (python) [Select]
#!/usr/local/bin/python
'''
    Date: 2015.08.02
    Author: Kulverstukas
    Website: 9v.lt; evilzone.org
    Description:
        Downloads backup files from /backups in set hosts
        and downloads whole website content from defined website.
'''

import os
import sys
import time
import shutil
import zipfile
import ftputil
from ftplib import FTP

#-------------------------------------------------------
# where to put everything
rootFolder = 'webhost_backups'

# configuration of as many webshosts as you have
webhosts = [
    {'folder' : 'somesite.lt', # where to store your files
     'address' : 'somesite.lt', # URL of your website
     'username' : 'lorem', # FTP username
     'password' : 'ipsum', # FTP password
     'backup_path' : '/backups', # usually this is where backups are stored on the server
     'mirror' : True}, # should mirror the whole website starting from root
     
     {'folder' : 'subdomain.domain.com',
     'address' : 'subdomain.domain.com',
     'username' : 'lorem',
     'password' : 'ipsum',
     'backup_path' : '/backups',
     'mirror' : False}
]
#-------------------------------------------------------
# create folders if they don't exist already
if not os.path.exists(rootFolder) or not os.path.isdir(rootFolder):
    os.mkdir(rootFolder)
#-------------------------------------------------------
# replace symbols with encoded equivalents
def makeFriendlyFilename(input):
    badSymbols = {'<' : '%3C',
                  '>' : '%3E',
                  ':' : '%3A',
                  '"' : '%22',
                  '|' : '%7C',
                  '?' : '%3F',
                  '*' : '%2A'}
    i = ''
    for i in badSymbols.keys():
        input = input.replace(i, badSymbols[i]);
    return input
#-------------------------------------------------------
def zipdir(path, zipname):
    zipf = zipfile.ZipFile(zipname, 'w')
    for root, dirs, files in os.walk(path):
        for dir in dirs:
            zipf.write(os.path.join(root, dir))
        for file in files:
            zipf.write(os.path.join(root, file))
    zipf.close()
#-------------------------------------------------------
# download all of the files from FTP
def mirrorFtp():
    for config in webhosts:
        if config['mirror']:
            today = time.strftime("%Y-%m-%d")
            mirrorName = config['folder']+'_mirror_'+today
            localMirrorRoot = os.path.join(rootFolder, config['folder'], mirrorName)
            if not os.path.exists(localMirrorRoot) or not os.path.isdir(localMirrorRoot):
                os.makedirs(localMirrorRoot)
               
            ftp = ftputil.FTPHost(config['address'], config['username'], config['password'])
            for root, dirs, files in ftp.walk('/'):
                for dir in dirs:
                    try:
                        os.mkdir(os.path.join(localMirrorRoot, root[1:], dir))
                    except:
                        pass
                for file in files:
                    try:
                        ftp.download(root+'/'+file, os.path.join(localMirrorRoot, root[1:], makeFriendlyFilename(file)))
                    except:
                        print root+'/'+file
            zipdir(localMirrorRoot, localMirrorRoot+'.zip')
            shutil.rmtree(localMirrorRoot)
#-------------------------------------------------------
# download backup files made by DirectAdmin
def getBackupFiles():
    ftp = FTP()
    for config in webhosts:
        if not os.path.exists(rootFolder+'/'+config['folder']) or not os.path.isdir(rootFolder+'/'+config['folder']):
            os.mkdir(rootFolder+'/'+config['folder'])
        try:
            ftp.connect(config['address'])
            ftp.login(config['username'], config['password'])
            ftp.cwd(config['backup_path'])
            filesToDl = ftp.nlst();
            for file in filesToDl:
                if (file not in ['.', '..']):
                    ftp.retrbinary('RETR '+file, open(rootFolder+'/'+config['folder']+'/'+file, 'wb').write)
                    try:
                        # comment this out if you want to keep backup archives on the server
                        ftp.delete(file)
                    except:
                        pass
            ftp.quit()
        except:
            pass
#-------------------------------------------------------

getBackupFiles()
mirrorFtp()

#-------------------------------------------------------