Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / third_party / tvcm / tvcm / dev_server.py
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 import json
6 import optparse
7 import os
8 import sys
9 import time
10 import traceback
11 import base64
12
13 from tvcm import parse_deps
14 from tvcm import project as project_module
15 from tvcm import generate
16 from tvcm import resource_loader
17
18 import SocketServer
19 import SimpleHTTPServer
20 import BaseHTTPServer
21
22 DEPS_CHECK_DELAY = 30
23
24 class DevServerHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
25   def __init__(self, *args, **kwargs):
26     SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
27
28   def send_response(self, code, message=None):
29     SimpleHTTPServer.SimpleHTTPRequestHandler.send_response(self, code, message)
30     if code == 200:
31       self.send_header('Cache-Control', 'no-cache')
32
33   def do_GET(self):
34     if self.do_path_handler('GET'):
35       return
36
37     return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
38
39   def do_POST(self):
40     if self.do_path_handler('POST'):
41       return
42     return SimpleHTTPServer.SimpleHTTPRequestHandler.do_POST(self)
43
44
45   def do_path_handler(self, method):
46     handler = self.server.GetPathHandler(self.path, method)
47     if handler:
48       try:
49         handler(self)
50       except Exception, ex:
51         msg = json.dumps({"details": traceback.format_exc(),
52                           "message": ex.message});
53         self.log_error('While parsing %s: %s', self.path, ex.message)
54         self.send_response(500)
55         self.send_header('Content-Type', 'application/json')
56         self.send_header('Cache-Control', 'no-cache')
57         self.send_header('Content-Length', len(msg))
58         self.end_headers()
59         self.wfile.write(msg)
60       return True
61     return False
62
63   def translate_path(self, path):
64     path = path.split('?',1)[0]
65     path = path.split('#',1)[0]
66     for mapped_path in self.server.project.source_paths:
67       rel = os.path.relpath(path, '/')
68       candidate = os.path.join(mapped_path, rel)
69       if os.path.exists(candidate):
70         return candidate
71     return ''
72
73   def log_error(self, format, *args):
74     if self.server._quiet:
75       return
76     if self.path == '/favicon.ico':
77       return
78     self.log_message("While processing %s: ", self.path)
79     SimpleHTTPServer.SimpleHTTPRequestHandler.log_error(self, format, *args)
80
81   def log_request(self, code='-', size='-'):
82     # Dont spam the console unless it is important.
83     pass
84
85 def do_GET_json_tests(self):
86   test_module_names = self.server.project.FindAllTestModuleNames()
87
88   tests = {'test_module_names': test_module_names,
89            'test_links': self.server.test_links}
90   tests_as_json = json.dumps(tests);
91
92   self.send_response(200)
93   self.send_header('Content-Type', 'application/json')
94   self.send_header('Content-Length', len(tests_as_json))
95   self.end_headers()
96   self.wfile.write(tests_as_json)
97
98
99 def do_GET_deps(self):
100   try:
101     self.server.update_deps_and_templates()
102   except Exception, ex:
103     msg = json.dumps({"details": traceback.format_exc(),
104                       "message": ex.message});
105     self.log_error('While parsing deps: %s', ex.message)
106     self.send_response(500)
107     self.send_header('Content-Type', 'application/json')
108     self.send_header('Cache-Control', 'no-cache')
109     self.send_header('Content-Length', len(msg))
110     self.end_headers()
111     self.wfile.write(msg)
112     return
113   self.send_response(200)
114   self.send_header('Content-Type', 'application/javascript')
115   self.send_header('Content-Length', len(self.server.deps))
116   self.end_headers()
117   self.wfile.write(self.server.deps)
118
119 def do_GET_templates(self):
120   self.server.update_deps_and_templates()
121   self.send_response(200)
122   self.send_header('Content-Type', 'text/html')
123   self.send_header('Content-Length', len(self.server.templates))
124   self.end_headers()
125   self.wfile.write(self.server.templates)
126
127
128 class PathHandler(object):
129   def __init__(self, path, handler, supports_get, supports_post):
130     self.path = path
131     self.handler = handler
132     self.supports_get = supports_get
133     self.supports_post = supports_post
134
135   def CanHandle(self, path, method):
136     if path != self.path:
137       return False
138     if method == 'GET' and self.supports_get:
139       return True
140     if method == 'POST' and self.supports_post:
141       return True
142     return False
143
144 def do_GET_root(request):
145   request.send_response(301)
146   request.send_header("Location", request.server.default_path)
147   request.end_headers()
148
149 class DevServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
150   def __init__(self, port, quiet=False, project=None):
151     BaseHTTPServer.HTTPServer.__init__(self, ('', port), DevServerHandler)
152     self._quiet = quiet
153     if port == 0:
154       port = self.server_address[1]
155     self._port = port
156     self._path_handlers = []
157     self._test_links = []
158     if project:
159       self._project = project
160     else:
161       self._project = project_module.Project([])
162
163     self._next_deps_check = -1
164     self.deps = None
165
166     self.AddPathHandler('/', do_GET_root)
167     self.AddPathHandler('', do_GET_root)
168     self.default_path = '/tvcm/tests.html'
169
170     # Redirect old tests.html places to the new location until folks have gotten used to its new
171     # location.
172     self.AddPathHandler('/src/tests.html', do_GET_root)
173     self.AddPathHandler('/tests.html', do_GET_root)
174
175     self.AddPathHandler('/tvcm/json/tests', do_GET_json_tests)
176     self.AddPathHandler('/tvcm/all_templates.html', do_GET_templates)
177     self.AddPathHandler('/tvcm/deps.js', do_GET_deps)
178
179   def AddPathHandler(self, path, handler, supports_get=True, supports_post=False):
180     self._path_handlers.append(PathHandler(path, handler, supports_get, supports_post))
181
182   def GetPathHandler(self, path, method):
183     for h in self._path_handlers:
184       if h.CanHandle(path, method):
185         return h.handler
186     return None
187
188   def AddSourcePathMapping(self, file_system_path):
189     self._project.AddSourcePath(file_system_path)
190
191   def AddTestLink(self, path, title):
192     self._test_links.append({'path': path,
193                              'title': title})
194
195   @property
196   def test_links(self):
197     return self._test_links
198
199   @property
200   def project(self):
201     return self._project
202
203   def update_deps_and_templates(self):
204     current_time = time.time()
205     if self._next_deps_check >= current_time:
206       return
207
208     if not self._quiet:
209       sys.stderr.write('Regenerating deps and templates\n')
210
211     load_sequence = self.project.calc_load_sequence()
212     self.deps = generate.generate_deps_js(
213         load_sequence, self.project)
214     self.templates = generate.generate_html_for_combined_templates(
215         load_sequence)
216     self._next_deps_check = current_time + DEPS_CHECK_DELAY
217
218   @property
219   def port(self):
220     return self._port
221
222   def serve_forever(self):
223     if not self._quiet:
224       sys.stderr.write("Now running on http://localhost:%i\n" % self._port)
225     BaseHTTPServer.HTTPServer.serve_forever(self)