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.
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.
39 _log
.info('%s: starting', title
)
40 success_count
, failure_count
= 0, 0
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
)
48 response
= request_callback(item
)
49 if response
.status
== 200:
52 _log
.error(error_message('response status %s' % response
.status
))
54 except Exception as e
:
55 _log
.error(error_message(traceback
.format_exc()))
57 if IsDeadlineExceededError(e
): raise
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
):
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.
86 def maybe_strip_ext(name
):
87 if name
== SITE_VERIFICATION_FILE
or not strip_ext
:
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
)