1 #!/usr/bin/env python 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 3 # Use of this source code is governed by a BSD-style license that can be 4 # found in the LICENSE file. 5 6 # This helps you preview the apps and extensions docs. 7 # 8 # ./preview.py --help 9 # 10 # There are two modes: server- and render- mode. The default is server, in which 11 # a webserver is started on a port (default 8000). Navigating to paths on 12 # http://localhost:8000, for example 13 # 14 # http://localhost:8000/extensions/tabs.html 15 # 16 # will render the documentation for the extension tabs API. 17 # 18 # On the other hand, render mode statically renders docs to stdout. Use this 19 # to save the output (more convenient than needing to save the page in a 20 # browser), handy when uploading the docs somewhere (e.g. for a review), 21 # and for profiling the server. For example, 22 # 23 # ./preview.py -r extensions/tabs.html 24 # 25 # will output the documentation for the tabs API on stdout and exit immediately. 26 27 # NOTE: RUN THIS FIRST. Or all third_party imports will fail. 28 import build_server 29 # Copy all the files necessary to run the server. These are cleaned up when the 30 # server quits. 31 build_server.main() 32 33 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 34 import logging 35 import optparse 36 import os 37 import sys 38 import time 39 40 from local_renderer import LocalRenderer 41 42 class _RequestHandler(BaseHTTPRequestHandler): 43 '''A HTTPRequestHandler that outputs the docs page generated by Handler. 44 ''' 45 def do_GET(self): 46 response = LocalRenderer.Render(self.path) 47 self.send_response(response.status) 48 for k, v in response.headers.iteritems(): 49 self.send_header(k, v) 50 self.end_headers() 51 self.wfile.write(response.content.ToString()) 52 53 if __name__ == '__main__': 54 parser = optparse.OptionParser( 55 description='Runs a server to preview the extension documentation.', 56 usage='usage: %prog [option]...') 57 parser.add_option('-p', '--port', default='8000', 58 help='port to run the server on') 59 parser.add_option('-r', '--render', default='', 60 help='statically render a page and print to stdout rather than starting ' 61 'the server, e.g. apps/storage.html. The path may optionally end ' 62 'with #n where n is the number of times to render the page before ' 63 'printing it, e.g. apps/storage.html#50, to use for profiling.') 64 parser.add_option('-t', '--time', action='store_true', 65 help='Print the time taken rendering rather than the result.') 66 67 (opts, argv) = parser.parse_args() 68 69 if opts.render: 70 if opts.render.find('#') >= 0: 71 (path, iterations) = opts.render.rsplit('#', 1) 72 extra_iterations = int(iterations) - 1 73 else: 74 path = opts.render 75 extra_iterations = 0 76 77 if opts.time: 78 start_time = time.time() 79 80 response = LocalRenderer.Render(path) 81 if response.status != 200: 82 print('Error status: %s' % response.status) 83 exit(1) 84 85 for _ in range(extra_iterations): 86 LocalRenderer.Render(path) 87 88 if opts.time: 89 print('Took %s seconds' % (time.time() - start_time)) 90 else: 91 print(response.content.ToString()) 92 exit() 93 94 print('Starting previewserver on port %s' % opts.port) 95 print('') 96 print('The extension documentation can be found at:') 97 print('') 98 print(' http://localhost:%s/extensions/' % opts.port) 99 print('') 100 print('The apps documentation can be found at:') 101 print('') 102 print(' http://localhost:%s/apps/' % opts.port) 103 print('') 104 105 logging.getLogger().setLevel(logging.INFO) 106 server = HTTPServer(('', int(opts.port)), _RequestHandler) 107 try: 108 server.serve_forever() 109 finally: 110 server.socket.close() 111