# $Id$
#
# Locate all standard modules available in this build.
#
# This script is designed to run on Python 1.5.2 and newer.
#
# Written by Fredrik Lundh, January 2005
#

import imp, sys, os, re, time

identifier = "python-%s-%s" % (sys.version[:3], sys.platform)
timestamp = time.strftime("%Y%m%dT%H%M%SZ", time.gmtime(time.time()))

# known test packages
TEST_PACKAGES = "test.", "bsddb.test.", "distutils.tests."

try:
    import platform
    platform = platform.platform()
except:
    platform = None # unknown

suffixes = imp.get_suffixes()

def get_suffix(file):
    for suffix in suffixes:
        if file[-len(suffix[0]):] == suffix[0]:
            return suffix
    return None

def main():

    path = getpath()

    modules = {}
    for m in sys.builtin_module_names:
        modules[m] = None

    for p in path:
        modules.update(getmodules(p))

    keys = modules.keys()
    keys.sort()

    # filter out known test packages
    def cb(m):
        for d in TEST_PACKAGES:
            if m[:len(d)] == d:
                return 0
        return 1
    keys = filter(cb, keys)

    try:
        outfile = sys.argv[1]
        if outfile == "-":
            outfile = None
        elif outfile == "-f":
            outfile = "modules-" + identifier + ".txt"
    except IndexError:
        outfile = None

    if not outfile:
        out = sys.stdout
    else:
        out = open(outfile, "w")

    out.write("# module list (generated by listmodules.py)\n")
    out.write("#\n")
    out.write("# timestamp=%s\n" % repr(timestamp))
    out.write("# sys.version=%s\n" % repr(sys.version))
    out.write("# sys.platform=%s\n" % repr(sys.platform))
    if platform:
        out.write("# platform=%s\n" % repr(platform))
    out.write("#\n")

    for k in keys:
        out.write(k + "\n")

    if out is not sys.stdout:
        out.close()
        print out.name, "ok (%d modules)" % len(modules)

def getmodules(p):
    # get modules in a given directory
    modules = {}
    for f in os.listdir(p):
        f = os.path.join(p, f)
        if os.path.isfile(f):
            m, e = os.path.splitext(f)
            suffix = get_suffix(f)
            if not suffix:
                continue
            m = os.path.basename(m)
            if re.compile("(?i)[a-z_]\w*$").match(m):
                if suffix[2] == imp.C_EXTENSION:
                    # check that this extension can be imported
                    try:
                        __import__(m)
                    except ImportError:
                        continue
                modules[m] = f
        elif os.path.isdir(f):
            m = os.path.basename(f)
            if os.path.isfile(os.path.join(f, "__init__.py")):
                for mm, f in getmodules(f).items():
                    modules[m + "." + mm] = f
    return modules

def getpath():
    path = map(os.path.normcase, map(os.path.abspath, sys.path[:]))
    # get rid of site packages
    for p in path:
        if p[-13:] == "site-packages":
            def cb(p, site_package_path=os.path.abspath(p)):
                return p[:len(site_package_path)] != site_package_path
            path = filter(cb, path)
            break
    # get rid of non-existent directories and the current directory
    def cb(p, cwd=os.path.normcase(os.getcwd())):
        return os.path.isdir(p) and p != cwd
    path = filter(cb, path)
    return path

if __name__ == "__main__":
    main()
