#!/usr/nlocal/bin/python

import sys
import os, string, regex
import posix, time, socket
import BaseHTTPServer

import NaviHTTP
from EditServer import HTTPError

class CVSRequestHandler(NaviHTTP.NaviRequestHandler):

        work = '/afs/w3.org/pub'
        cvsroot = '/afs/w3.org/CVS-Repository'

	def find_module(self, path):
	    self.separator = ''
	    r = self.work

	    p = self.translate_path(path)

	    if p[:len(r)] == r:
		p = p[len(r):]
		if p[:4] == '/WWW': # @# Hack!
		    p = p[4:]
		    self.separator = '/WWW'
		return os.path.dirname(p)[1:], os.path.basename(p), p
	    else:
		raise HTTPError, (403, 'Cannot find module for: ' + path)


	def start_cvs(self, module, cmd, args):
	    return os.popen('cd %s%s/%s; CVSROOT=%s cvs %s %s' % \
		(self.work, self.separator, module, self.cvsroot, cmd, args))


	def run_cvs(self, module, cmd, args):
	    f = self.start_cvs(module, cmd, args)
	    f.read()
	    f.close()


	def cvs_status(self, module, file):
	    f = self.start_cvs(module, 'status', file)
	    d = f.read()
	    f.close()
	    re = regex.compile("""Status: +\([^\n]+\)""")

	    if re.search(d) >= 0:
		return re.group(1)


	def put(self):
	    (module, file, path) = self.find_module(self.path)

	    s = self.cvs_status(module, file)

	    print "@@Status:", s

	    commitargs = "-m 'HTTP put from %s (%s)' %s" \
		       % (self.address_string(), self.client_address, file)

	    if s == 'Locally Modified':
		raise HTTPError, (403, "Working copy newer than checked-in version")
	    elif s == 'Unknown':
		if os.path.exists(path):
		    raise HTTPError, (403, "Working copy is not checked in")

		self.saveContent(module, file)
		self.run_cvs(module, 'add', file)
		self.run_cvs(module, 'commit', commitargs)
	    elif s == 'Up-to-date':
		try:
		    self.saveContent(module, file)
		    self.run_cvs(module, 'commit', commitargs)
		except:
		    # Restore previous version
		    try: posix.unlink(path)
		    except: pass
		    f = self.run_cvs(module, 'update', file)
		    raise sys.exc_type, sys.exc_value
	    else:
		raise HTTPError, (403, "Status: " + `s`)

	    self.send_response(200)
	    self.send_header("Content-Type", "text/html")
	    self.end_headers()

	    self.wfile.write("<!doctype html><p>done!\n")


	def saveContent(self, module, file):
	    P = os.path

	    l = self.content_length()
	    path = P.join(P.join(self.work + self.separator, module), file)

#	    print "@@", path, self.headers.headers

	    try:
		sv = open(path, "w")
		sv.write(self.rfile.read(l))
		sv.close()
	    except IOError:
		raise HTTPError, (500, "Error writing file: " + `sys.exc_type` + `sys.exc_value`)

def test():
    import sys

    r = CVSRequestHandler('/afs/w3.org/www-name/WWW-connolly', '/afs/w3.org/pub/WWW')
    r.rfile = sys.stdin
    r.wfile = sys.stdout
    r.client_address = ('beach.w3.org', 4000)
    r.handle()

def main(argv):

    Usage = 'edit-server [port]'

    if len(argv) == 2:
	port = string.atoi(argv[1])
    else:
        port = 8000 + (posix.getuid() % 1000)

    while 1:
	try:
	    server_address = ('', port)
	    httpd = BaseHTTPServer.HTTPServer(server_address,
					      CVSRequestHandler)
	    break
	except socket.error:
	    print "Port", port, "in use. Trying another..."
	    port = port + 1

    nowstr = time.asctime(time.localtime(time.time()))
    print "Serving HTTP on port %d at %s\n" % (port, nowstr)

    logfile = open(posix.environ['HOME'] +'/edit-server-log', "a+", 0)

    sys.stdout = sys.stderr = logfile
    print "Serving HTTP on port %d at %s\n" % (port, nowstr)

    httpd.serve_forever()

if __name__ == '__main__':
    import sys
    main(sys.argv)
