Advertisement
justin_hanekom

create-dpkg-list.py

May 13th, 2019 (edited)
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.57 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. from __future__ import (
  5.     absolute_import, division, print_function, unicode_literals
  6. )
  7. from nine import (
  8.     IS_PYTHON2, basestring, chr, class_types, filter, integer_types,
  9.     implements_iterator, implements_to_string, implements_repr,
  10.     input, iterkeys, iteritems, itervalues, long, map,
  11.     native_str, nine, nimport, range, range_list, reraise, str, zip
  12. )
  13.  
  14. argparse = nimport('argparse')
  15. glob = nimport('glob')
  16. grp = nimport('grp')
  17. os = nimport('os')
  18. pwd = nimport('pwd')
  19. subprocess = nimport('subprocess')
  20. sys = nimport('sys')
  21. time = nimport('time')
  22.  
  23. DEFAULT_PREFIX = 'dpkg_'
  24. DEFAULT_SUFFIX = '.txt'
  25.  
  26.  
  27. def run():
  28.     """Runs this program.
  29.  
  30.    The program runs 'dpkg --list' to store the current package list
  31.    into a time-stamped file in the given destination directory.
  32.  
  33.    Returns:
  34.        None
  35.    """
  36.     start_time = time.time()
  37.     options = parse_cmd_line(
  38.             default_prefix=DEFAULT_PREFIX,
  39.             default_suffix=DEFAULT_SUFFIX)
  40.     remove_old_files(
  41.         pattern='{destdir}{sep}{prefix}*{suffix}'.format(
  42.             destdir=options['destdir'],
  43.             sep=os.sep,
  44.             prefix=options['prefix'],
  45.             suffix=options['suffix']),
  46.         remove=options['remove'],
  47.         verbose=options['verbose'])
  48.     dest_file = generate_results_file_name(
  49.         dest_dir=options['destdir'],
  50.         prefix=options['prefix'],
  51.         suffix=options['suffix'])
  52.     dpkg_list(
  53.         dest_file=dest_file,
  54.         verbose=options['verbose'])
  55.     change_file_owner_group(
  56.         filename=dest_file,
  57.         user=options['user'],
  58.         group=options['user'],
  59.         verbose=options['verbose'])
  60.     if options['verbose']:
  61.         print('Done, in {} seconds!'.format(time.time() - start_time))
  62.  
  63.  
  64. def parse_cmd_line(default_prefix, default_suffix):
  65.     """Parses the command-line arguments.
  66.  
  67.    Arguments:
  68.        default_prefix: the default prefix for the generated dpkg list file
  69.        default_suffix: the default suffix for the generated dpkg list file
  70.  
  71.    Returns:
  72.        A dictionary with each of the supplied command-line arguments.
  73.    """
  74.     parser = argparse.ArgumentParser(
  75.         description="Stores 'dpkg --list' results")
  76.     parser.add_argument(
  77.         'user',
  78.         help=' '.join([
  79.             'specify the owner of the dpkg list file;',
  80.             'the dpkg list file user and group will be set to this value']))
  81.     parser.add_argument(
  82.         'destdir',
  83.         help=' '.join([
  84.             'specify the directory that the dpkg list file',
  85.             'will be saved to']))
  86.     parser.add_argument(
  87.         '--prefix', '-p',
  88.         default=default_prefix,
  89.         help=' '.join([
  90.             'specify the prefix to use for the dpkg list file',
  91.             "(default: '%(default)s')"]))
  92.     parser.add_argument(
  93.         '--suffix', '-s',
  94.         default=default_suffix,
  95.         help=' '.join([
  96.             'specify the suffix to use for the dpkg list file',
  97.             "(default: '%(default)s')"]))
  98.     parser.add_argument(
  99.         '--remove', '-r',
  100.         action='store_true',
  101.         default=False,
  102.         help='specify this to enable the removal of obsolete dpkg list files')
  103.     parser.add_argument(
  104.         '--verbose', '-v',
  105.         action='store_true',
  106.         default=False,
  107.         help='specify this to display verbose output')
  108.     # vars() turns Namespace into a regular dictionary
  109.     options = vars(parser.parse_args())
  110.     options['destdir'] = chomp_sep(options['destdir'])
  111.     return options
  112.  
  113.  
  114. def chomp_sep(dir_name):
  115.     """Removes any trailing directory separator characters from the given
  116.    directory name.
  117.  
  118.    Arguments:
  119.        dir_name: the name that has to have any trailing slashes removed
  120.  
  121.    Returns:
  122.        The directory name with no trailing separator characters
  123.    """
  124.     while dir_name.endswith(os.sep):
  125.         dir_name = dir_name[:-1]
  126.     return dir_name
  127.  
  128.  
  129. def remove_old_files(**kwargs):
  130.     """Only keeps the newest files that match the given pattern.
  131.  
  132.    Arguments:
  133.        kwargs: a dictionary with the following keys:-
  134.            'pattern'   - the glob pattern of existing files
  135.            'remove'    - whether to remove old files
  136.            'verbose'   - whether to output text describing non-fatal events
  137.  
  138.    Returns:
  139.        None
  140.    """
  141.     pattern = kwargs.pop('pattern')
  142.     remove = kwargs.pop('remove')
  143.     verbose= kwargs.pop('verbose')
  144.     if kwargs:
  145.         raise TypeError('Unexpected **kwargs: %r' % kwargs)
  146.     if not remove:
  147.         return
  148.     for f in glob.glob(pattern):
  149.         os.remove(f)
  150.         if verbose:
  151.             print("Removed file '{filename}'".format(filename=f))
  152.  
  153.  
  154. def generate_results_file_name(dest_dir, prefix, suffix):
  155.     """Generates a results file filename prefix.
  156.  
  157.    Arguments:
  158.        dest_dir:   the directory into which the results file should be saved
  159.        prefix:     the prefix to use for the results file
  160.        suffix:     the suffix to use for the results file
  161.  
  162.    Returns:
  163.        A unique results file filename of the format:
  164.            <dest_dir>/<prefix><year><month><day><hour><minute>second><suffix>
  165.        where the year, month, day, etc. values represent the local time
  166.        at the point at which this function is called.
  167.    """
  168.     localtime = time.localtime()
  169.     return ('{dest_dir}{sep}{prefix}{year:04d}{month:02d}{day:02d}' +
  170.         '{hour:02d}{minute:02d}{second:02d}{suffix}').format(
  171.             dest_dir=dest_dir,
  172.             prefix=prefix,
  173.             suffix=suffix,
  174.             year=localtime[0],
  175.             month=localtime[1],
  176.             day=localtime[2],
  177.             hour=localtime[3],
  178.             minute=localtime[4],
  179.             second=localtime[5],
  180.             sep=os.sep)
  181.  
  182.  
  183. def dpkg_list(dest_file, verbose):
  184.     """Creates a clone file into .
  185.  
  186.    Arguments:
  187.        dest_file:  what to name of the dpkg --list results file
  188.        verbose:    whether to output text describing non-fatal events
  189.  
  190.    Returns:
  191.        None
  192.   """
  193.     subprocess.call(
  194.         'dpkg --list > "{}"'.format(dest_file), shell=True)
  195.     if verbose:
  196.         print('Performed apt-clone clone to: {}'.format(dest_file))
  197.  
  198.  
  199. def change_file_owner_group(**kwargs):
  200.     """Changes the owner and group of the named file.
  201.  
  202.    Arguments:
  203.        kwargs: a dictionary with the following keys:-
  204.            'filename': the file whose ownership is to be changed
  205.            'user':     the new owner to assign to the file
  206.            'group':    the new group to assign to the file;
  207.                        this is the same as 'user' if not given
  208.            'verbose':  whether to output text describing non-fatal events
  209.  
  210.    Returns:
  211.        None
  212.    """
  213.     filename = kwargs.pop('filename')
  214.     user = kwargs.pop('user')
  215.     group = kwargs.pop('group', user)
  216.     verbose= kwargs.pop('verbose')
  217.     if kwargs:
  218.         raise TypeError('Unexpected **kwargs: %r' % kwargs)
  219.     try:
  220.         os.chown(filename,
  221.                  pwd.getpwnam(user).pw_uid,
  222.                  grp.getgrnam(group).gr_gid)
  223.         if verbose:
  224.             print("Changed ownership of '{filename}' to {user}:{group}".format(
  225.                   filename=filename,
  226.                   user=user,
  227.                   group=group))
  228.     except os.OSError:
  229.         print("Unable to change ownership of "
  230.             + "'{filename}' to {user}:{group}".format(
  231.                 filename=filename,
  232.                 user=user,
  233.                 group=group),
  234.             file=sys.stderr)
  235.  
  236.  
  237. if __name__ == '__main__':
  238.     run()
  239.  
Tags: python
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement