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 time 37 38 from local_renderer import LocalRenderer 39 40 class _RequestHandler(BaseHTTPRequestHandler): 41 '''A HTTPRequestHandler that outputs the docs page generated by Handler. 42 ''' 43 def do_GET(self): 44 response = LocalRenderer.Render(self.path) 45 self.send_response(response.status) 46 for k, v in response.headers.iteritems(): 47 self.send_header(k, v) 48 self.end_headers() 49 self.wfile.write(response.content.ToString()) 50 51 if __name__ == '__main__': 52 parser = optparse.OptionParser( 53 description='Runs a server to preview the extension documentation.', 54 usage='usage: %prog [option]...') 55 parser.add_option('-p', '--port', default='8000', 56 help='port to run the server on') 57 parser.add_option('-r', '--render', default='', 58 help='statically render a page and print to stdout rather than starting ' 59 'the server, e.g. apps/storage.html. The path may optionally end ' 60 'with #n where n is the number of times to render the page before ' 61 'printing it, e.g. apps/storage.html#50, to use for profiling.') 62 parser.add_option('-t', '--time', action='store_true', 63 help='Print the time taken rendering rather than the result.') 64 65 (opts, argv) = parser.parse_args() 66 67 if opts.render: 68 if opts.render.find('#') >= 0: 69 (path, iterations) = opts.render.rsplit('#', 1) 70 extra_iterations = int(iterations) - 1 71 else: 72 path = opts.render 73 extra_iterations = 0 74 75 if opts.time: 76 start_time = time.time() 77 78 response = LocalRenderer.Render(path) 79 if response.status != 200: 80 print('Error status: %s' % response.status) 81 exit(1) 82 83 for _ in range(extra_iterations): 84 LocalRenderer.Render(path) 85 86 if opts.time: 87 print('Took %s seconds' % (time.time() - start_time)) 88 else: 89 print(response.content.ToString()) 90 exit() 91 92 print('Starting previewserver on port %s' % opts.port) 93 print('') 94 print('The extension documentation can be found at:') 95 print('') 96 print(' http://localhost:%s/extensions/' % opts.port) 97 print('') 98 print('The apps documentation can be found at:') 99 print('') 100 print(' http://localhost:%s/apps/' % opts.port) 101 print('') 102 103 logging.getLogger().setLevel(logging.INFO) 104 server = HTTPServer(('', int(opts.port)), _RequestHandler) 105 try: 106 server.serve_forever() 107 finally: 108 server.socket.close() 109