try: import BaseHTTPServer except ImportError: import http.server as BaseHTTPServer import time import cgi import threading import traceback from pymol import cmd _server = None def _shutdown(self_cmd=cmd): if _server != None: _server.socket.close() self_cmd.quit() # Note, this handler assumes PyMOL is running as a global singleton def get_status(out, self_cmd=cmd): out.write('\n') out.write('
\n') out.write('\n') out.write('
\n') out.write('

PyMOL WebGUI Proof of Concept

\n') out.write('\n') out.write('\n') out.write('\n'% time.time()) out.write('\n'% time.time()) out.write('\n') out.write('
') out.write('load $TUT/1hpv.pdb\n') names = self_cmd.get_names('objects') if not len(names): out.write('

No objects loaded.

\n') else: out.write('

Loaded Objects:

\n') out.write(''%time.time()+"") out.write('\n') def get_monitor(out, self_cmd=cmd): out.write('\n') out.write('
\n') out.write('\n') out.write('
\n') out.write(''%time.time()+"") out.write('\n') def get_start(out, self_cmd=cmd): window_open="javascript: window.open('./status.pymol','hello', 'location=no,toolbar=no,width=400,height=600,top=0,left=880');" out.write('\n') out.write('Launch WebGUI\n') out.write('') def write_image(out, ray=0, self_cmd=cmd): if ray: self_cmd.ray() # encode the file descriptor into the PNG filename if self_cmd.png(chr(1)+str(out.fileno()),prior=-1) != 1: # no prior image available, so wait for update / finish self_cmd.sync() class PymolHandler(BaseHTTPServer.BaseHTTPRequestHandler): def log_message(self, format, *args): pass # nuke logging feature for the time being def do_js(self): self.send_response(200) self.send_header('Content-type','text/javascript') self.end_headers() self.wfile.write(''' function updateImage() { images = document.getElementsByTagName("img"); for( var i = 0; i < images.length; i++ ) { images[i].src = "./draw.pymol?t=" + new Date().getTime(); } return false; } function monitorOnLoad(event) { setInterval('updateImage()',1000) } ''') def do_pymol(self): if "ray.pymol" in self.path: # send image self.send_response(200) self.send_header('Content-type', 'image/x-png') self.send_header('Cache-control', 'no-cache') self.send_header('Pragma', 'no-cache') self.end_headers() write_image(self.wfile,1) elif "draw.pymol" in self.path: self.send_response(200) self.send_header('Content-type', 'image/x-png') self.send_header('Cache-control', 'no-cache') self.send_header('Pragma', 'no-cache') self.end_headers() write_image(self.wfile) else: if "load" in self.path: # load a structure cmd.load("$TUT/1hpv.pdb") cmd.rock() self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() if "status.pymol" in self.path: get_status(self.wfile) elif "monitor.pymol" in self.path: get_monitor(self.wfile) elif "quit.pymol" in self.path: self.wfile.write('

Quitting...

') self.wfile.flush() _shutdown() else: # start page get_start(self.wfile) self.wfile.flush() def do_GET(self): try: doc = self.path.split('?')[0] if doc.endswith('.pymol'): # PyMOL try: self.do_pymol() except: traceback.print_exc() elif doc.endswith('.js'): # Javascript self.do_js() elif doc.endswith('.html'): f = open('.'+self.path) # UNSAFE!!! self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(f.read()) f.close() except IOError: self.send_error(404,'File Not Found: %s' % self.path) def do_POST(self): global rootnode try: ctype, pdict = cgi.parse_header(self.headers.getheader('content-type')) if ctype == 'multipart/form-data': query=cgi.parse_multipart(self.rfile, pdict) self.send_response(301) self.end_headers() upfilecontent = query.get('upfile') print("filecontent", upfilecontent[0]) self.wfile.write('POST OK.

'); self.wfile.write(upfilecontent[0]); except : pass def main(): try: global _server _server = BaseHTTPServer.HTTPServer(('', 8080), PymolHandler) print('started httpserver...') _server.serve_forever() except KeyboardInterrupt: print('^C received, shutting down server') _server.socket.close() def open_browser(): import webbrowser time.sleep(1) webbrowser.open('http://localhost:8080/status.pymol') # import os # os.system('open http://localhost:8080/start.pymol') if __name__ == '__main__': main() if __name__ == 'pymol': cmd.set("image_copy_always") # copy all updates into image buffer t = threading.Thread(target=main) t.setDaemon(1) t.start() t = threading.Thread(target=open_browser) t.setDaemon(1) t.start() """ okay, what we need now is a simple safe way to pass comands and arguments through the client brower, with escape characters, etc. ideally, we'd like a javascript object which responds to the same messages as PyMOL for our initial test, let's just put up some button links to control representations. also outstanding: - how does one send asynchronous javascript URL requests? - we also need some way to package up images in PyMOL without passaging through the file systems - we also need to decide what this initial user interface is going to do """