[Tutor] Script Feedback
Damon Timm
damontimm at gmail.com
Wed Mar 31 01:54:34 CEST 2010
Hello Denis & Steven -
Thanks for your replies. I have taken another stab at things to try
and bring it a little further up to snuff ... some more
comments/thoughts follow ...
On Tue, Mar 30, 2010 at 12:57 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> I usually create a function "print_" or "pr", something like this:
>
> def print_(obj, verbosity=1):
> if verbosity > 0:
> print obj
>
> and then have a variable "verbosity" which defaults to 1 and is set to 0
> if the user passes the --quiet flag. Then in my code, I write:
>
> print_("this is a message", verbosity)
Your suggestion prompted me to remember having looked into this
earlier (and found an old thread of mine) -- some folks had
recommended using the logging module -- which I have implemented in
round two (seems to work). I think it accomplishes the same thing
that you are suggesting, only using one of Python's built-ins.
On Tue, Mar 30, 2010 at 12:57 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Separate the underlying functionality from the application-level code.
> These functions should NEVER print anything: they do all communication
> through call-backs, or by returning a value, or raising an exception.
I tried to implement this, however, I am not sure how the 'callback'
works ... is that just a function that a user would pass to *my*
function that gets called at the end of the script? Also, I tried to
separate out the logic a little so the functions make more sense ... I
think I may remove the 'ignore_walk' function and just add it to the
tar_bz2_directory function (see below) ... but am still unclear about
the callback concept.
2010/3/30 spir ☣ <denis.spir at gmail.com>:
> First, it seems you use [:] only to preserves the object identity so that it remains a generator. But it may be better (at least clearer for me) to filter and transform the generation process so as to get what you actually need, I guess: iterating on (dirpath,filename) pairs. If I'm right on this, maybe try to figure out how do that.
> I would call the func eg "filtered_dir_walk" or "relevant_dir_walk".
I am not sure where I first got this 'ignore_walk' bit but I do
remember taking it from another program of mine ... to be honest,
though, I am rethinking its use and may implement it using fnmatch
testing so that I may implement wildcards (eg, *.pyc) ... right now,
it won't match wildcards and that might be helpful.
Again, thank you both for your feedback. I made some changes tonight
(posted below) and also updated the changes on:
http://blog.damontimm.com/python-script-clean-bzip/ (if you want
pretty colors).
Damon
CODE BELOW
-------------------
#! /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
import logging
from optparse import OptionParser
# Default files and directories to exclude from the bzip tar
IGNORE_DIRS = ('.AppleDouble',)
IGNORE_FILES = ('.DS_Store',)
class DestinationTarFileExists(Exception):
'''If the destination tar.bz2 file already exists.'''
def ignore_walk(directory, ignore_dirs=None, ignore_files=None):
'''Ignore defined files and directories when doing the walk.'''
# TODO: this does not currently take wild cards into account. For example,
# if you wanted to exclude *.pyc files ... should fix that. Perhaps
# consider moving this entirely into the below function (or making it more
# reusable for other apps).
for dirpath, dirnames, filenames in os.walk(directory):
if ignore_dirs:
dirnames[:] = [dn for dn in dirnames if dn not in ignore_dirs]
if ignore_files:
filenames[:] = [fn for fn in filenames if fn not in ignore_files]
yield dirpath, dirnames, filenames
def tar_bzip2_directory(directory, ignore_dirs=IGNORE_DIRS,
ignore_files=IGNORE_FILES ):
'''Takes a directory and creates a tar.bz2 file (based on the directory
name). You can exclude files and sub-directories as desired.'''
file_name = '-'.join(directory.split(' '))
tar_name = file_name.replace('/','').lower() + ".tar.bz2"
if os.path.exists(tar_name):
msg = ("The file %s already exists. " +
"Please move or rename it and try again.") % tar_name
raise DestinationTarFileExists(msg)
tar = tarfile.open(tar_name, 'w:bz2')
for dirpath, dirnames, filenames in ignore_walk(directory, ignore_dirs,
ignore_files):
for file in filenames:
logging.info(os.path.join(dirpath, file))
tar.add(os.path.join(dirpath, file))
tar.close()
def main(args=None, callback=None):
directories = []
for arg in args:
if os.path.isdir(arg):
directories.append(arg)
else:
logging.ERROR("Ingoring: %s (it's not a directory)." % arg)
for dir in directories:
try:
tar_bzip2_directory(dir)
except DestinationTarFileExists, e:
print e
if __name__ == "__main__":
parser = OptionParser(usage="%prog [options: -q ] [dir1] [...dir2]")
parser.add_option("-q", "--quiet", action="store_true", dest="quiet")
options, args = parser.parse_args()
if options.quiet:
logging.basicConfig(level=logging.ERROR, format='%(message)s')
else:
logging.basicConfig(level=logging.INFO, format='%(message)s')
main(args)
More information about the Tutor
mailing list