#### Source code for ./examples/find.py ####


#!/usr/bin/env python
"""my first sysadmin module

added a find option function
config exclude_dirs with ConfigParser
"""

# *****************************************************************************

from __future__ import generators

import sys
import os
import stat
import re
from ConfigParser import ConfigParser

# *****************************************************************************

# read config file defaults

rcfile = os.path.join(os.getenv('HOME'), 'pyadmin.rc')
parser = ConfigParser()
parser.read([rcfile])
exclude_dirs = parser.get('walk', 'exclude')

# -----------------------------------------------------------------------------

def walktree(top='.', depthfirst=True, ): 
    """Directory tree generator.
    
    Traverses filesystem from directory 'top' downwards, returning each
    directory found and a list of files in that directory.
    
    If depthfirst is True, returns files found from bottom of tree first.

    See also os.walk, available in Python 2.3 on.

    Thanks to Noah Spurrier and Doug Fort.
    """

    names = os.listdir(top)
    if not depthfirst: 
        yield top, names
    for name in names: 
        try: 
            state = os.lstat(os.path.join(top, name))
        except os.error: 
            continue
        if stat.S_ISDIR(state.st_mode)and (name not in exclude_dirs): 
            for (newtop, children)in \
                     walktree(os.path.join(top, name), depthfirst): 
                yield newtop, children
    if depthfirst: 
        yield top, names

# -----------------------------------------------------------------------------

def find(paths=['.'], inc_pattern='.*', 
          exc_pattern='', newer_than=None, prt=False, ): 
    """Find files below path(s) matching inc_pattern.

    exc_pattern = pattern to exclude files.
    paths = list of paths to search.

    Returns a list of files found.
    If prt is True, prints full pathname of files found on stdout.
    If newer_than is set to the name of a file, only files newer than that
    file will be returned.
    """

    if newer_than: 
        # get ctime of stamp file
        try: 
            state = os.lstat(newer_than)
            stamp_date = state[stat.ST_CTIME]
        except os.error: 
            raise
    else: 
        wanted = True
    results = []
    inc_rgx = re.compile(inc_pattern)
    if exc_pattern: 
        exc_rgx = re.compile(exc_pattern)
    else: 
        exc_rgx = None
    if isinstance(paths, str): 
        paths = [paths, ]
    for path in paths: 
        for basepath, children in walktree(path, False, ): 
            for child in children: 
                if inc_rgx.match(child, ): 
                    if not exc_rgx or not exc_rgx.match(child): 
                        fullpath = os.path.join(basepath, child, )
                        if newer_than: 
                            # see if file mod time is later than stamp file
                            state = os.lstat(fullpath)
                            last_mod_date = state[stat.ST_CTIME]
                            wanted = (last_mod_date>stamp_date)
                        if wanted: 
                            if prt: 
                                sys.stdout.write('%s\n'%fullpath)
                            results.append(fullpath)
    return results

# *****************************************************************************

if __name__ == '__main__': 
    sys.stdout.write('Enter directory paths to find in >> ')
    paths = sys.stdin.readline().strip()
    if not paths: 
        sys.exit()
    paths = paths.split()
    sys.stdout.write('Pattern to match >> ')
    include = sys.stdin.readline().strip()
    if not include: include = '.*'
    sys.stdout.write('Pattern to exclude >> ')
    exclude = sys.stdin.readline().strip()
    find(paths, inc_pattern = include, exc_pattern = exclude, 
          newer_than = None, prt = True)

# *****************************************************************************

[Created with py2html Ver:0.62]

Valid HTML 4.01!