#!/usr/bin/python
"""Clean files unmentioned in .xo-files from a directory tree."""
# Copyright (C) 2007 One Laptop Per Child Association, Inc.
# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details.
# Written by C. Scott Ananian <cscott@laptop.org>
from __future__ import with_statement

import os, os.path
from bitfrost.contents.utils import DIROBJECT, clean, UnifiedContents, SplitContents, mkusermap, mkgroupmap, verify

def main ():
    from optparse import OptionParser
    from bitfrost.contents import VERSION_INFO
    parser = OptionParser(usage='%prog [options] [directory]')
    parser.add_option('-f', '--file', dest='filename',default=None,
                      help='read contents manifest from FILE, instead of '+
                      'looking for '+DIROBJECT+' in each directory.',
                      metavar='FILE')
    parser.add_option('-n', '--dry_run', action='store_true',
                      dest='dryrun', default=False,
                      help="don't actually delete any files, just print out "
                      "the extra files.")
    parser.add_option('-p', '--passwd-file', dest='passwd_file',
                      default='/etc/passwd', metavar='PASSWD',
                      help='use PASSWD to lookup usernames for uids')
    parser.add_option('-g', '--group-file', dest='group_file',
                      default='/etc/group', metavar='GROUP',
                      help='use GROUP to lookup groupnames for gids')
    parser.add_option('--version',action='store_true',dest='version',
                      default=False,
                      help="display version and license information.")
    (options, args) = parser.parse_args()
    if options.version:
        print VERSION_INFO
    if not args:
        parser.error('The directory argument is required.')
    path = args[0]

    # create user and group maps
    usermap = mkusermap(options.passwd_file)
    groupmap = mkgroupmap(options.group_file)

    if options.filename is not None:
        contents = UnifiedContents(options.filename)
        dlen, mlen = None, os.fstat(contents.file.fileno()).st_size
    else:
        contents = SplitContents(path)
        dlen, mlen = os.stat(os.path.join(path, DIROBJECT)).st_size, None
    verify(path, '', contents, dlen, mlen,
           allow_extra=True, usermap=usermap, groupmap=groupmap)
    clean(path, '', contents, options.dryrun)

if __name__ == '__main__': main ()
