[Tutor] Script Feedback

Damon Timm damontimm at gmail.com
Tue Mar 30 16:27:43 CEST 2010


As a self-taught Python user I am still looking for insight on the
most pythonic and programmatically-friendly way of accomplishing a
given task. In this case, I have written a script that will perform a
“clean bzip2″ of a directory (or directories). Mac OS X (via AFP and
netatalk, in my case) tends leaves a bunch of ugly files/directories
hanging around and I would rather not include them in my compressed
tar file.

In writing the script, though, I ran into some questions and I am not
sure what the recommended approach would be. The script works, as it
is, but I feel its a little hacked together and also a little limited
in its application.   There is something to be said for programs that
"just work" (this does) but I want to take it a little further as an
educational endeavor and would like it to appear robust,
future-thinking, and pythonic.

My initial questions are:

1. Is there a better way to implement a --quiet flag?
2. I am not very clear on the use of Exceptions (or even if I am using
it in a good way here) — is what I have done the right approach?
3. Finally, in general: any feedback on how to improve this? (I am
thinking, just now, that the script is only suitable for a command
line usage, and couldn’t be imported by another script, for example.)

Any feedback is greatly appreciated. Writing a script like this is a
good learning tool (for me, at least).

I have posted this email online if you want to see the script with
pretty code formatting:
http://blog.damontimm.com/python-script-clean-bzip/

Thanks for any insight you may provide.

Damon

Script follows
************************

#! /usr/bin/env python

'''Script to perform a "clean" bzip2 on a directory (or directories).  Removes
extraneous files that are created by Apple/AFP/netatalk before compressing.
'''

import os
import tarfile
from optparse import OptionParser

IGNORE_DIRS = ( '.AppleDouble', )
IGNORE_FILES = ('.DS_Store', )

class DestinationTarFileExists(Exception):
    '''If the destination tar.bz2 file already exists.'''

def ignore_walk(directory):
    '''Ignore defined files and directories when doing the walk.'''
    for dirpath, dirnames, filenames in os.walk(directory):
        dirnames[:] = [ dn for dn in dirnames if dn not in IGNORE_DIRS ]
        filenames[:] = [ fn for fn in filenames if fn not in IGNORE_FILES ]
        yield dirpath, dirnames, filenames

def tar_bzip2_directories(directories):
    for directory in directories:
        file_name = '-'.join(directory.split(' '))
        tar_name = file_name.replace('/','').lower() + ".tar.bz2"

        if os.path.exists(tar_name):
            raise DestinationTarFileExists()

        if not options.quiet:
            print 'Compressing files into: ' + tar_name

        tar = tarfile.open(tar_name, 'w:bz2')

        for dirpath, dirnames, filenames in ignore_walk(directory):
            for file in filenames:
                if not options.quiet:
                    print os.path.join(dirpath, file)

                tar.add(os.path.join(dirpath, file))

        tar.close()

if __name__ == "__main__":

    parser = OptionParser(usage="%prog [options: -q ] [directory]")
    parser.add_option("-q", "--quiet", action="store_true", dest="quiet")
    options, args = parser.parse_args()

    directories = []

    for arg in args:
        if os.path.isdir(arg):
            directories.append(arg)
        else:
            print "Ingoring: %s (it's not a directory)." % arg

    try:
        tar_bzip2_directories(directories)
    except DestinationTarFileExists:
        print "A tar file already exists this this directory name."
        print "Move or rename it and try again."


More information about the Tutor mailing list