#!/usr/nlocal/bin/python

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

import NaviHTTP
from EditServer import HTTPError

class CVSRequestHandler(NaviHTTP.NaviRequestHandler):

        work = '/afs/w3.org/team/WWW'
        cvsroot = '/afs/w3.org/pub/WWW'

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

	    p = self.translate_path(path)

	    if p[:len(r)] == r:
		p = p[len(r):]
		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; CVSROOT=%s cvs %s %s' % (self.work, 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, 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 = 'cvs-put.py port'

    if len(argv) == 2:
	port = string.atoi(argv[1])
	nowstr = time.asctime(time.localtime(time.time()))
	print "Serving HTTP on port %d at %s\n" % (port, nowstr)
	print "You should probably redirect this log -- stdout and stderr."
	print "csh: python cvs-put.py port >>^ log-file"
	print "sh: python cvs-put.py port >>log-file 2>&1"
    else:
	raise Usage
    server_address = ('', port)

    httpd = BaseHTTPServer.HTTPServer(server_address, CVSRequestHandler)

    print "Serving HTTP on port", port, "..."

    httpd.serve_forever()

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