Chromium Code Reviews| Index: chrome/common/extensions/docs/server2/samples_data_source.py |
| diff --git a/chrome/common/extensions/docs/server2/samples_data_source.py b/chrome/common/extensions/docs/server2/samples_data_source.py |
| index a692e979ca1c7bc5d4b80911603e950d6d5bfb2a..2d145e89eb8b5c881bdad6cd8da1470411d9948e 100644 |
| --- a/chrome/common/extensions/docs/server2/samples_data_source.py |
| +++ b/chrome/common/extensions/docs/server2/samples_data_source.py |
| @@ -2,252 +2,75 @@ |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| -import json |
| import logging |
| -import posixpath |
| -import re |
| import traceback |
| +from data_source import DataSource |
| from extensions_paths import EXAMPLES |
| -import third_party.json_schema_compiler.json_comment_eater as json_comment_eater |
| -import url_constants |
| +from future import Future |
| -_DEFAULT_ICON_PATH = 'images/sample-default-icon.png' |
| +def _GetSampleId(sample_name): |
| + return sample_name.lower().replace(' ', '-') |
| -class SamplesDataSource(object): |
| - '''Constructs a list of samples and their respective files and api calls. |
| - ''' |
| - class Factory(object): |
| - '''A factory to create SamplesDataSource instances bound to individual |
| - Requests. |
| - ''' |
| - def __init__(self, |
| - host_file_system, |
| - app_samples_file_system, |
| - compiled_fs_factory, |
| - platform_bundle, |
| - base_path): |
| - self._host_file_system = host_file_system |
| - self._app_samples_file_system = app_samples_file_system |
| - self._platform_bundle = platform_bundle |
| - self._base_path = base_path |
| - self._extensions_cache = compiled_fs_factory.Create( |
| - host_file_system, |
| - self._MakeSamplesList, |
| - SamplesDataSource, |
| - category='extensions') |
| - self._extensions_text_cache = compiled_fs_factory.ForUnicode( |
| - host_file_system) |
| - self._apps_cache = compiled_fs_factory.Create( |
| - app_samples_file_system, |
| - lambda *args: self._MakeSamplesList(*args, is_apps=True), |
| - SamplesDataSource, |
| - category='apps') |
| - self._apps_text_cache = compiled_fs_factory.ForUnicode( |
| - app_samples_file_system) |
| +def GetAcceptedLanguages(request): |
| + accept_language = request.headers.get('Accept-Language', None) |
| + if accept_language is None: |
| + return [] |
| + return [lang_with_q.split(';')[0].strip() |
| + for lang_with_q in accept_language.split(',')] |
| - def Create(self, request): |
| - '''Returns a new SamplesDataSource bound to |request|. |
| - ''' |
| - return SamplesDataSource(self._extensions_cache, |
| - self._apps_cache, |
| - self._base_path, |
| - request) |
| - def _GetAPIItems(self, js_file): |
| - chrome_pattern = r'chrome[\w.]+' |
| - # Add API calls that appear normally, like "chrome.runtime.connect". |
| - calls = set(re.findall(chrome_pattern, js_file)) |
| - # Add API calls that have been assigned into variables, like |
| - # "var storageArea = chrome.storage.sync; storageArea.get", which should |
| - # be expanded like "chrome.storage.sync.get". |
| - for match in re.finditer(r'var\s+(\w+)\s*=\s*(%s);' % chrome_pattern, |
| - js_file): |
| - var_name, api_prefix = match.groups() |
| - for var_match in re.finditer(r'\b%s\.([\w.]+)\b' % re.escape(var_name), |
| - js_file): |
| - api_suffix, = var_match.groups() |
| - calls.add('%s.%s' % (api_prefix, api_suffix)) |
| - return calls |
| - |
| - def _GetDataFromManifest(self, path, text_cache, file_system): |
| - manifest = text_cache.GetFromFile(path + '/manifest.json').Get() |
| +def CreateSamplesView(samples_list, request): |
| + return_list = [] |
| + for dict_ in samples_list: |
| + name = dict_['name'] |
| + description = dict_['description'] |
| + if description is None: |
| + description = '' |
| + if name.startswith('__MSG_') or description.startswith('__MSG_'): |
| try: |
| - manifest_json = json.loads(json_comment_eater.Nom(manifest)) |
| - except ValueError as e: |
| - logging.error('Error parsing manifest.json for %s: %s' % (path, e)) |
| - return None |
| - l10n_data = { |
| - 'name': manifest_json.get('name', ''), |
| - 'description': manifest_json.get('description', None), |
| - 'icon': manifest_json.get('icons', {}).get('128', None), |
| - 'default_locale': manifest_json.get('default_locale', None), |
| - 'locales': {} |
| - } |
| - if not l10n_data['default_locale']: |
| - return l10n_data |
| - locales_path = path + '/_locales/' |
| - locales_dir = file_system.ReadSingle(locales_path).Get() |
| - if locales_dir: |
| - def load_locale_json(path): |
| - return (path, json.loads(text_cache.GetFromFile(path).Get())) |
| - |
| - try: |
| - locales_json = [load_locale_json(locales_path + f + 'messages.json') |
| - for f in locales_dir] |
| - except ValueError as e: |
| - logging.error('Error parsing locales files for %s: %s' % (path, e)) |
| - else: |
| - for path, json_ in locales_json: |
| - l10n_data['locales'][path[len(locales_path):].split('/')[0]] = json_ |
| - return l10n_data |
| - |
| - def _MakeSamplesList(self, base_path, files, is_apps=False): |
| - file_system = (self._app_samples_file_system if is_apps else |
| - self._host_file_system) |
| - text_cache = (self._apps_text_cache if is_apps else |
| - self._extensions_text_cache) |
| - samples_list = [] |
| - for filename in sorted(files): |
| - if filename.rsplit('/')[-1] != 'manifest.json': |
| - continue |
| - |
| - # This is a little hacky, but it makes a sample page. |
| - sample_path = filename.rsplit('/', 1)[-2] |
| - sample_files = [path for path in files |
| - if path.startswith(sample_path + '/')] |
| - js_files = [path for path in sample_files if path.endswith('.js')] |
| - js_contents = [text_cache.GetFromFile( |
| - posixpath.join(base_path, js_file)).Get() |
| - for js_file in js_files] |
| - api_items = set() |
| - for js in js_contents: |
| - api_items.update(self._GetAPIItems(js)) |
| - |
| - api_calls = [] |
| - for item in sorted(api_items): |
| - if len(item.split('.')) < 3: |
| - continue |
| - if item.endswith('.removeListener') or item.endswith('.hasListener'): |
| - continue |
| - if item.endswith('.addListener'): |
| - item = item[:-len('.addListener')] |
| - if item.startswith('chrome.'): |
| - item = item[len('chrome.'):] |
| - ref_data = self._platform_bundle.GetReferenceResolver( |
| - 'apps' if is_apps else 'extensions').GetLink(item) |
| - # TODO(kalman): What about references like chrome.storage.sync.get? |
| - # That should link to either chrome.storage.sync or |
| - # chrome.storage.StorageArea.get (or probably both). |
| - # TODO(kalman): Filter out API-only references? This can happen when |
| - # the API namespace is assigned to a variable, but it's very hard to |
| - # to disambiguate. |
| - if ref_data is None: |
| - continue |
| - api_calls.append({ |
| - 'name': ref_data['text'], |
| - 'link': ref_data['href'] |
| - }) |
| - |
| - if is_apps: |
| - url = url_constants.GITHUB_BASE + '/' + sample_path |
| - icon_base = url_constants.RAW_GITHUB_BASE + '/' + sample_path |
| - download_url = url |
| - else: |
| - extension_sample_path = posixpath.join('examples', sample_path) |
| - url = extension_sample_path |
| - icon_base = extension_sample_path |
| - download_url = extension_sample_path + '.zip' |
| - |
| - manifest_data = self._GetDataFromManifest( |
| - posixpath.join(base_path, sample_path), |
| - text_cache, |
| - file_system) |
| - if manifest_data['icon'] is None: |
| - icon_path = posixpath.join( |
| - self._base_path, 'static', _DEFAULT_ICON_PATH) |
| - else: |
| - icon_path = '%s/%s' % (icon_base, manifest_data['icon']) |
| - manifest_data.update({ |
| - 'icon': icon_path, |
| - 'download_url': download_url, |
| - 'url': url, |
| - 'files': [f.replace(sample_path + '/', '') for f in sample_files], |
| - 'api_calls': api_calls |
| - }) |
| - samples_list.append(manifest_data) |
| + # Copy the sample dict so we don't change the dict in the cache. |
| + sample_data = dict_.copy() |
| + name_key = name[len('__MSG_'):-len('__')] |
| + description_key = description[len('__MSG_'):-len('__')] |
| + locale = sample_data['default_locale'] |
| + for lang in GetAcceptedLanguages(request): |
| + if lang in sample_data['locales']: |
| + locale = lang |
| + break |
| + locale_data = sample_data['locales'][locale] |
| + sample_data['name'] = locale_data[name_key]['message'] |
| + sample_data['description'] = locale_data[description_key]['message'] |
| + sample_data['id'] = _GetSampleId(sample_data['name']) |
| + except Exception: |
| + logging.error(traceback.format_exc()) |
| + # Revert the sample to the original dict. |
| + sample_data = dict_ |
| + return_list.append(sample_data) |
| + else: |
| + dict_['id'] = _GetSampleId(name) |
| + return_list.append(dict_) |
| + return return_list |
| - return samples_list |
| - def __init__(self, |
| - extensions_cache, |
| - apps_cache, |
| - base_path, |
| - request): |
| - self._extensions_cache = extensions_cache |
| - self._apps_cache = apps_cache |
| - self._base_path = base_path |
| +class SamplesDataSource(DataSource): |
| + '''Constructs a list of samples and their respective files and api calls. |
| + ''' |
| + def __init__(self, server_instance, request): |
| + self._platform_bundle = server_instance.platform_bundle |
| self._request = request |
| - def _GetSampleId(self, sample_name): |
| - return sample_name.lower().replace(' ', '-') |
| + def _CreateSamplesDict(self, platform): |
| + cache = self._platform_bundle.GetSamplesModel(platform).GetCache() |
| + samples_list = cache.GetFromFileListing( |
| + '' if platform == 'apps' else EXAMPLES).Get() |
| + return CreateSamplesView(samples_list, self._request) |
| - def _GetAcceptedLanguages(self): |
| - accept_language = self._request.headers.get('Accept-Language', None) |
| - if accept_language is None: |
| - return [] |
| - return [lang_with_q.split(';')[0].strip() |
| - for lang_with_q in accept_language.split(',')] |
| - |
| - def FilterSamples(self, key, api_name): |
| - '''Fetches and filters the list of samples specified by |key|, returning |
| - only the samples that use the API |api_name|. |key| is either 'apps' or |
| - 'extensions'. |
| - ''' |
| - return [sample for sample in self.get(key) if any( |
| - call['name'].startswith(api_name + '.') |
| - for call in sample['api_calls'])] |
| - |
| - def _CreateSamplesDict(self, key): |
| - if key == 'apps': |
| - samples_list = self._apps_cache.GetFromFileListing('').Get() |
| - else: |
| - samples_list = self._extensions_cache.GetFromFileListing(EXAMPLES).Get() |
| - return_list = [] |
| - for dict_ in samples_list: |
| - name = dict_['name'] |
| - description = dict_['description'] |
| - if description is None: |
| - description = '' |
| - if name.startswith('__MSG_') or description.startswith('__MSG_'): |
| - try: |
| - # Copy the sample dict so we don't change the dict in the cache. |
| - sample_data = dict_.copy() |
| - name_key = name[len('__MSG_'):-len('__')] |
| - description_key = description[len('__MSG_'):-len('__')] |
| - locale = sample_data['default_locale'] |
| - for lang in self._GetAcceptedLanguages(): |
| - if lang in sample_data['locales']: |
| - locale = lang |
| - break |
| - locale_data = sample_data['locales'][locale] |
| - sample_data['name'] = locale_data[name_key]['message'] |
| - sample_data['description'] = locale_data[description_key]['message'] |
| - sample_data['id'] = self._GetSampleId(sample_data['name']) |
| - except Exception as e: |
| - logging.error(traceback.format_exc()) |
| - # Revert the sample to the original dict. |
| - sample_data = dict_ |
| - return_list.append(sample_data) |
| - else: |
| - dict_['id'] = self._GetSampleId(name) |
| - return_list.append(dict_) |
| - return return_list |
| + def get(self, platform): |
| + return self._CreateSamplesDict(platform) |
| - def get(self, key): |
| - return { |
| - 'apps': lambda: self._CreateSamplesDict('apps'), |
| - 'extensions': lambda: self._CreateSamplesDict('extensions') |
| - }.get(key, lambda: {})() |
| + def Cron(self): |
| + # TODO(ahernandez): Implement. |
|
ahernandez
2014/08/04 20:40:03
How should I go about implementing this?
Ken Rockot(use gerrit already)
2014/08/05 01:57:21
I think calling CreateSamplesView for each platfor
|
| + return Future(value=()) |