#!/usr/bin/env python2 # # $Id$ # $Source$ # """docutils to HTML CGI converter. CGI script that automatically converts docutils files into html and serves it. The script caches the HTML files and uses the timestamps to regenerate if necessary. Also, the indexes are generated automatically. """ __author__ = 'Martin Blais ' __version__ = '$Revision$' #=============================================================================== # EXTERNAL DECLARATIONS #=============================================================================== import sys assert sys.version_info[0] == 2 if sys.version_info[1] > 1: import cgitb; cgitb.enable() import os, cgi, stat, re from os.path import * import commands from pprint import pprint from ConfigParser import ConfigParser #cgi.print_environ() if not os.environ.has_key('NO_CONTENT_TYPE'): print "Content-type: text/html" #=============================================================================== # LOCAL DECLARATIONS #=============================================================================== configfn = join(os.getcwd(), 'rst-server.conf') if not exists(configfn): print 'Error: config file "%s" does not exist' % configfn sys.exit(1) confparser = ConfigParser() confparser.add_section('options') confparser.read(configfn) class Dummy: pass opts = Dummy() for o in ['source', 'cache', 'converter']: if not confparser.has_option('options', o): print 'Error: must configure variable', o raise SystemExit() setattr(opts, o.replace('-', '_'), confparser.get('options', o)) for o in ['docutils-config']: val = None if confparser.has_option('options', o): val = confparser.get('options', o) setattr(opts, o.replace('-', '_'), val) form = cgi.FieldStorage() if form.has_key('p'): fn = form["p"].value else: fn = '' if os.environ.has_key('CONVERTER'): opts.converter = os.environ['CONVERTER'] # if from_php: # if len(sys.argv) > 1: # fn = sys.argv[1] #=============================================================================== # LOCAL DECLARATIONS #=============================================================================== rootstr = '(notes)' rejre = map(re.compile, ['^\s*[-=]+\s*$', '^\.\.', '^\s*$', '\s*:\w+:']) def gettitle( fn ): #print '
'
    try:
        f = open(fn, 'r')
        while 1:
            l = f.readline()
            if not l:
                break
            rej = 0
            for r in rejre:
                if r.match(l):
                    rej = 1
                    break
            if rej:
                #print l
                continue

            title = l.strip()
            break
        f.close()
    except:
        title = fn
    #print '
' # prevent tag-only titles, at least we'll get an error message if title[0] == '<' and title[-1] == '>': title = title[1:-1] return title valre = re.compile('(.*)\.txt') def nav( fn, script ): if fn and isfile(join(opts.source, fn)): mo = valre.match(fn) assert(mo) fn = mo.group(1) comps = [] if fn: fn = normpath(fn) comps += fn.split(os.sep) print '' print '' print '
' ccomps = [] cpath = '' if comps: for i in comps[0:-1]: cpath = join(cpath, i) ccomps.append('%s' % (script, cpath, i)) ccomps.append('%s' % comps[-1]) ccomps = ['%s' % (script, rootstr)] + ccomps print ' » '.join(ccomps) print '
' print """ """ script = os.environ['SCRIPT_NAME'] # make sure the cache directory exists if not exists(opts.cache): os.mkdir(opts.cache) if fn: srcfn = join(opts.source, fn) else: srcfn = opts.source nav(fn, script) class Page: def __init__( self, fn, base ): self.fn = fn self.base = base self.title = base if not exists(srcfn): print 'Error: this file does not exist' else: if isdir(srcfn): #cachefn = join(cache, fn, 'index.html') files, dirs = [], [] for f in os.listdir(srcfn): if f.startswith('.') or f.startswith('#'): continue if f == 'CVS': continue af = join(srcfn, f) if isfile(af): mo = valre.match(f) if mo: files.append( Page(f, mo.group(1)) ) elif isdir(af): dirs.append(f) print '' print '' else: if not fn.endswith('.txt'): print 'request for file not ending in .txt', fn sys.exit(0) cachefn = join(opts.cache, '%s.html' % splitext(fn)[0]) regen = 1 if exists(srcfn) and exists(cachefn): fnstat, cachestat = map(os.stat, [srcfn, cachefn]) if fnstat[stat.ST_MTIME] <= cachestat[stat.ST_MTIME]: # use cache regen = 0 if regen: cachedir = dirname(cachefn) if not exists(cachedir): os.makedirs(cachedir) cmd = opts.converter if opts.docutils_config: cmd += ' --config="%s"' % opts.docutils_config cmd += ' "%s" "%s" 2>&1' % (srcfn, cachefn) if 0: chin, chout, cherr = os.popen3(cmd) chin.close() err = chout.read() out = chout.read() else: s, out = commands.getstatusoutput(cmd) if out: print '
' print 'Error: converting document:' print '
'
                    print out
                    print '
' print '
' print open(cachefn, 'r').read() print """ """