OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # This helps you preview the apps and extensions docs. | 6 # This helps you preview the apps and extensions docs. |
7 # | 7 # |
8 # ./preview.py --help | 8 # ./preview.py --help |
9 # | 9 # |
10 # There are two modes: server- and render- mode. The default is server, in which | 10 # There are two modes: server- and render- mode. The default is server, in which |
(...skipping 15 matching lines...) Expand all Loading... |
26 # | 26 # |
27 # Note: absolute paths into static content (e.g. /static/css/site.css) will be | 27 # Note: absolute paths into static content (e.g. /static/css/site.css) will be |
28 # relative paths (e.g. static/css/site.css) for convenient sandboxing. | 28 # relative paths (e.g. static/css/site.css) for convenient sandboxing. |
29 | 29 |
30 # NOTE: RUN THIS FIRST. Or all third_party imports will fail. | 30 # NOTE: RUN THIS FIRST. Or all third_party imports will fail. |
31 import build_server | 31 import build_server |
32 # Copy all the files necessary to run the server. These are cleaned up when the | 32 # Copy all the files necessary to run the server. These are cleaned up when the |
33 # server quits. | 33 # server quits. |
34 build_server.main() | 34 build_server.main() |
35 | 35 |
36 from render_servlet import AlwaysOnline | |
37 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer | 36 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer |
38 from local_renderer import LocalRenderer | |
39 import logging | 37 import logging |
40 import optparse | 38 import optparse |
41 import os | 39 import os |
42 import sys | 40 import sys |
43 import time | 41 import time |
44 | 42 |
45 def _GetLocalPath(): | 43 from local_renderer import LocalRenderer |
46 if os.sep in sys.argv[0]: | |
47 return os.path.join(sys.argv[0].rsplit(os.sep, 1)[0], os.pardir, os.pardir) | |
48 return os.path.join(os.pardir, os.pardir) | |
49 | 44 |
50 @AlwaysOnline | 45 class _RequestHandler(BaseHTTPRequestHandler): |
51 def _Render(base_dir, path): | 46 '''A HTTPRequestHandler that outputs the docs page generated by Handler. |
52 renderer = LocalRenderer(base_dir) | 47 ''' |
53 response = renderer.Render(path) | |
54 while response.status in [301, 302]: | |
55 redirect = response.headers['Location'].lstrip('/') | |
56 sys.stderr.write('<!-- Redirected %s to %s -->\n' % (path, redirect)) | |
57 response = renderer.Render(redirect) | |
58 return response | |
59 | |
60 class RequestHandler(BaseHTTPRequestHandler): | |
61 class Factory(object): | |
62 def __init__(self, base_dir): | |
63 self._base_dir = base_dir | |
64 | |
65 def Create(self, *args): | |
66 return RequestHandler(self._base_dir, *args) | |
67 | |
68 def __init__(self, base_dir, *args): | |
69 self._base_dir = base_dir | |
70 BaseHTTPRequestHandler.__init__(self, *args) | |
71 | |
72 """A HTTPRequestHandler that outputs the docs page generated by Handler. | |
73 """ | |
74 def do_GET(self): | 48 def do_GET(self): |
75 response = _Render(self._base_dir, self.path) | 49 response = LocalRenderer.Render(self.path) |
76 self.send_response(response.status) | 50 self.send_response(response.status) |
77 for k, v in response.headers.iteritems(): | 51 for k, v in response.headers.iteritems(): |
78 self.send_header(k, v) | 52 self.send_header(k, v) |
79 self.end_headers() | 53 self.end_headers() |
80 self.wfile.write(response.content) | 54 self.wfile.write(response.content.ToString()) |
81 | 55 |
82 if __name__ == '__main__': | 56 if __name__ == '__main__': |
83 parser = optparse.OptionParser( | 57 parser = optparse.OptionParser( |
84 description='Runs a server to preview the extension documentation.', | 58 description='Runs a server to preview the extension documentation.', |
85 usage='usage: %prog [option]...') | 59 usage='usage: %prog [option]...') |
86 parser.add_option('-p', '--port', default='8000', | 60 parser.add_option('-p', '--port', default='8000', |
87 help='port to run the server on') | 61 help='port to run the server on') |
88 parser.add_option('-d', '--directory', default=_GetLocalPath(), | |
89 help='extensions directory to serve from - ' | |
90 'should be chrome/common/extensions within a Chromium checkout') | |
91 parser.add_option('-r', '--render', default='', | 62 parser.add_option('-r', '--render', default='', |
92 help='statically render a page and print to stdout rather than starting ' | 63 help='statically render a page and print to stdout rather than starting ' |
93 'the server, e.g. apps/storage.html. The path may optionally end ' | 64 'the server, e.g. apps/storage.html. The path may optionally end ' |
94 'with #n where n is the number of times to render the page before ' | 65 'with #n where n is the number of times to render the page before ' |
95 'printing it, e.g. apps/storage.html#50, to use for profiling.') | 66 'printing it, e.g. apps/storage.html#50, to use for profiling.') |
96 parser.add_option('-t', '--time', action='store_true', | 67 parser.add_option('-t', '--time', action='store_true', |
97 help='Print the time taken rendering rather than the result.') | 68 help='Print the time taken rendering rather than the result.') |
98 | 69 |
99 (opts, argv) = parser.parse_args() | 70 (opts, argv) = parser.parse_args() |
100 | 71 |
101 if (not os.path.isdir(opts.directory) or | |
102 not os.path.isdir(os.path.join(opts.directory, 'docs')) or | |
103 not os.path.isdir(os.path.join(opts.directory, 'api'))): | |
104 print('Specified directory does not exist or does not contain extension ' | |
105 'docs.') | |
106 exit() | |
107 | |
108 if opts.render: | 72 if opts.render: |
109 if opts.render.find('#') >= 0: | 73 if opts.render.find('#') >= 0: |
110 (path, iterations) = opts.render.rsplit('#', 1) | 74 (path, iterations) = opts.render.rsplit('#', 1) |
111 extra_iterations = int(iterations) - 1 | 75 extra_iterations = int(iterations) - 1 |
112 else: | 76 else: |
113 path = opts.render | 77 path = opts.render |
114 extra_iterations = 0 | 78 extra_iterations = 0 |
115 | 79 |
116 if opts.time: | 80 if opts.time: |
117 start_time = time.time() | 81 start_time = time.time() |
118 | 82 |
119 response = _Render(opts.directory, path) | 83 response = LocalRenderer.Render(path) |
120 if response.status != 200: | 84 if response.status != 200: |
121 print('Error status: %s' % response.status) | 85 print('Error status: %s' % response.status) |
122 exit(1) | 86 exit(1) |
123 | 87 |
124 for _ in range(extra_iterations): | 88 for _ in range(extra_iterations): |
125 _Render(opts.directory, path) | 89 LocalRenderer.Render(path) |
126 | 90 |
127 if opts.time: | 91 if opts.time: |
128 print('Took %s seconds' % (time.time() - start_time)) | 92 print('Took %s seconds' % (time.time() - start_time)) |
129 else: | 93 else: |
130 # Static paths will show up as /stable/static/foo but this only makes | 94 # Static paths will show up as /stable/static/foo but this only makes |
131 # sense from a webserver. | 95 # sense from a webserver. |
132 print(content.replace('/stable/static', 'static')) | 96 print(content.replace('/stable/static', 'static')) |
133 exit() | 97 exit() |
134 | 98 |
135 print('Starting previewserver on port %s' % opts.port) | 99 print('Starting previewserver on port %s' % opts.port) |
136 print('') | 100 print('') |
137 print('The extension documentation can be found at:') | 101 print('The extension documentation can be found at:') |
138 print('') | 102 print('') |
139 print(' http://localhost:%s/extensions/' % opts.port) | 103 print(' http://localhost:%s/extensions/' % opts.port) |
140 print('') | 104 print('') |
141 print('The apps documentation can be found at:') | 105 print('The apps documentation can be found at:') |
142 print('') | 106 print('') |
143 print(' http://localhost:%s/apps/' % opts.port) | 107 print(' http://localhost:%s/apps/' % opts.port) |
144 print('') | 108 print('') |
145 | 109 |
146 logging.getLogger().setLevel(logging.INFO) | 110 logging.getLogger().setLevel(logging.INFO) |
147 server = HTTPServer(('', int(opts.port)), | 111 server = HTTPServer(('', int(opts.port)), _RequestHandler) |
148 RequestHandler.Factory(opts.directory).Create) | |
149 try: | 112 try: |
150 server.serve_forever() | 113 server.serve_forever() |
151 finally: | 114 finally: |
152 server.socket.close() | 115 server.socket.close() |
OLD | NEW |