#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import ( absolute_import, division, print_function, unicode_literals ) from nine import ( IS_PYTHON2, basestring, chr, class_types, filter, integer_types, implements_iterator, implements_to_string, implements_repr, input, iterkeys, iteritems, itervalues, long, map, native_str, nine, nimport, range, range_list, reraise, str, zip ) argparse = nimport('argparse') os = nimport('os') subprocess = nimport('subprocess') time = nimport('time') def run(): """Runs this program. The program runs 'rsync' to copy files from one directory tree to another """ start_time = time.time() options = parse_cmd_line() rsync_dir( src_dir=options['srcdir'], dest_dir=options['destdir'], remove=options['remove'], verbose=options['verbose']) if options['verbose']: print('Done, in {} seconds!'.format(time.time() - start_time)) def parse_cmd_line(): """Parses the command-line arguments. Arguments: None Returns: A dictionary with each of the supplied command-line arguments. """ parser = argparse.ArgumentParser( description=' '.join([ 'Uses rsync to recursively copy files from a source directory', 'to a destination directory'])) parser.add_argument( 'srcdir', help='specify the directory that files will be recursively copied from') parser.add_argument( 'destdir', help='specify the directory that files will be recursively copied to') parser.add_argument( '--remove', '-r', action='store_true', default=False, help=' '.join([ 'specify this to remove files from the destination directory that', 'no longer exist under the source directory'])) parser.add_argument( '--verbose', '-v', action='store_true', default=False, help='specify this to display verbose output') # vars() turns Namespace into a regular dictionary options = vars(parser.parse_args()) options['srcdir'] = chomp_sep(options['srcdir']) options['destdir'] = chomp_sep(options['destdir']) return options def chomp_sep(dir_name): """Removes any trailing directory separator characters from the given directory name. Arguments: dir_name: the name that has to have any trailing slashes removed Returns: The directory name with no trailing separator characters """ while dir_name.endswith(os.sep): dir_name = dir_name[:-1] return dir_name def rsync_dir(**kwargs): """Copies files from one directory tree to another. Arguments: kwargs: a dictionary with the following keys:- src_dir: the directory from which to recursively copy files dest_dir: the directory into which files are recursively copied remove: whether to remove files that exist in the dest_dir directory but not the src_dir directory verbose: whether to output text describing non-fatal events Returns: None """ src_dir = kwargs.pop('src_dir') dest_dir = kwargs.pop('dest_dir') remove = kwargs.pop('remove') verbose = kwargs.pop('verbose') if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) rsync_options = [ '--archive', '--compress', '--partial'] if remove: rsync_options.append('--delete') if verbose: rsync_options.extend(['--progress', '--human-readable', '--stats']) else: rsync_options.append('--quiet') subprocess.call( 'sudo rsync {} "{}/" "{}"'.format( ' '.join(rsync_options), src_dir, dest_dir), shell=True) if verbose: print('Performed apt-clone clone from {} to {}'.format( src_dir, dest_dir)) if __name__ == '__main__': run()