Part of Slepp's ProjectsPastebinTURLImagebinFilebin
Feedback -- English French German Japanese
Create Upload Newest Tools Donate
Sign In | Create Account

Advertising

Python backup
2009 year 10 month 2 day Friday 22:41:14 MDT 

  1. import sys
  2. import os
  3. import os.path
  4. import tarfile
  5. import time
  6. import gzip
  7. import copy
  8. import shutil
  9.  
  10. Verbose = False
  11.  
  12. ignoreList = []
  13.  
  14. copiedFiles = 0
  15. skippedFiles = 0
  16. createdFolders = 0
  17. deletedFolders = 0
  18. deletedFiles = 0
  19. errors = 0
  20.  
  21. def removeDir(path):
  22.     '''
  23.     Remove dir and all subdirs with all subfiles
  24.     '''
  25.     for root, dirs, files in os.walk(path, False):
  26.         for f in files:
  27.             os.unlink(os.path.join(root, f))
  28.            
  29.         for d in dirs:
  30.             os.rmdir(os.path.join(root, d))
  31.            
  32.     os.rmdir(path)
  33.    
  34. def copyFile(fromFilename, toFilename):
  35.     '''
  36.     Function will copy file only if toFilename is different than fromFilename.
  37.     Size and modification date checked.
  38.    
  39.     Returns True if file been realy copied,
  40.     return False if there was no real copy (files seems the same)
  41.     '''
  42.     copy = True
  43.     if os.path.isfile(toFilename):
  44.         fromStat = os.stat(fromFilename)
  45.         toStat = os.stat(toFilename)
  46.  
  47.         copy = (fromStat.st_size != toStat.st_size) or (str(fromStat.st_mtime) != str(toStat.st_mtime))       
  48.  
  49.     # Copy file with stat info, including e.g. modification date
  50.     if copy:
  51.         shutil.copy2(fromFilename, toFilename)
  52.        
  53.     return copy
  54.  
  55. def createFolderStruct(path):
  56.     '''
  57.     Create struct (tree node) for folder tree
  58.     '''
  59.     return {'full_path': path,
  60.             'files': [],
  61.             'dirs': {}}
  62.  
  63. def makeDirTree(path, data):
  64.     '''
  65.     Creates folder tree in form of special struct
  66.     '''
  67.     for i in os.listdir(path):
  68.         newPath = os.path.join(path, i)
  69.  
  70.         # Ignore some folders from proccessing
  71.         if (i.lower() in ignoreList) or (newPath.lower() in ignoreList):
  72.             continue
  73.        
  74.         if os.path.isfile(newPath):
  75.             data['files'].append(i)
  76.         elif os.path.isdir(newPath):
  77.             data['dirs'][i] = createFolderStruct(newPath)
  78.            
  79.             makeDirTree(newPath, data['dirs'][i])
  80.            
  81. def copyFolder(srcDirs, outDirs):
  82.     '''
  83.     Copy folder from "left" to "right", given folders trees srcDirs and outDirs.
  84.     Right folder will be complete copy of left folder with minimum number of file operations
  85.     (don't copy file if it's already exists and hasn't been modified)
  86.     '''
  87.    
  88.     # Use global counters
  89.     global copiedFiles
  90.     global skippedFiles
  91.     global createdFolders
  92.     global deletedFolders
  93.     global deletedFiles
  94.     global errors   
  95.    
  96.     # Loop throught all src folders, s - current folder name
  97.     for s in srcDirs['dirs']:
  98.         # If src folder isn't exist in output folder
  99.         if s not in outDirs['dirs']:
  100.             # If there is file in output folder with name as folder in src folder - delete that file
  101.             if s in outDirs['files']:
  102.                 # Delete file s
  103.                 fullFilename = os.path.join(outDirs['full_path'], s)
  104.                 os.unlink(fullFilename)
  105.                 if Verbose:
  106.                     print('D %s' % fullFilename)
  107.                 deletedFiles += 1                                       
  108.                
  109.             outDirs['dirs'][s] = createFolderStruct(os.path.join(outDirs['full_path'], s))
  110.            
  111.             # Create output folder with src folder name               
  112.             fullPath = os.path.join(outDirs['full_path'], s)
  113.             os.mkdir(fullPath)
  114.             if Verbose:
  115.                 print('M [%s]' % fullPath)
  116.             createdFolders += 1
  117.  
  118.         # Go deep inside current folder
  119.         copyFolder(srcDirs['dirs'][s], outDirs['dirs'][s])
  120.    
  121.     # Remove folders from right, that don't exist on left
  122.     for o in outDirs['dirs']:
  123.         if o not in srcDirs['dirs']:
  124.             fullPath = os.path.join(outDirs['dirs'][o]['full_path'])
  125.             removeDir(fullPath)
  126.             if Verbose:
  127.                 print('D [%s]' % fullPath)
  128.             deletedFolders += 1               
  129.  
  130.     # Remove files from right, that don't exist on left
  131.     for o in outDirs['files']:
  132.         if o not in srcDirs['files']:
  133.             fullFilename = os.path.join(outDirs['full_path'], o)
  134.             os.unlink(fullFilename)
  135.             if Verbose:
  136.                 print('D %s' % fullFilename)
  137.             deletedFiles += 1           
  138.  
  139.     # Copy files from left to right
  140.     for s in srcDirs['files']:
  141.         fullFrom = os.path.join(srcDirs['full_path'], s)
  142.         fullTo = os.path.join(outDirs['full_path'], s)
  143.        
  144.         copied = copyFile(fullFrom, fullTo)
  145.         if copied:
  146.             c = 'C'
  147.             copiedFiles += 1
  148.         else:
  149.             c = '-'
  150.             skippedFiles += 1
  151.            
  152.         if Verbose and copied:
  153.             print('%s %s -> %s' % (c, fullFrom, fullTo))
  154.  
  155. if __name__ == "__main__":
  156.     if (len(sys.argv) < 2):
  157.         print("Usage: backup.py <output folder> [--verbose]")
  158.         print('E.g.: "backup.py d:\\dropbox\\my dropbox\\backup\\"')
  159.         exit(1)
  160.  
  161.     RootFoldersFile = "tobackup.lst"
  162.     IgnoreFoldersFile = "ignore.lst"
  163.     ExtraFile = "extra.lst"
  164.     OutputFolder = sys.argv[1]
  165.    
  166.     try:
  167.         Verbose = (sys.argv[2] == '--verbose')
  168.     except:
  169.         pass
  170.  
  171.     # Only mandatory file is RootFoldersFile, check that it exists
  172.     if (not os.path.isfile(RootFoldersFile)):
  173.         print("! %s doesn't exist" % RootFoldersFile)
  174.         exit(1)
  175.  
  176.     # Output folder should exist, or we should be able to create it
  177.     if not os.path.isdir(OutputFolder):
  178.         try:
  179.             os.makedirs(OutputFolder)
  180.         except:
  181.             print("! Can't create output folder %s" % OutputFolder)
  182.             exit(1)
  183.  
  184.     # Read root folders from file, skip empty lines
  185.     rootFolders = [i.strip() for i in open(RootFoldersFile, "r").readlines()]
  186.     if '' in rootFolders:
  187.         rootFolders.remove('')
  188.  
  189.     # Read list of folders that need to be ignored (if specified)
  190.     if (os.path.isfile(IgnoreFoldersFile)):
  191.         ignoreList = [i.strip().lower() for i in open(IgnoreFoldersFile, "r").readlines()]
  192.         if '' in ignoreList:
  193.             ignoreList.remove('')
  194.  
  195.     # Create folders trees for each input folder
  196.     for rootFolder in rootFolders:
  197.         inputTree = createFolderStruct(rootFolder)
  198.         makeDirTree(rootFolder, inputTree)
  199.  
  200.         # File will be placed under OutputFolder plus full path to src folder
  201.         # E.g. src folder d:\projects\python will be copied to folder q:\backup\d_\projects\python
  202.         #                 ^^^^^^^^^^^^^^^^^^                                    ^^^^^^^^^^^^^^^^^^           
  203.         outFolder = inputTree['full_path']
  204.         outFolder = outFolder.replace(':', '_')
  205.         outFolder = os.path.join(OutputFolder, outFolder)
  206.  
  207.         print('[%s] -> [%s]...' % (rootFolder, outFolder))
  208.            
  209.         if not os.path.isdir(outFolder):
  210.             try:
  211.                 os.makedirs(outFolder)
  212.                 print('M [%s]' % outFolder)
  213.             except:
  214.                 print("! Can't create output folder [%s]" % outFolder)
  215.                 print("! Skip input folder %s" % rootFolder)
  216.                 errors += 1
  217.                 continue
  218.        
  219.         # Make folder tree for real output folder
  220.         outputTree = createFolderStruct(outFolder)       
  221.         makeDirTree(outFolder, outputTree)
  222.        
  223.         # Copy input folder to output folder
  224.         copyFolder(inputTree, outputTree)
  225.        
  226.     # Read list of extra files
  227.     if (os.path.isfile(ExtraFile)):
  228.         extraList = [i.strip().lower() for i in open(ExtraFile, "r").readlines()]
  229.         if '' in extraList:
  230.             extraList.remove('')
  231.        
  232.         print('Extra files...')
  233.        
  234.         for file in extraList:
  235.             outFileDir = os.path.join(OutputFolder, os.path.dirname(file).replace(':', '_'))
  236.             if not os.path.isdir(outFileDir):
  237.                 try:
  238.                     os.makedirs(outFileDir)
  239.                 except:
  240.                     print("! Can't create output folder [%s]. Skip extra file %s" % (outFileDir, file))
  241.                     errors += 1
  242.                     continue
  243.        
  244.             fullTo = os.path.join(outFileDir, os.path.basename(file))
  245.        
  246.             copied = copyFile(file, fullTo)
  247.             if copied:
  248.                 c = 'C'
  249.                 copiedFiles += 1
  250.             else:
  251.                 c = '-'
  252.                 skippedFiles += 1
  253.                
  254.             if Verbose and copied:
  255.                 print('%s %s -> %s' % (c, file, fullTo))
  256.            
  257.     print('==============================')
  258.     print('Copied file(s):    %d' % copiedFiles)
  259.     print('Skipped file(s):   %d' % skippedFiles)
  260.     print('Created folder(s): %d' % createdFolders)
  261.     print('Deleted folder(s): %d' % deletedFolders)
  262.     print('Deleted file(s):   %d' % deletedFiles)
  263.     print('Errors:            %d' % errors)
  264.     print('==============================')   
  265.     print("Done")

Paste Details

advertising

Update the Post

Either update this post and resubmit it with changes, or make a new post.

You may also comment on this post.

update paste below
details of the post (optional)

Note: Only the paste content is required, though the following information can be useful to others.

Save name / title?

(space separated, optional)



Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.