| 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 |