Skip to content

Hypelocate

I wrote a small app called hypelocate to test hype, it’s a clone of unix “locate” tool. You must install hype and my patch (the first, not the second one) to the hype source tree to use it.

You can find the whole app here: http://www.oluyede.org/files/hypelocate-0.5.tar.gz

You can find more informations about hyper in my older post: Hype, the Python indexer

Here are the supported options:

rhymes@voodoo:~/hypelocate $ python hypelocate.py
usage: hypelocate.py [options]

HypeLocate 0.5 - Released 2005-12-10 Copyright (c) 2005, Lawrence Oluyede

options: --version show program's version number and exit -h, --help show this help message and exit -u Create database starting at path /. -U <dir> Create database starting at path <dir>. -n <num> Limit the amount of results shown to <num>. -o <dir>, --output=<dir> Specifies the database to create. -d <path>, --database=<path> Specifies the path of databases to search in. -v, --verbose Verbose mode. Display files when creating database.

and this is the main file:

[code lang="python"]

!/usr/bin/env python

from optparse import OptionParser, OptionValueError import os import fnmatch import sys import string

import hype

import conf

class HypeLocate(object): def init(self, db_path=None): self.db_path = db_path or conf.DB_PATH self.max_results = False

def _open_db(self, flags=None):
    try:
        os.mkdir(self.db_path)
    except OSError:
        pass

    if flags:
        return hype.Database(self.db_path, flags)

    return hype.Database(self.db_path)

def _remove_non_existent(self, db):
    for doc in db.get_documents():
        if not os.path.exists(doc["@uri"]):
            db.remove(doc)

def _all_files(self, root, patterns="*", single_level=False, yield_folders=True):
    """ Walks through subdirectories yielding one file (or folder) at time.

    root: the root dir to start at
    patterns: which kind of file to catch, es: *.py;*.gif [defaults to anything]
    single_level: True if you don't want to walk in subdirs [defaults to False]
    yield_folders: True if you want folders in retuns in addition of files [defaults to True]
    """
    patterns = patterns.split(";")

    for path, subdirs, files in os.walk(root):
        if yield_folders:
            files.extend(subdirs)
            files.sort()
        for name in files:
            for pattern in patterns:
                if fnmatch.fnmatch(name, pattern):
                    yield os.path.abspath(os.path.join(path, name))
                    break

        if single_level:
            break

def updatedb(self, root=".", remove=True, verbose=False):
    """ Generate the index of files starting at root.

    root: where to start the indexing [defaults to current dir]
    remove: True if you want to remove non existent paths, False otherwise [defaults to True]
    verbose: True if you want to display files when creating database, False otherwise [defaults to False]
    """
    num_docs = 0

    try:
        db = self._open_db()

        if remove:
            self._remove_non_existent(db)

        for index, name in enumerate(self._all_files(root)):
            doc = hype.Document()
            if verbose:
                print name
            doc["@uri"] = name
            doc.add_text(name)
            db.put_doc(doc)

        num_docs = len(db)
    finally:
        try:
            db.close()
        except:
            pass

    return num_docs

def locate(self, search_string, remove=True, db_path=None):
    """ Search through the index the given search string.

    search_string: what to search in the index
    remove: remove: True if you want to remove non existent paths, False otherwise [defaults to True]
    db_path: an alternative db to search against. [defaults to None]
    """
    db = docs = None
    try:
        if db_path:
            self.db_path = db_path

        db = self._open_db()

        if remove:
            self._remove_non_existent(db)

        searcher = db.search(search_string).order("@uri STRD")
        list(searcher)

        docs = [doc.uri for doc in searcher if doc]
    finally:
        try:
            db.close()
        except:
            pass

    return docs

def display_results(self, search_strings, db_path=None):
    """ Concatenate the results of multiple invocations of locate() and
    print them to the standard output.

    search_strings: a list of item to search
    db_path: an alternative db to search against. [defaults to None]
    """

    for search_string in search_strings:
        for index, doc in enumerate(self.locate(search_string, db_path)):
            if self.max_results:
                if self.max_results == index:
                    return
            print doc

def main(): description = """$prog_name $version - Released $release_date

Copyright (c) 2005, $author""" desc_template = string.Template(description) description = desc_template.substitute({"prog_name": conf.PROG_NAME, "version": conf.VERSION, "release_date": conf.RELEASE_DATE, "author": conf.AUTHOR}) version = "%s %s" % (conf.PROG_NAME, conf.VERSION) parser = OptionParser(description=description, version=version)

parser.set_default("start_root", False)
parser.add_option("-u", action="store_true", dest="start_at_root",
                  help="Create database starting at path /.")

parser.add_option("-U", dest="start_path", metavar="<dir>",
                  help="Create database starting at path <dir>.")

parser.add_option("-n", dest="max_results", type="int", metavar="<num>",
                  help="Limit the amount of results shown to <num>.")

parser.add_option("-o", "--output", dest="out_db", metavar="<dir>",
                  help="Specifies the database to create.")

parser.add_option("-d", "--database", dest="db_path", metavar="<path>",
                  help="Specifies the path of databases to search in.")

parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
                  help="Verbose mode. Display files when creating database.")

if len(sys.argv) < 2:
    parser.print_help()
    return    

options, args = parser.parse_args()

finder = HypeLocate()

if options.out_db:
    if not parser.values.start_at_root and not parser.values.start_path:
        parser.error(
            "Must specify an 'Update' database option first.")

    finder.db_path = options.out_db

if options.max_results:
    finder.max_results = options.max_results

if options.start_at_root and options.start_path:
    parser.error("Options -u and -U are mutually exclusive")

if options.start_path:
    # index at start_path
    finder.updatedb(options.start_path, verbose=options.verbose)
elif options.start_at_root:
    # index the whole fs tree
    finder.updatedb("/", verbose=options.verbose)

finder.display_results(args, options.db_path)

if name == "main": main() [/code]

UPDATE: - hypelocate 0.5.1 released in sync with the latest Hype revision number. Fixes a couple of bugs in the handling of the db and uses unicode everywhere. download

Additional comments powered by BackType