Index: chrome/common/extensions/docs/server2/render_refresher.py |
diff --git a/chrome/common/extensions/docs/server2/render_refresher.py b/chrome/common/extensions/docs/server2/render_refresher.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0bf19787d42201e5ddecab84dfee36edb19db674 |
--- /dev/null |
+++ b/chrome/common/extensions/docs/server2/render_refresher.py |
@@ -0,0 +1,101 @@ |
+# Copyright 2014 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import logging |
+import posixpath |
+ |
+from custom_logger import CustomLogger |
+from extensions_paths import EXAMPLES |
+from file_system_util import CreateURLsFromPaths |
+from future import Future |
+from render_servlet import RenderServlet |
+from special_paths import SITE_VERIFICATION_FILE |
+from timer import Timer |
+ |
+ |
+_SUPPORTED_TARGETS = { |
+ 'examples': (EXAMPLES, 'extensions/examples'), |
+} |
+ |
+ |
+_log = CustomLogger('render_refresher') |
+ |
+ |
+class _SingletonRenderServletDelegate(RenderServlet.Delegate): |
+ def __init__(self, server_instance): |
+ self._server_instance = server_instance |
+ |
+ def CreateServerInstance(self): |
+ return self._server_instance |
+ |
+ |
+def _RequestEachItem(title, items, request_callback): |
+ '''Runs a task |request_callback| named |title| for each item in |items|. |
+ |request_callback| must take an item and return a servlet response. |
+ Returns true if every item was successfully run, false if any return a |
+ non-200 response or raise an exception. |
+ ''' |
+ _log.info('%s: starting', title) |
+ success_count, failure_count = 0, 0 |
+ timer = Timer() |
+ try: |
+ for i, item in enumerate(items): |
+ def error_message(detail): |
+ return '%s: error rendering %s (%s of %s): %s' % ( |
+ title, item, i + 1, len(items), detail) |
+ try: |
+ response = request_callback(item) |
+ if response.status == 200: |
+ success_count += 1 |
+ else: |
+ _log.error(error_message('response status %s' % response.status)) |
+ failure_count += 1 |
+ except Exception as e: |
+ _log.error(error_message(traceback.format_exc())) |
+ failure_count += 1 |
+ if IsDeadlineExceededError(e): raise |
+ finally: |
+ _log.info('%s: rendered %s of %s with %s failures in %s', |
+ title, success_count, len(items), failure_count, |
+ timer.Stop().FormatElapsed()) |
+ return success_count == len(items) |
+ |
+ |
+class RenderRefresher(object): |
+ '''Used to refresh any set of renderable resources. Currently only supports |
+ assets related to extensions examples.''' |
+ def __init__(self, server_instance, request): |
+ self._server_instance = server_instance |
+ self._request = request |
+ |
+ def GetRefreshPaths(self): |
+ return _SUPPORTED_TARGETS.keys() |
+ |
+ def Refresh(self, path): |
+ def render(path): |
+ request = Request(path, self._request.host, self._request.headers) |
+ delegate = _SingletonRenderServletDelegate(self._server_instance) |
+ return RenderServlet(request, delegate).Get() |
+ |
+ def request_files_in_dir(path, prefix='', strip_ext=None): |
+ '''Requests every file found under |path| in this host file system, with |
+ a request prefix of |prefix|. |strip_ext| is an optional list of file |
+ extensions that should be stripped from paths before requesting. |
+ ''' |
+ def maybe_strip_ext(name): |
+ if name == SITE_VERIFICATION_FILE or not strip_ext: |
+ return name |
+ base, ext = posixpath.splitext(name) |
+ return base if ext in strip_ext else name |
+ files = [maybe_strip_ext(name) |
+ for name, _ in CreateURLsFromPaths(master_fs, path, prefix)] |
+ return _RequestEachItem(path, files, render) |
+ |
+ # Only support examples for now. |
+ if path not in _SUPPORTED_TARGETS: |
+ return Future(callback=lambda: False) |
+ |
+ dir = _SUPPORTED_TARGETS[path][0] |
+ prefix = _SUPPORTED_TARGETS[path][1] |
+ return request_files_in_dir(dir, prefix=prefix) |