#!/usr/bin/env python # # Basic HTTP Server giving access to the CCP4i database # Based on the basichttp.py example - in ""Foundations of Python Network # Programming" (John Goerzen) Chapter 16 # This server takes requests in the form of # http://localhost:8765/?command=...&project=...&job=... etc # It then connects to the handler, retrieves some data and sends # back a HTML page #CCP4i_cvs_Id $Id: http_dbclient.py,v 1.9 2008/08/12 10:48:13 pjx Exp $ from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler import sys import time import dbClientAPI class RequestHandler(BaseHTTPRequestHandler): def _writeheaders(self): self.send_response(200) self.send_header('Content-type','text/html') self.end_headers() def do_HEAD(self): self._writeheaders() def do_GET(self): self._writeheaders() # decode the input data = decodeRequest(self.path) print "Request decoded" # Execute the request result = dbccp4i_request(data) print "Sending result to requester" self.wfile.write(""" DbCCP4i """) # Write the actual result self.wfile.write(result) # Report the parameters self.wfile.write("
Parameters for the request:\n") self.wfile.write("\n") self.wfile.write("
\n") # Add a little report self.wfile.write("
") self.wfile.write("Generated by http_dbclient "+\ dbClientAPI.ConvertTime(time.time())+\ "
\n") self.wfile.write("\n") print "Request sent" return def dbccp4i_request(data): print "Started processing request" # Get a connection to the handler db = dbClientAPI.HandlerConnection('http_dbccp4i',True) result = "" # Attempt to execute a handler request if not data.has_key("command"): # Assume that we want to list the available projects data["command"] = "ListProjects" # Available actions if data["command"] == "ListProjects": # Generate a list of projects with links to more commands result = "

List of projects

\n" projects = db.ListProjects() if len(projects) == 0: result += "

No projects available

" else: result += "\n" elif data["command"] == "ListJobs": # Generate a list of the jobs in the project project = data["project"] result = "

Project: "+str(project)+"

\n" if data.has_key("job"): result += "

Subjobs for job "+str(data["job"])+"

\n" if db.OpenProject(project,readonly=True): if data.has_key("job"): records = db.GetListofRecords(project,[data["job"]],\ ["DATE","STATUS","TASKNAME","TITLE"]) result += "

" result += str(records[0][2])+": \""+str(records[0][3])+"\"" result += "

\n" jobs = db.ListJobs(project,data["job"]) subjobs = [] else: jobs = db.ListJobs(project) subjobs = db.ListJobswithsubjobs(project) if len(jobs) == 0: result += "

There are currently no jobs in this project

\n" else: jobs.reverse() records = db.GetListofRecords(project,jobs,\ ["DATE","STATUS","TASKNAME","TITLE"]) result += """""" if not data.has_key("job"): result += "\n" for i in range(0,len(jobs)): result += "" result += "\n" j = 0 for item in records[i]: if j == 0: # Convert the DATE to a human readable form item = dbClientAPI.ConvertTimeCCP4i(float(item)) j += 1 result += "" # Indicate if there are subjobs available if not data.has_key("job"): try: subjobs.index(jobs[i]) result += "" except ValueError: result += "" result += "\n" result = result + "
IDDATE STATUSTASKNAMETITLESubjobs
"+str(jobs[i])+""+str(item)+"View subjobs 
\n" db.CloseProject(project) else: result = "

Unable to access the project

" # Links at the tail of the page # Refresh the view by executing the same request again result += "

" result += " [Refresh]" # Link for subjobs to return to main job view if data.has_key("job"): result += " [List jobs in "+str(project)+"]" # Write a link to get back to the list of projects result += " [Back to projects]" result += "

\n" # Finish with the handler connection db.HandlerDisconnect() # Return the result print "Finished building result HTML" return result # Supporting functions def decodeRequest(url): """Break up a url into a set of arguments and values. Given a url of the form path?key1=value1&key2=value2&... return a dictionary where the keys are key1, key2 etc and the corresponding values are value1, value2 etc.""" request = url.split("?") try: args = request[1].split("&") except IndexError: args = request data= {} for arg in args: try: key = arg.split("=")[0] value = arg.split("=")[1] data[key] = value except: print "Error decoding "+arg return data def buildRequest(args): """Make a request string from a dictionary Given a dictionary of the form { 'key1':value1, 'key2':value2, ... } return a string of the form '?key1=value1&key2=value2&...""" request = [] for key in args: request.append(str(key)+"="+str(args[key])) request.sort() return "?"+"&".join(request) # Main program try: # Start the HTTP server port = 8765 serveraddr = ('', port) srvr = HTTPServer(serveraddr, RequestHandler) print "http_dbclient listening on port %d" % port print "Point your browser at http://localhost:%d to connect" % port print "Using Ctrl-C to stop the server" srvr.serve_forever() except KeyboardInterrupt: print "Finished" sys.exit(0)