Adding the orphaned options pages to the navigation
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / render_refresher.py
blob0bf19787d42201e5ddecab84dfee36edb19db674
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import logging
6 import posixpath
8 from custom_logger import CustomLogger
9 from extensions_paths import EXAMPLES
10 from file_system_util import CreateURLsFromPaths
11 from future import Future
12 from render_servlet import RenderServlet
13 from special_paths import SITE_VERIFICATION_FILE
14 from timer import Timer
17 _SUPPORTED_TARGETS = {
18 'examples': (EXAMPLES, 'extensions/examples'),
22 _log = CustomLogger('render_refresher')
25 class _SingletonRenderServletDelegate(RenderServlet.Delegate):
26 def __init__(self, server_instance):
27 self._server_instance = server_instance
29 def CreateServerInstance(self):
30 return self._server_instance
33 def _RequestEachItem(title, items, request_callback):
34 '''Runs a task |request_callback| named |title| for each item in |items|.
35 |request_callback| must take an item and return a servlet response.
36 Returns true if every item was successfully run, false if any return a
37 non-200 response or raise an exception.
38 '''
39 _log.info('%s: starting', title)
40 success_count, failure_count = 0, 0
41 timer = Timer()
42 try:
43 for i, item in enumerate(items):
44 def error_message(detail):
45 return '%s: error rendering %s (%s of %s): %s' % (
46 title, item, i + 1, len(items), detail)
47 try:
48 response = request_callback(item)
49 if response.status == 200:
50 success_count += 1
51 else:
52 _log.error(error_message('response status %s' % response.status))
53 failure_count += 1
54 except Exception as e:
55 _log.error(error_message(traceback.format_exc()))
56 failure_count += 1
57 if IsDeadlineExceededError(e): raise
58 finally:
59 _log.info('%s: rendered %s of %s with %s failures in %s',
60 title, success_count, len(items), failure_count,
61 timer.Stop().FormatElapsed())
62 return success_count == len(items)
65 class RenderRefresher(object):
66 '''Used to refresh any set of renderable resources. Currently only supports
67 assets related to extensions examples.'''
68 def __init__(self, server_instance, request):
69 self._server_instance = server_instance
70 self._request = request
72 def GetRefreshPaths(self):
73 return _SUPPORTED_TARGETS.keys()
75 def Refresh(self, path):
76 def render(path):
77 request = Request(path, self._request.host, self._request.headers)
78 delegate = _SingletonRenderServletDelegate(self._server_instance)
79 return RenderServlet(request, delegate).Get()
81 def request_files_in_dir(path, prefix='', strip_ext=None):
82 '''Requests every file found under |path| in this host file system, with
83 a request prefix of |prefix|. |strip_ext| is an optional list of file
84 extensions that should be stripped from paths before requesting.
85 '''
86 def maybe_strip_ext(name):
87 if name == SITE_VERIFICATION_FILE or not strip_ext:
88 return name
89 base, ext = posixpath.splitext(name)
90 return base if ext in strip_ext else name
91 files = [maybe_strip_ext(name)
92 for name, _ in CreateURLsFromPaths(master_fs, path, prefix)]
93 return _RequestEachItem(path, files, render)
95 # Only support examples for now.
96 if path not in _SUPPORTED_TARGETS:
97 return Future(callback=lambda: False)
99 dir = _SUPPORTED_TARGETS[path][0]
100 prefix = _SUPPORTED_TARGETS[path][1]
101 return request_files_in_dir(dir, prefix=prefix)