OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import logging | 5 import logging |
6 import os | 6 import os |
7 import traceback | 7 import traceback |
8 | 8 |
9 from chroot_file_system import ChrootFileSystem | 9 from chroot_file_system import ChrootFileSystem |
10 from content_provider import ContentProvider | 10 from content_provider import ContentProvider |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 class ContentProviders(object): | 34 class ContentProviders(object): |
35 '''Implements the content_providers.json configuration; see | 35 '''Implements the content_providers.json configuration; see |
36 chrome/common/extensions/docs/templates/json/content_providers.json for its | 36 chrome/common/extensions/docs/templates/json/content_providers.json for its |
37 current state and a description of the format. | 37 current state and a description of the format. |
38 | 38 |
39 Returns ContentProvider instances based on how they're configured there. | 39 Returns ContentProvider instances based on how they're configured there. |
40 ''' | 40 ''' |
41 | 41 |
42 def __init__(self, | 42 def __init__(self, |
| 43 object_store_creator, |
43 compiled_fs_factory, | 44 compiled_fs_factory, |
44 host_file_system, | 45 host_file_system, |
45 github_file_system_provider, | 46 github_file_system_provider, |
46 gcs_file_system_provider): | 47 gcs_file_system_provider): |
| 48 self._object_store_creator = object_store_creator |
47 self._compiled_fs_factory = compiled_fs_factory | 49 self._compiled_fs_factory = compiled_fs_factory |
48 self._host_file_system = host_file_system | 50 self._host_file_system = host_file_system |
49 self._github_file_system_provider = github_file_system_provider | 51 self._github_file_system_provider = github_file_system_provider |
50 self._gcs_file_system_provider = gcs_file_system_provider | 52 self._gcs_file_system_provider = gcs_file_system_provider |
51 self._cache = None | 53 self._cache = None |
52 | 54 |
53 # If running the devserver and there is a LOCAL_DEBUG_DIR, we | 55 # If running the devserver and there is a LOCAL_DEBUG_DIR, we |
54 # will read the content_provider configuration from there instead | 56 # will read the content_provider configuration from there instead |
55 # of fetching it from SVN trunk or patch. | 57 # of fetching it from SVN trunk or patch. |
56 if environment.IsDevServer() and os.path.exists(LOCAL_DEBUG_DIR): | 58 if environment.IsDevServer() and os.path.exists(LOCAL_DEBUG_DIR): |
(...skipping 18 matching lines...) Expand all Loading... |
75 None of there is no such content provider. | 77 None of there is no such content provider. |
76 ''' | 78 ''' |
77 config = self._GetConfig().get(name) | 79 config = self._GetConfig().get(name) |
78 if config is None: | 80 if config is None: |
79 logging.error('No content provider found with name "%s"' % name) | 81 logging.error('No content provider found with name "%s"' % name) |
80 return None | 82 return None |
81 return self._CreateContentProvider(name, config) | 83 return self._CreateContentProvider(name, config) |
82 | 84 |
83 @memoize | 85 @memoize |
84 def GetByServeFrom(self, path): | 86 def GetByServeFrom(self, path): |
85 '''Gets a (content_provider, path_in_content_provider) tuple, where | 87 '''Gets a (content_provider, serve_from, path_in_content_provider) tuple, |
86 content_provider is the ContentProvider with the longest "serveFrom" | 88 where content_provider is the ContentProvider with the longest "serveFrom" |
87 property that is a subpath of |path|, and path_in_content_provider is the | 89 property that is a subpath of |path|, serve_from is that property, and |
88 remainder of |path|. | 90 path_in_content_provider is the remainder of |path|. |
89 | 91 |
90 For example, if content provider A serves from "foo" and content provider B | 92 For example, if content provider A serves from "foo" and content provider B |
91 serves from "foo/bar", GetByServeFrom("foo/bar/baz") will return (B, "baz"). | 93 serves from "foo/bar", GetByServeFrom("foo/bar/baz") will return (B, |
| 94 "foo/bar", "baz"). |
92 | 95 |
93 Returns (None, |path|) if no ContentProvider serves from |path|. | 96 Returns (None, '', |path|) if no ContentProvider serves from |path|. |
94 ''' | 97 ''' |
95 serve_from_to_config = dict( | 98 serve_from_to_config = dict( |
96 (config['serveFrom'], (name, config)) | 99 (config['serveFrom'], (name, config)) |
97 for name, config in self._GetConfig().iteritems()) | 100 for name, config in self._GetConfig().iteritems()) |
98 path_parts = path.split('/') | 101 path_parts = path.split('/') |
99 for i in xrange(len(path_parts), -1, -1): | 102 for i in xrange(len(path_parts), -1, -1): |
100 name_and_config = serve_from_to_config.get('/'.join(path_parts[:i])) | 103 name_and_config = serve_from_to_config.get('/'.join(path_parts[:i])) |
101 if name_and_config is not None: | 104 if name_and_config is not None: |
102 return (self._CreateContentProvider(name_and_config[0], | 105 return (self._CreateContentProvider(name_and_config[0], |
103 name_and_config[1]), | 106 name_and_config[1]), |
| 107 '/'.join(path_parts[:i]), |
104 '/'.join(path_parts[i:])) | 108 '/'.join(path_parts[i:])) |
105 return None, path | 109 return None, '', path |
106 | 110 |
107 def _GetConfig(self): | 111 def _GetConfig(self): |
108 return self._cache.GetFromFile(CONTENT_PROVIDERS).Get() | 112 return self._cache.GetFromFile(CONTENT_PROVIDERS).Get() |
109 | 113 |
110 def _CreateContentProvider(self, name, config): | 114 def _CreateContentProvider(self, name, config): |
| 115 default_extensions = config.get('defaultExtensions', ()) |
111 supports_templates = config.get('supportsTemplates', False) | 116 supports_templates = config.get('supportsTemplates', False) |
112 supports_zip = config.get('supportsZip', False) | 117 supports_zip = config.get('supportsZip', False) |
113 | 118 |
114 if 'chromium' in config: | 119 if 'chromium' in config: |
115 chromium_config = config['chromium'] | 120 chromium_config = config['chromium'] |
116 if 'dir' not in chromium_config: | 121 if 'dir' not in chromium_config: |
117 logging.error('%s: "chromium" must have a "dir" property' % name) | 122 logging.error('%s: "chromium" must have a "dir" property' % name) |
118 return None | 123 return None |
119 file_system = ChrootFileSystem(self._host_file_system, | 124 file_system = ChrootFileSystem(self._host_file_system, |
120 chromium_config['dir']) | 125 chromium_config['dir']) |
(...skipping 21 matching lines...) Expand all Loading... |
142 if 'dir' in github_config: | 147 if 'dir' in github_config: |
143 file_system = ChrootFileSystem(file_system, github_config['dir']) | 148 file_system = ChrootFileSystem(file_system, github_config['dir']) |
144 | 149 |
145 else: | 150 else: |
146 logging.error('%s: content provider type not supported' % name) | 151 logging.error('%s: content provider type not supported' % name) |
147 return None | 152 return None |
148 | 153 |
149 return ContentProvider(name, | 154 return ContentProvider(name, |
150 self._compiled_fs_factory, | 155 self._compiled_fs_factory, |
151 file_system, | 156 file_system, |
| 157 self._object_store_creator, |
| 158 default_extensions=default_extensions, |
152 supports_templates=supports_templates, | 159 supports_templates=supports_templates, |
153 supports_zip=supports_zip) | 160 supports_zip=supports_zip) |
154 | 161 |
155 def Cron(self): | 162 def Cron(self): |
156 def safe(name, action, callback): | 163 def safe(name, action, callback): |
157 '''Safely runs |callback| for a ContentProvider called |name| by | 164 '''Safely runs |callback| for a ContentProvider called |name| by |
158 swallowing exceptions and turning them into a None return value. It's | 165 swallowing exceptions and turning them into a None return value. It's |
159 important to run all ContentProvider Crons even if some of them fail. | 166 important to run all ContentProvider Crons even if some of them fail. |
160 ''' | 167 ''' |
161 try: | 168 try: |
162 return callback() | 169 return callback() |
163 except: | 170 except: |
164 if not _IGNORE_MISSING_CONTENT_PROVIDERS[0]: | 171 if not _IGNORE_MISSING_CONTENT_PROVIDERS[0]: |
165 logging.error('Error %s Cron for ContentProvider "%s":\n%s' % | 172 logging.error('Error %s Cron for ContentProvider "%s":\n%s' % |
166 (action, name, traceback.format_exc())) | 173 (action, name, traceback.format_exc())) |
167 return None | 174 return None |
168 | 175 |
169 futures = [(name, safe(name, | 176 futures = [(name, safe(name, |
170 'initializing', | 177 'initializing', |
171 self._CreateContentProvider(name, config).Cron)) | 178 self._CreateContentProvider(name, config).Cron)) |
172 for name, config in self._GetConfig().iteritems()] | 179 for name, config in self._GetConfig().iteritems()] |
173 return Future(delegate=Gettable( | 180 return Future(delegate=Gettable( |
174 lambda: [safe(name, 'resolving', f.Get) for name, f in futures if f])) | 181 lambda: [safe(name, 'resolving', f.Get) for name, f in futures if f])) |
OLD | NEW |