OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 """ | 3 """ |
4 Copyright 2013 Google Inc. | 4 Copyright 2013 Google Inc. |
5 | 5 |
6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
7 found in the LICENSE file. | 7 found in the LICENSE file. |
8 | 8 |
9 HTTP server for our HTML rebaseline viewer. | 9 HTTP server for our HTML rebaseline viewer. |
10 """ | 10 """ |
11 | 11 |
12 # System-level imports | 12 # System-level imports |
13 import argparse | 13 import argparse |
14 import BaseHTTPServer | 14 import BaseHTTPServer |
15 import json | 15 import json |
16 import logging | 16 import logging |
17 import os | 17 import os |
18 import posixpath | 18 import posixpath |
19 import re | 19 import re |
20 import shutil | 20 import shutil |
| 21 import socket |
21 import sys | 22 import sys |
22 import thread | 23 import thread |
23 import time | 24 import time |
24 import urlparse | 25 import urlparse |
25 | 26 |
26 # Imports from within Skia | 27 # Imports from within Skia |
27 # | 28 # |
28 # We need to add the 'tools' directory, so that we can import svn.py within | 29 # We need to add the 'tools' directory, so that we can import svn.py within |
29 # that directory. | 30 # that directory. |
30 # Make sure that the 'tools' dir is in the PYTHONPATH, but add it at the *end* | 31 # Make sure that the 'tools' dir is in the PYTHONPATH, but add it at the *end* |
(...skipping 27 matching lines...) Expand all Loading... |
58 | 59 |
59 DEFAULT_ACTUALS_DIR = '.gm-actuals' | 60 DEFAULT_ACTUALS_DIR = '.gm-actuals' |
60 DEFAULT_EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm') | 61 DEFAULT_EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm') |
61 DEFAULT_PORT = 8888 | 62 DEFAULT_PORT = 8888 |
62 | 63 |
63 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length' | 64 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length' |
64 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type' | 65 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type' |
65 | 66 |
66 _SERVER = None # This gets filled in by main() | 67 _SERVER = None # This gets filled in by main() |
67 | 68 |
| 69 def get_routable_ip_address(): |
| 70 """Returns routable IP address of this host (the IP address of its network |
| 71 interface that would be used for most traffic, not its localhost |
| 72 interface). See http://stackoverflow.com/a/166589 """ |
| 73 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) |
| 74 sock.connect(('8.8.8.8', 80)) |
| 75 host = sock.getsockname()[0] |
| 76 sock.close() |
| 77 return host |
| 78 |
| 79 |
68 class Server(object): | 80 class Server(object): |
69 """ HTTP server for our HTML rebaseline viewer. """ | 81 """ HTTP server for our HTML rebaseline viewer. """ |
70 | 82 |
71 def __init__(self, | 83 def __init__(self, |
72 actuals_dir=DEFAULT_ACTUALS_DIR, | 84 actuals_dir=DEFAULT_ACTUALS_DIR, |
73 expectations_dir=DEFAULT_EXPECTATIONS_DIR, | 85 expectations_dir=DEFAULT_EXPECTATIONS_DIR, |
74 port=DEFAULT_PORT, export=False, editable=True, | 86 port=DEFAULT_PORT, export=False, editable=True, |
75 reload_seconds=0): | 87 reload_seconds=0): |
76 """ | 88 """ |
77 Args: | 89 Args: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 time.sleep(self._reload_seconds) | 169 time.sleep(self._reload_seconds) |
158 self.update_results() | 170 self.update_results() |
159 | 171 |
160 def run(self): | 172 def run(self): |
161 self.results_lock = thread.allocate_lock() | 173 self.results_lock = thread.allocate_lock() |
162 self.update_results() | 174 self.update_results() |
163 thread.start_new_thread(self._result_reloader, ()) | 175 thread.start_new_thread(self._result_reloader, ()) |
164 | 176 |
165 if self._export: | 177 if self._export: |
166 server_address = ('', self._port) | 178 server_address = ('', self._port) |
| 179 host = get_routable_ip_address() |
167 if self._editable: | 180 if self._editable: |
168 logging.warning('Running with combination of "export" and "editable" ' | 181 logging.warning('Running with combination of "export" and "editable" ' |
169 'flags. Users on other machines will ' | 182 'flags. Users on other machines will ' |
170 'be able to modify your GM expectations!') | 183 'be able to modify your GM expectations!') |
171 else: | 184 else: |
172 server_address = ('127.0.0.1', self._port) | 185 host = '127.0.0.1' |
| 186 server_address = (host, self._port) |
173 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) | 187 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) |
174 logging.info('Ready for requests on http://%s:%d' % ( | 188 logging.info('Ready for requests on http://%s:%d' % (host, http_server.serve
r_port)) |
175 http_server.server_name, http_server.server_port)) | |
176 http_server.serve_forever() | 189 http_server.serve_forever() |
177 | 190 |
178 | 191 |
179 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 192 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
180 """ HTTP request handlers for various types of queries this server knows | 193 """ HTTP request handlers for various types of queries this server knows |
181 how to handle (static HTML and Javascript, expected/actual results, etc.) | 194 how to handle (static HTML and Javascript, expected/actual results, etc.) |
182 """ | 195 """ |
183 def do_GET(self): | 196 def do_GET(self): |
184 """ Handles all GET requests, forwarding them to the appropriate | 197 """ Handles all GET requests, forwarding them to the appropriate |
185 do_GET_* dispatcher. """ | 198 do_GET_* dispatcher. """ |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 args = parser.parse_args() | 438 args = parser.parse_args() |
426 global _SERVER | 439 global _SERVER |
427 _SERVER = Server(actuals_dir=args.actuals_dir, | 440 _SERVER = Server(actuals_dir=args.actuals_dir, |
428 expectations_dir=args.expectations_dir, | 441 expectations_dir=args.expectations_dir, |
429 port=args.port, export=args.export, editable=args.editable, | 442 port=args.port, export=args.export, editable=args.editable, |
430 reload_seconds=args.reload) | 443 reload_seconds=args.reload) |
431 _SERVER.run() | 444 _SERVER.run() |
432 | 445 |
433 if __name__ == '__main__': | 446 if __name__ == '__main__': |
434 main() | 447 main() |
OLD | NEW |