#!/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()