Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2019
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.13 KB | None | 0 0
  1. # courg_dpatch.py
  2. # Generate a delta of two directories using Google's Courgette
  3. #
  4. # Copyright (C) 2007  National Fitness Financial Systems
  5. #   Written by Steven Willoughby (stevenw _at_ nffs _dot_ com)
  6. # Adapted with some script modifications by
  7. #   Puligheddu Karsten Sascha (fwiffo _at_ ircom _dot_ net)
  8. # Conversion from Perl to Python with some additional changes
  9. #   by nBurn
  10. #
  11. # This program is free software; you can redistribute it and/or
  12. # modify it under the terms of the GNU General Public License
  13. # as published by the Free Software Foundation; either version 2
  14. # of the License, or (at your option) any later version.
  15. #
  16. # This program is distributed in the hope that it will be useful,
  17. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. # GNU General Public License for more details.
  20. #
  21. # You should have received a copy of the GNU General Public License
  22. # along with this program; if not, write to the Free Software
  23. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  24.  
  25. import os, re, sys, shutil, subprocess
  26. from timeit import default_timer
  27. patch_error = False
  28. verbose = False
  29. courgette = r"path\\to\\courgette.executable"  # replace with local path
  30.  
  31. success_marker = "courgette_completed"
  32. deleted_files = "DELETED"
  33. total_size = 0
  34. delta_size = 0
  35. file2pat = ''
  36.  
  37.  
  38. def print_usage_and_exit():
  39.     print("Usage:\n" +
  40.         "  courg_dpatch [-v] delta old new patch_to_make\n" +
  41.         "  courg_dpatch [-v] patch patch_location old patch_output\n")
  42.     sys.exit()
  43.  
  44.  
  45. def main():
  46.     global verbose, patch_error, success_marker
  47.     global total_size, delta_size
  48.     start = default_timer()
  49.  
  50.     if len(sys.argv) == 6:
  51.         if sys.argv[1] in ('-v', '--v', '-verbose', '--verbose'):
  52.             verbose = True
  53.         else:
  54.             print_usage_and_exit()
  55.     elif len(sys.argv) != 5:
  56.         print_usage_and_exit()
  57.  
  58.     mode = sys.argv[-4]
  59.  
  60.     if mode == 'delta':
  61.         old_dir = sys.argv[-3]
  62.         new_dir = sys.argv[-2]
  63.         patch_dir = sys.argv[-1]
  64.  
  65.         print("mode:", mode)  # debug
  66.         print("old_dir:", old_dir)  # debug
  67.         print("new_dir:", new_dir)  # debug
  68.         print("patch_dir:", patch_dir)  # debug
  69.  
  70.         if os.path.exists(patch_dir):
  71.             print("Patch directory '%s' exists, delete it!" % patch_dir)
  72.             sys.exit()
  73.  
  74.         dir_delta(old_dir, new_dir, patch_dir)
  75.         with open(os.path.join(patch_dir, success_marker), 'w') as wf:
  76.             wf.write("1")
  77.         info("xdelta completed!\n\n")
  78.         #print("xdelta completed! total_size: %s\n\n" % total_size)  # debug
  79.  
  80.         if total_size != 0:
  81.             '''
  82.            #info("original size: %5i MB  delta: %4i MB  reduction: %4.2f%%\n" % (
  83.                total_size / 1024 / 1024,
  84.                delta_size / 1024 / 1024,
  85.                delta_size / total_size * 100))
  86.            '''
  87.             print("original size: %5i B  delta: %4i B  reduction: %4.2f%%\n" % (
  88.                 total_size,
  89.                 delta_size,
  90.                 delta_size / total_size * 100))
  91.  
  92.     elif mode == 'patch':
  93.         patch_dir = sys.argv[-3]
  94.         old_dir = sys.argv[-2]
  95.         new_dir = sys.argv[-1]
  96.  
  97.         print("mode:", mode)  # debug
  98.         print("patch_dir:", patch_dir)  # debug
  99.         print("old_dir:", old_dir)  # debug
  100.         print("new_dir:", new_dir)  # debug
  101.  
  102.         if not os.path.exists(os.path.join(patch_dir, success_marker)):
  103.             # No 'success_marker' found in patch directory
  104.             print("File '%s' missing, the directory '%s' does not contain correct data..." %
  105.                     (success_marker, patch_dir))
  106.             sys.exit()
  107.  
  108.         if os.path.exists(new_dir):
  109.             #print("Warning: The destination directory already exists!", file=sys.stderr)
  110.             print("Destination directory '%s' exists, delete it!" % new_dir)
  111.             sys.exit()
  112.  
  113.         dir_patch(patch_dir, old_dir, new_dir)
  114.  
  115.         if not patch_error:
  116.             print("Patch completed!\n")
  117.         else:
  118.             print("Patch completed with ERRORS!\n")
  119.     else:
  120.         print("Unknown mode '%s'" % mode)
  121.         sys.exit()
  122.  
  123.     print("Total time: %4.2f seconds" % (default_timer() - start))
  124.     sys.exit()
  125.  
  126.  
  127. def info(message):
  128.     global verbose
  129.     if verbose:
  130.         print(message, file=sys.stderr)
  131.  
  132.  
  133. def call(cmds):
  134.     subprocess.call(cmds)  # popen ?
  135.     '''
  136.    if(defined wantarray):  # if call run in SCALER context (or list?)
  137.        # bitshift 8 unless system failed to execute or child died with signal
  138.        return $? >> 8 unless $? == -1 || $? & 127
  139.  
  140.    global patch_error, file2pat
  141.    if ($?):  # if system status not zero or undefined
  142.        if $?: print("Can not apply patch: %s\n" % file2pat)
  143.        patch_error = True
  144.    '''
  145.  
  146.  
  147. def dir_delta(old_dir, new_dir, patch_dir):
  148.     global deleted_files, success_marker, total_size, delta_size, courgette
  149.     info("Directory: %s\n" % new_dir)
  150.     os.mkdir(patch_dir)
  151.  
  152.     # To avoid missing dir in old causing xdelta to quit in unexpected manner...
  153.     if not os.path.isdir(old_dir):
  154.         os.mkdir(old_dir)
  155.  
  156.     old_files = {i:1 for i in os.listdir(old_dir)}
  157.     new_files = {i:1 for i in os.listdir(new_dir)}
  158.     with open(os.path.join(patch_dir, success_marker), 'w') as wf:
  159.         wf.write("1")
  160.     # just note deleted files and dirs and write a file where we keep this note...
  161.     for i in sorted(old_files.keys()):
  162.         # Note deleted dirs or files
  163.         if i in new_files:
  164.             continue
  165.         elif os.path.isdir(os.path.join(old_dir, i)):
  166.             info("Directory deleted: %s\n" % os.path.join(old_dir, i))
  167.         else:
  168.             info("File deleted: %s\n" % os.path.join(old_dir, i))
  169.  
  170.         with open(deleted_files, 'a') as df:
  171.             df.write(os.path.join(old_dir, i) + "\n")
  172.  
  173.     for i in sorted(new_files.keys()):
  174.         old = os.path.join(old_dir, i)
  175.         new = os.path.join(new_dir, i)
  176.         patch = os.path.join(patch_dir, i)
  177.  
  178.         # directories
  179.         if os.path.isdir(new):
  180.             dir_delta(old, new, patch)
  181.             continue
  182.  
  183.         patch += ".courgette"
  184.         #cmd = ['xdelta3', '-0', '-D', '-R', '-q']
  185.  
  186.         # created files
  187.         if i in old_files and os.path.getsize(old) > 0 and \
  188.                 os.path.getsize(new) > 0:
  189.             #call(['courgette64.exe', '-gen', old, new, patch])
  190.             call([courgette, '-gen', old, new, patch])
  191.             #    cmd.extend(('-s', old))
  192.             #print("Changed file: %s\n" % new)  # debug
  193.             info("Changed file: %s\n" % new)
  194.         else:
  195.             shutil.copy2(new, patch)
  196.             #print("New file: %s\n" % new)  # debug
  197.             info("New file: %s\n" % new)
  198.  
  199.         #cmd.extend((new, patch))
  200.         #call(cmd)
  201.  
  202.         total_size += os.path.getsize(new)
  203.         delta_size += os.path.getsize(patch)
  204.         #print("total_size: %s  delta_size: %s\n" % (total_size, delta_size))  # debug
  205.  
  206.  
  207. def dir_patch(patch_dir, old_dir, new_dir):
  208.     global success_marker, file2pat, courgette
  209.     os.mkdir(new_dir)
  210.     info("Directory: %s\n" % new_dir)
  211.  
  212.     for i in sorted(os.listdir(patch_dir)):
  213.         if i == success_marker:
  214.             continue
  215.         patch = os.path.join(patch_dir, i)
  216.         old = os.path.join(old_dir, i)
  217.         new = os.path.join(new_dir, i)
  218.  
  219.         # directories
  220.         if os.path.isdir(patch):
  221.             dir_patch(patch, old, new)
  222.  
  223.         # changed and new files
  224.         elif i.endswith(".courgette"):
  225.             old = old[:-len('.courgette')]
  226.             new = new[:-len('.courgette')]
  227.  
  228.             file2pat = old
  229.  
  230.             #cmd = ['xdelta3', '-d', '-q', '-D', '-R']
  231.             if os.path.exists(old) and os.path.getsize(old) > 0 and \
  232.                     os.path.getsize(patch) > 0:
  233.                 call([courgette, '-apply', old, patch, new])
  234.                 info("Changed file: %s\n" % new)
  235.             else:
  236.                 shutil.copy2(patch, new)
  237.                 info("New file: %s\n" % new)
  238.             #cmd.extend((patch, new))
  239.             #call(cmd)
  240.  
  241.  
  242. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement