#!/usr/bin/python

'''Python CGI test script by Ben Hutchings <ben@decadent.org.uk>.

Use this to find out what Python facilities your web server provides.
Upload it to a directory where you can run CGI scripts.  If the web
server runs Unix, remember to make the uploaded script executable.
Then load the URL for the CGI script in a web browser.  If this
produces an error message, try changing the interpreter name on the
first line to /usr/local/bin/python and uploading the script again.
Once it is working, you should have a list of available Python
executables.  You may be able to choose an alternate version of
Python by changing the interpreter name again.

2016-04-17: Removed Python 1.x support and added Python 3.x support.
'''

import os, os.path, re, sys

def esc(s):
    return s.replace('&', '&amp;').replace('<', '&lt;')

# We can't use print as it may be a statement or a function, but this
# function does all we need
def print_fn(*args):
    for arg in args[:-1]:
        sys.stdout.write(str(arg))
        sys.stdout.write(' ')
    sys.stdout.write(args[-1])
    sys.stdout.write('\n')

try:
    sorted = __builtins__.sorted
except NameError:
    def sorted(it):
        # Dumb implementation depending on nothing newer than 2.0
        l = [elem for elem in it]
        l.sort()
        return l

print_fn('Content-Type: text/html')
print_fn('')

print_fn('<title>Python CGI test</title>')
print_fn('<h1>Python CGI test</h1>')

print_fn('<p>Python executable:', esc(sys.executable), '</p>')
print_fn('<p>Python version:', esc(sys.version), '</p>')

os_path = os.environ['PATH'].split(os.pathsep)
print_fn('<p>OS path:</p>')
print_fn('<ul>')
for dir_name in os_path:
    print_fn('<li>', esc(dir_name), '</li>')
print_fn('</ul>')
print_fn('<p>Python executables found in OS path:</p>')
print_fn('<ul>')
for dir_name in os_path:
    try:
        for file_name in os.listdir(dir_name):
            if file_name[:6] == 'python':
                print_fn('<li>', esc(os.path.join(dir_name, file_name)), '</li>')
    except OSError:
        pass
print_fn('</ul>')

print_fn('<p>Python path:</p>')
print_fn('<ul>')
for dir_name in sys.path:
    print_fn('<li>', esc(dir_name), '</li>')
print_fn('</ul>')
print_fn('<p>Python modules found in Python path or built-in:</p>')
modules = {}
for name in sys.builtin_module_names:
    modules[name] = '(built-in)'
for dir_name in sys.path:
    # Python treats an empty string in the path as the current directory
    if dir_name == '':
        dir_name = os.curdir
    # Handle directories
    if os.path.isdir(dir_name):
        try:
            for file_name in os.listdir(dir_name):
                # Match *.py and *.py?
                full_name = os.path.join(dir_name, file_name)
                match = re.match(r'(\w+)\.py\w?$', file_name)
                if match:
                    name = match.group(1)
                    modules.setdefault(name, full_name)
                # Match directories containing __init__.py
                elif (os.path.isdir(full_name)
                      and os.path.isfile(os.path.join(full_name,
                                                      '__init__.py'))):
                    modules.setdefault(file_name, full_name)
        except OSError:
            pass
    # Handle zip files
    elif dir_name[:4] == '.zip':
        try:
            list = __import__('zipfile').ZipFile(dir_name).namelist()
            for file_name in list:
                # Match *.py, *.py? and */__init__.py
                match = re.match(r'(\w+)([/\\]__init__\.py|\.py\w?$',
                                 file_name)
                if match:
                    name = match.group(1)
                    modules.setdefault(name, dir_name)
        except (ImportError, IOError):
            pass
print_fn('<table>')
print_fn('<tr><th>Name</th><th>Filename</th></tr>')
for name in sorted(modules.keys()):
    print_fn('<tr><td>', name, '</td><td>', modules[name], '</td></tr>')
print_fn('</table>')
