Advertisement
justin_hanekom

rsync-dir.py

May 13th, 2019
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.18 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. # File: rsync-dir.py
  5. # Copyright (c) 2018-2019 Justin Hanekom <justin_hanekom@yahoo.com>
  6. # Licensed under the MIT License
  7.  
  8. # Permission is hereby granted, free of charge, to any person obtaining
  9. # a copy of this software and associated documentation files
  10. # (the "Software"), to deal in the Software without restriction,
  11. # including without limitation the rights to use, copy, modify, merge,
  12. # publish, distribute, sublicense, and/or sell copies of the Software,
  13. # and to permit persons to whom the Software is furnished to do so,
  14. # subject to the following conditions:
  15. #
  16. # The above copyright notice and this permission notice shall be
  17. # included in all copies or substantial portions of the Software.
  18. #
  19. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  22. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  24. # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26.  
  27. from __future__ import (
  28.     absolute_import, division, print_function, unicode_literals
  29. )
  30. from nine import (
  31.     IS_PYTHON2, basestring, chr, class_types, filter, integer_types,
  32.     implements_iterator, implements_to_string, implements_repr,
  33.     input, iterkeys, iteritems, itervalues, long, map,
  34.     native_str, nine, nimport, range, range_list, reraise, str, zip
  35. )
  36.  
  37. argparse = nimport('argparse')
  38. os = nimport('os')
  39. subprocess = nimport('subprocess')
  40. time = nimport('time')
  41.  
  42.  
  43. def run():
  44.     """Runs this program.
  45.  
  46.    The program runs 'rsync' to copy files from one directory tree to another
  47.    """
  48.     start_time = time.time()
  49.     options = parse_cmd_line()
  50.     rsync_dir(
  51.         src_dir=options['srcdir'],
  52.         dest_dir=options['destdir'],
  53.         remove=options['remove'],
  54.         verbose=options['verbose'])
  55.     if options['verbose']:
  56.         print('Done, in {} seconds!'.format(time.time() - start_time))
  57.  
  58.  
  59. def parse_cmd_line():
  60.     """Parses the command-line arguments.
  61.  
  62.    Arguments:
  63.        None
  64.  
  65.    Returns:
  66.        A dictionary with each of the supplied command-line arguments.
  67.    """
  68.     parser = argparse.ArgumentParser(
  69.         description=' '.join([
  70.             'Uses rsync to recursively copy files from a source directory',
  71.             'to a destination directory']))
  72.     parser.add_argument(
  73.         'srcdir',
  74.         help='specify the directory that files will be recursively copied from')
  75.     parser.add_argument(
  76.         'destdir',
  77.         help='specify the directory that files will be recursively copied to')
  78.     parser.add_argument(
  79.         '--remove', '-r',
  80.         action='store_true',
  81.         default=False,
  82.         help=' '.join([
  83.             'specify this to remove files from the destination directory that',
  84.             'no longer exist under the source directory']))
  85.     parser.add_argument(
  86.         '--verbose', '-v',
  87.         action='store_true',
  88.         default=False,
  89.         help='specify this to display verbose output')
  90.     # vars() turns Namespace into a regular dictionary
  91.     options = vars(parser.parse_args())
  92.     options['srcdir'] = chomp_sep(options['srcdir'])
  93.     options['destdir'] = chomp_sep(options['destdir'])
  94.     return options
  95.  
  96.  
  97. def chomp_sep(dir_name):
  98.     """Removes any trailing directory separator characters from the given
  99.    directory name.
  100.  
  101.    Arguments:
  102.        dir_name: the name that has to have any trailing slashes removed
  103.  
  104.    Returns:
  105.        The directory name with no trailing separator characters
  106.    """
  107.     while dir_name.endswith(os.sep):
  108.         dir_name = dir_name[:-1]
  109.     return dir_name
  110.  
  111.  
  112. def rsync_dir(**kwargs):
  113.     """Copies files from one directory tree to another.
  114.  
  115.    Arguments:
  116.        kwargs: a dictionary with the following keys:-
  117.            src_dir:    the directory from which to recursively copy files
  118.            dest_dir:   the directory into which files are recursively copied
  119.            remove:     whether to remove files that exist in the
  120.                        dest_dir directory but not the src_dir directory
  121.            verbose:    whether to output text describing non-fatal events
  122.  
  123.    Returns:
  124.        None
  125.    """
  126.     src_dir = kwargs.pop('src_dir')
  127.     dest_dir = kwargs.pop('dest_dir')
  128.     remove = kwargs.pop('remove')
  129.     verbose = kwargs.pop('verbose')
  130.     if kwargs:
  131.         raise TypeError('Unexpected **kwargs: %r' % kwargs)
  132.     rsync_options = [
  133.         '--archive',
  134.         '--compress',
  135.         '--partial']
  136.     if remove:
  137.        rsync_options.append('--delete')
  138.     if verbose:
  139.         rsync_options.extend(['--progress', '--human-readable', '--stats'])
  140.     else:
  141.         rsync_options.append('--quiet')
  142.     subprocess.call(
  143.         'sudo rsync {} "{}/" "{}"'.format(
  144.             ' '.join(rsync_options),
  145.             src_dir,
  146.             dest_dir),
  147.         shell=True)
  148.     if verbose:
  149.         print('Performed apt-clone clone from {} to {}'.format(
  150.             src_dir,
  151.             dest_dir))
  152.  
  153.  
  154. if __name__ == '__main__':
  155.     run()
  156.  
  157. # vim: set filetype=python smartindent autoindent smarttab expandtab tabstop=4 softtabstop=4 shiftwidth=4 autoread
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement