| 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 traceback | 7 import traceback |
| 7 | 8 |
| 8 from chroot_file_system import ChrootFileSystem | 9 from chroot_file_system import ChrootFileSystem |
| 9 from content_provider import ContentProvider | 10 from content_provider import ContentProvider |
| 10 from extensions_paths import CONTENT_PROVIDERS | 11 import environment |
| 12 from extensions_paths import CONTENT_PROVIDERS, LOCAL_DEBUG_DIR |
| 11 from future import Gettable, Future | 13 from future import Gettable, Future |
| 14 from local_file_system import LocalFileSystem |
| 12 from third_party.json_schema_compiler.memoize import memoize | 15 from third_party.json_schema_compiler.memoize import memoize |
| 13 | 16 |
| 14 | 17 |
| 15 _IGNORE_MISSING_CONTENT_PROVIDERS = [False] | 18 _IGNORE_MISSING_CONTENT_PROVIDERS = [False] |
| 16 | 19 |
| 17 | 20 |
| 18 def IgnoreMissingContentProviders(fn): | 21 def IgnoreMissingContentProviders(fn): |
| 19 '''Decorates |fn| to ignore missing content providers during its run. | 22 '''Decorates |fn| to ignore missing content providers during its run. |
| 20 ''' | 23 ''' |
| 21 def run(*args, **optargs): | 24 def run(*args, **optargs): |
| (...skipping 10 matching lines...) Expand all Loading... |
| 32 '''Implements the content_providers.json configuration; see | 35 '''Implements the content_providers.json configuration; see |
| 33 chrome/common/extensions/docs/templates/json/content_providers.json for its | 36 chrome/common/extensions/docs/templates/json/content_providers.json for its |
| 34 current state and a description of the format. | 37 current state and a description of the format. |
| 35 | 38 |
| 36 Returns ContentProvider instances based on how they're configured there. | 39 Returns ContentProvider instances based on how they're configured there. |
| 37 ''' | 40 ''' |
| 38 | 41 |
| 39 def __init__(self, | 42 def __init__(self, |
| 40 compiled_fs_factory, | 43 compiled_fs_factory, |
| 41 host_file_system, | 44 host_file_system, |
| 42 github_file_system_provider): | 45 github_file_system_provider, |
| 46 gcs_file_system_provider): |
| 43 self._compiled_fs_factory = compiled_fs_factory | 47 self._compiled_fs_factory = compiled_fs_factory |
| 44 self._host_file_system = host_file_system | 48 self._host_file_system = host_file_system |
| 45 self._github_file_system_provider = github_file_system_provider | 49 self._github_file_system_provider = github_file_system_provider |
| 46 self._cache = compiled_fs_factory.ForJson(host_file_system) | 50 self._gcs_file_system_provider = gcs_file_system_provider |
| 51 self._cache = None |
| 52 |
| 53 # If running the devserver and there is a LOCAL_DEBUG_DIR, we |
| 54 # will read the content_provider configuration from there instead |
| 55 # of fetching it from SVN trunk or patch. |
| 56 if environment.IsDevServer() and os.path.exists(LOCAL_DEBUG_DIR): |
| 57 local_fs = LocalFileSystem(LOCAL_DEBUG_DIR) |
| 58 conf_stat = None |
| 59 try: |
| 60 conf_stat = local_fs.Stat(CONTENT_PROVIDERS) |
| 61 except: |
| 62 pass |
| 63 |
| 64 if conf_stat: |
| 65 logging.warn(("Using local debug folder (%s) for " |
| 66 "content_provider.json configuration") % LOCAL_DEBUG_DIR) |
| 67 self._cache = compiled_fs_factory.ForJson(local_fs) |
| 68 |
| 69 if not self._cache: |
| 70 self._cache = compiled_fs_factory.ForJson(host_file_system) |
| 47 | 71 |
| 48 @memoize | 72 @memoize |
| 49 def GetByName(self, name): | 73 def GetByName(self, name): |
| 50 '''Gets the ContentProvider keyed by |name| in content_providers.json, or | 74 '''Gets the ContentProvider keyed by |name| in content_providers.json, or |
| 51 None of there is no such content provider. | 75 None of there is no such content provider. |
| 52 ''' | 76 ''' |
| 53 config = self._GetConfig().get(name) | 77 config = self._GetConfig().get(name) |
| 54 if config is None: | 78 if config is None: |
| 55 logging.error('No content provider found with name "%s"' % name) | 79 logging.error('No content provider found with name "%s"' % name) |
| 56 return None | 80 return None |
| (...skipping 30 matching lines...) Expand all Loading... |
| 87 supports_templates = config.get('supportsTemplates', False) | 111 supports_templates = config.get('supportsTemplates', False) |
| 88 supports_zip = config.get('supportsZip', False) | 112 supports_zip = config.get('supportsZip', False) |
| 89 | 113 |
| 90 if 'chromium' in config: | 114 if 'chromium' in config: |
| 91 chromium_config = config['chromium'] | 115 chromium_config = config['chromium'] |
| 92 if 'dir' not in chromium_config: | 116 if 'dir' not in chromium_config: |
| 93 logging.error('%s: "chromium" must have a "dir" property' % name) | 117 logging.error('%s: "chromium" must have a "dir" property' % name) |
| 94 return None | 118 return None |
| 95 file_system = ChrootFileSystem(self._host_file_system, | 119 file_system = ChrootFileSystem(self._host_file_system, |
| 96 chromium_config['dir']) | 120 chromium_config['dir']) |
| 121 elif 'gcs' in config: |
| 122 gcs_config = config['gcs'] |
| 123 if 'bucket' not in gcs_config: |
| 124 logging.error('%s: "gcs" must have a "bucket" property' % name) |
| 125 return None |
| 126 bucket = gcs_config['bucket'] |
| 127 if not bucket.startswith('gs://'): |
| 128 logging.error('%s: bucket %s should start with gs://' % (name, bucket)) |
| 129 return None |
| 130 bucket = bucket[len('gs://'):] |
| 131 file_system = self._gcs_file_system_provider.Create(bucket) |
| 132 if 'dir' in gcs_config: |
| 133 file_system = ChrootFileSystem(file_system, gcs_config['dir']) |
| 134 |
| 97 elif 'github' in config: | 135 elif 'github' in config: |
| 98 github_config = config['github'] | 136 github_config = config['github'] |
| 99 if 'owner' not in github_config or 'repo' not in github_config: | 137 if 'owner' not in github_config or 'repo' not in github_config: |
| 100 logging.error('%s: "github" must provide an "owner" and "repo"' % name) | 138 logging.error('%s: "github" must provide an "owner" and "repo"' % name) |
| 101 return None | 139 return None |
| 102 file_system = self._github_file_system_provider.Create( | 140 file_system = self._github_file_system_provider.Create( |
| 103 github_config['owner'], github_config['repo']) | 141 github_config['owner'], github_config['repo']) |
| 104 if 'dir' in github_config: | 142 if 'dir' in github_config: |
| 105 file_system = ChrootFileSystem(file_system, github_config['dir']) | 143 file_system = ChrootFileSystem(file_system, github_config['dir']) |
| 144 |
| 106 else: | 145 else: |
| 107 logging.error( | 146 logging.error('%s: content provider type not supported' % name) |
| 108 '%s: content provider type "%s" not supported' % (name, type_)) | |
| 109 return None | 147 return None |
| 110 | 148 |
| 111 return ContentProvider(name, | 149 return ContentProvider(name, |
| 112 self._compiled_fs_factory, | 150 self._compiled_fs_factory, |
| 113 file_system, | 151 file_system, |
| 114 supports_templates=supports_templates, | 152 supports_templates=supports_templates, |
| 115 supports_zip=supports_zip) | 153 supports_zip=supports_zip) |
| 116 | 154 |
| 117 def Cron(self): | 155 def Cron(self): |
| 118 def safe(name, action, callback): | 156 def safe(name, action, callback): |
| 119 '''Safely runs |callback| for a ContentProvider called |name| by | 157 '''Safely runs |callback| for a ContentProvider called |name| by |
| 120 swallowing exceptions and turning them into a None return value. It's | 158 swallowing exceptions and turning them into a None return value. It's |
| 121 important to run all ContentProvider Crons even if some of them fail. | 159 important to run all ContentProvider Crons even if some of them fail. |
| 122 ''' | 160 ''' |
| 123 try: | 161 try: |
| 124 return callback() | 162 return callback() |
| 125 except: | 163 except: |
| 126 if not _IGNORE_MISSING_CONTENT_PROVIDERS[0]: | 164 if not _IGNORE_MISSING_CONTENT_PROVIDERS[0]: |
| 127 logging.error('Error %s Cron for ContentProvider "%s":\n%s' % | 165 logging.error('Error %s Cron for ContentProvider "%s":\n%s' % |
| 128 (action, name, traceback.format_exc())) | 166 (action, name, traceback.format_exc())) |
| 129 return None | 167 return None |
| 130 | 168 |
| 131 futures = [(name, safe(name, | 169 futures = [(name, safe(name, |
| 132 'initializing', | 170 'initializing', |
| 133 self._CreateContentProvider(name, config).Cron)) | 171 self._CreateContentProvider(name, config).Cron)) |
| 134 for name, config in self._GetConfig().iteritems()] | 172 for name, config in self._GetConfig().iteritems()] |
| 135 return Future(delegate=Gettable( | 173 return Future(delegate=Gettable( |
| 136 lambda: [safe(name, 'resolving', f.Get) for name, f in futures if f])) | 174 lambda: [safe(name, 'resolving', f.Get) for name, f in futures if f])) |
| OLD | NEW |