#!/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') grp = nimport('grp') os = nimport('os') pwd = nimport('pwd') sys = nimport('sys') time = nimport('time') def run(): """Runs this program. The program ensures that all files under a directory belong to a certain user and group. """ start_time = time.time() options = parse_cmd_line() chown_dir_user( user=options['user'], directory=options['directory'], 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([ 'Sets the user and group of all files under/within a given', 'directory to a particular user and group'])) parser.add_argument( 'user', help=' '.join([ 'specify the name of the user/group for files within this', 'directory'])) parser.add_argument( 'directory', help=' '.join([ 'specify the directory to look for files', 'whose owner/group should to be modified'])) 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['directory'] = chomp_sep(options['directory']) + os.sep 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 chown_dir_user(**kwargs): """Removes unneeded files under directory dir_name. Arguments: kwargs: a dictionary with the following keys:- user: the name of the user/group to assign to files under the given directory directory: the root directory under which to search for unneccessary files to delete verbose: whether to output text describing non-fatal events Returns: None """ user = kwargs.pop('user') directory = kwargs.pop('directory') verbose= kwargs.pop('verbose') if kwargs: raise TypeError('Unexpected **kwargs: %r' % kwargs) uid = pwd.getpwnam(user).pw_uid gid = grp.getgrnam(user).gr_gid for tupl in os.walk(directory): # (dir, subdirs, filenames) dir_name = tupl[0].decode(encoding='utf-8', errors='ignore') for fname in tupl[2]: dir_fname = os.path.join( dir_name, fname.decode(encoding='utf-8', errors='ignore')) if os.path.exists(dir_fname): try: stat = os.stat(dir_fname) except OSError as err: print("Unable to stat '{}' - {}".format(dir_fname, err)) if stat.st_uid != uid or stat.st_gid != gid: os.chown(dir_fname, uid, gid) if verbose: print("Changed the owner of '{}' to {}:{}".format( dir_fname, user, user)) if __name__ == '__main__': run()