Advertisement
justin_hanekom

chown-dir-user.py

May 13th, 2019
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.27 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. # File: chown-dir-user.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. grp = nimport('grp')
  39. os = nimport('os')
  40. pwd = nimport('pwd')
  41. sys = nimport('sys')
  42. time = nimport('time')
  43.  
  44.  
  45. def run():
  46.     """Runs this program.
  47.  
  48.    The program ensures that all files under a directory belong to
  49.    a certain user and group.
  50.    """
  51.     start_time = time.time()
  52.     options = parse_cmd_line()
  53.     chown_dir_user(
  54.         user=options['user'],
  55.         directory=options['directory'],
  56.         verbose=options['verbose'])
  57.     if options['verbose']:
  58.         print('Done, in {} seconds!'.format(time.time() - start_time))
  59.  
  60.  
  61. def parse_cmd_line():
  62.     """Parses the command-line arguments.
  63.  
  64.    Arguments:
  65.        None
  66.  
  67.    Returns:
  68.        A dictionary with each of the supplied command-line arguments.
  69.    """
  70.     parser = argparse.ArgumentParser(
  71.         description=' '.join([
  72.             'Sets the user and group of all files under/within a given',
  73.             'directory to a particular user and group']))
  74.     parser.add_argument(
  75.         'user',
  76.         help=' '.join([
  77.             'specify the name of the user/group for files within this',
  78.             'directory']))
  79.     parser.add_argument(
  80.         'directory',
  81.         help=' '.join([
  82.             'specify the directory to look for files',
  83.             'whose owner/group should to be modified']))
  84.     parser.add_argument(
  85.         '--verbose', '-v',
  86.         action='store_true',
  87.         default=False,
  88.         help='specify this to display verbose output')
  89.     # vars() turns Namespace into a regular dictionary
  90.     options = vars(parser.parse_args())
  91.     options['directory'] = chomp_sep(options['directory']) + os.sep
  92.     return options
  93.  
  94.  
  95. def chomp_sep(dir_name):
  96.     """Removes any trailing directory separator characters from the given
  97.    directory name.
  98.  
  99.    Arguments:
  100.        dir_name: the name that has to have any trailing slashes removed
  101.  
  102.    Returns:
  103.        The directory name with no trailing separator characters
  104.    """
  105.     while dir_name.endswith(os.sep):
  106.         dir_name = dir_name[:-1]
  107.     return dir_name
  108.  
  109.  
  110. def chown_dir_user(**kwargs):
  111.     """Removes unneeded files under directory dir_name.
  112.  
  113.    Arguments:
  114.        kwargs: a dictionary with the following keys:-
  115.            user:       the name of the user/group to assign to files under
  116.                        the given directory
  117.            directory:  the root directory under which to search for
  118.                        unneccessary files to delete
  119.            verbose:    whether to output text describing non-fatal events
  120.  
  121.    Returns:
  122.        None
  123.    """
  124.     user = kwargs.pop('user')
  125.     directory = kwargs.pop('directory')
  126.     verbose= kwargs.pop('verbose')
  127.     if kwargs:
  128.         raise TypeError('Unexpected **kwargs: %r' % kwargs)
  129.     uid = pwd.getpwnam(user).pw_uid
  130.     gid = grp.getgrnam(user).gr_gid
  131.     for tupl in os.walk(directory):
  132.         # (dir, subdirs, filenames)
  133.         dir_name = tupl[0].decode(encoding='utf-8', errors='ignore')
  134.         for fname in tupl[2]:
  135.             dir_fname = os.path.join(
  136.                 dir_name,
  137.                 fname.decode(encoding='utf-8', errors='ignore'))
  138.             if os.path.exists(dir_fname):
  139.                 try:
  140.                     stat = os.stat(dir_fname)
  141.                 except OSError as err:
  142.                     print("Unable to stat '{}' - {}".format(dir_fname, err))
  143.                 if stat.st_uid != uid or stat.st_gid != gid:
  144.                     os.chown(dir_fname, uid, gid)
  145.                     if verbose:
  146.                         print("Changed the owner of '{}' to {}:{}".format(
  147.                             dir_fname,
  148.                             user,
  149.                             user))
  150.  
  151.  
  152. if __name__ == '__main__':
  153.     run()
  154.  
  155. # 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