Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4398)

Unified Diff: chrome/common/extensions/docs/server2/api_list_data_source.py

Issue 23867003: Docserver: Consolidate features caching and access. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/docs/server2/api_list_data_source.py
diff --git a/chrome/common/extensions/docs/server2/api_list_data_source.py b/chrome/common/extensions/docs/server2/api_list_data_source.py
index 2e35ad631fb6a9b14e94c954b843e25d6fef53a5..4c8868cda6028f843792e209e61170dac082a761 100644
--- a/chrome/common/extensions/docs/server2/api_list_data_source.py
+++ b/chrome/common/extensions/docs/server2/api_list_data_source.py
@@ -4,6 +4,7 @@
import os
+from third_party.json_schema_compiler.json_parse import Parse
import third_party.json_schema_compiler.model as model
import docs_server_utils as utils
@@ -11,75 +12,128 @@ class APIListDataSource(object):
""" This class creates a list of chrome.* APIs and chrome.experimental.* APIs
for extensions and apps that are used in the api_index.html and
experimental.html pages.
- |api_path| is the path to the API schemas.
- |public_path| is the path to the public HTML templates.
- An API is considered listable if it's in both |api_path| and |public_path| -
- the API schemas may contain undocumentable APIs, and the public HTML templates
- will contain non-API articles.
+ |file_system| is the host file system.
+ |public_template_path| is the relative path to public API HTML templates.
+ |api_features_path| is the path to _api_features.json.
+ |manifest_features_path| is the path to _manifest_features.json.
+ |permission_features_path| is the path to _permission_features.json.
+
+ An API is considered listable if it is listed in _api_features.json,
+ it has a corresponding HTML file in the public template path, and one of
+ the following conditions is met:
+ - It has no "dependencies" or "extension_types" properties in _api_features
+ - It has an "extension_types" property in _api_features with either/both
+ "extension"/"platform_app" values present.
+ - It has a dependency in _{api,manifest,permission}_features with an
+ "extension_types" property where either/both "extension"/"platform_app"
+ values are present.
"""
class Factory(object):
- def __init__(self, compiled_fs_factory, file_system, api_path, public_path):
- self._compiled_fs = compiled_fs_factory.Create(self._ListAPIs,
- APIListDataSource)
+ def __init__(self,
+ file_system,
+ public_template_path,
+ api_features_path,
+ manifest_features_path,
+ permission_features_path):
self._file_system = file_system
- def Normalize(string):
+ def NormalizePath(string):
return string if string.endswith('/') else (string + '/')
- self._api_path = Normalize(api_path)
- self._public_path = Normalize(public_path)
+ self._public_template_path = NormalizePath(public_template_path)
+ self._api_features = Parse(file_system.ReadSingle(api_features_path))
+ self._manifest_features = Parse(
+ file_system.ReadSingle(manifest_features_path))
+ self._permission_features = Parse(
+ file_system.ReadSingle(permission_features_path))
not at google - send to devlin 2013/09/19 19:21:52 It's preferable to do heavy lifting outside constr
+ self._public_apis = {
+ 'apps': self._GetPublicAPIs('apps'),
+ 'extensions': self._GetPublicAPIs('extensions')
+ }
+ self._apis = self._GenerateAPIDict()
- def _GetAPIsInSubdirectory(self, api_names, doc_type):
+ def _GetPublicAPIs(self, platform):
public_templates = []
for root, _, files in self._file_system.Walk(
- self._public_path + doc_type):
+ self._public_template_path + platform):
public_templates.extend(
('%s/%s' % (root, name)).lstrip('/') for name in files)
template_names = set(os.path.splitext(name)[0]
for name in public_templates)
- experimental_apis = []
- chrome_apis = []
- private_apis = []
- for template_name in sorted(template_names):
- if model.UnixName(template_name) not in api_names:
- continue
- entry = {'name': template_name.replace('_', '.')}
- if template_name.startswith('experimental'):
- experimental_apis.append(entry)
- elif template_name.endswith('Private'):
- private_apis.append(entry)
- else:
- chrome_apis.append(entry)
- if len(chrome_apis):
- chrome_apis[-1]['last'] = True
- if len(experimental_apis):
- experimental_apis[-1]['last'] = True
- if len(private_apis):
- private_apis[-1]['last'] = True
- return {
- 'chrome': chrome_apis,
- 'experimental': experimental_apis,
- 'private': private_apis
+ return map(lambda name: name.replace('_', '.'), template_names)
+
+ def _GetExtensionTypesForDependency(self, dependency):
+ feature_sources = {
+ 'api': self._api_features,
+ 'manifest': self._manifest_features,
+ 'permission': self._permission_features
}
+ feature_type, feature_name = dependency.split(':')
not at google - send to devlin 2013/09/19 19:21:52 This is the sort of stuff that feature_utility c/s
+ feature = feature_sources[feature_type].get(feature_name, None)
+ if feature is None:
+ logging.error('Unable to resolve feature dependency %s' % dependency)
+ return []
+ if type(feature) is list:
not at google - send to devlin 2013/09/19 19:21:52 isinstance(feature, list): but again feature_util
+ extension_types = []
+ for branch in feature:
+ extension_types.extend(branch.get('extension_types', []))
+ else:
+ extension_types = feature.get('extension_types', [])
+ return extension_types
+
+ def _GetAPIPlatforms(self, api):
+ def MapExtensionTypesToAPIPlatforms(extension_types):
+ mapping = { 'extension': 'extensions', 'platform_app': 'apps' }
+ platforms = set()
+ for extension_type in extension_types:
+ if extension_type in mapping:
+ platforms.add(mapping[extension_type])
+ return platforms
+ extension_types = api.get('extension_types', None)
+ if extension_types is not None:
+ return MapExtensionTypesToAPIPlatforms(extension_types)
+ platforms = set(['apps', 'extensions'])
not at google - send to devlin 2013/09/19 19:21:52 when creating fixed-length lists use (...) not [..
Ken Rockot(use gerrit already) 2013/09/20 20:53:37 Done.
+ for dependency in api.get('dependencies', []):
not at google - send to devlin 2013/09/19 19:21:52 () not []
Ken Rockot(use gerrit already) 2013/09/20 20:53:37 Done.
+ platforms = platforms.intersection(MapExtensionTypesToAPIPlatforms(
+ self._GetExtensionTypesForDependency(dependency)))
+ return list(platforms)
+
+ def _GetAPICategory(self, api, platform):
+ name = api['name']
+ if name.startswith('experimental.'):
+ return 'experimental'
+ elif (name.endswith('Private') or
+ name not in self._public_apis[platform]):
+ return 'private'
+ else:
+ return 'chrome'
not at google - send to devlin 2013/09/19 19:21:52 no else's after return's.
Ken Rockot(use gerrit already) 2013/09/20 20:53:37 Done.
- def _ListAPIs(self, base_dir, apis):
- api_names = set(utils.SanitizeAPIName(name) for name in apis)
- return {
- 'apps': self._GetAPIsInSubdirectory(api_names, 'apps'),
- 'extensions': self._GetAPIsInSubdirectory(api_names, 'extensions')
+ def _GenerateAPIDict(self):
+ def MakeEmptyAPIDict():
+ return { 'chrome': [], 'experimental': [], 'private': [] }
+ api_dict = {
+ 'apps': MakeEmptyAPIDict(),
+ 'extensions': MakeEmptyAPIDict()
}
+ for (name, api) in self._api_features.items():
not at google - send to devlin 2013/09/19 19:21:52 name, api not (name, api) iteritems not items.
Ken Rockot(use gerrit already) 2013/09/20 20:53:37 Done.
+ api['name'] = name
+ for platform in self._GetAPIPlatforms(api):
+ api_dict[platform][self._GetAPICategory(api, platform)].append(api)
+ for platform in api_dict.keys():
not at google - send to devlin 2013/09/19 19:21:52 iterkeys
Ken Rockot(use gerrit already) 2013/09/20 20:53:37 Done.
+ for category in api_dict[platform]:
+ api_dict[platform][category][-1]['last'] = True
+ return api_dict
def Create(self):
- return APIListDataSource(self._compiled_fs, self._api_path)
+ return APIListDataSource(self._apis)
- def __init__(self, compiled_fs, api_path):
- self._compiled_fs = compiled_fs
- self._api_path = api_path
+ def __init__(self, apis):
+ self._apis = apis
def GetAllNames(self):
- names = []
+ apis = []
for platform in ['apps', 'extensions']:
for category in ['chrome', 'experimental', 'private']:
- names.extend(self.get(platform).get(category))
- return [api_name['name'] for api_name in names]
+ apis.extend(self._apis[platform][category])
+ return [api['name'] for api in apis]
def get(self, key):
- return self._compiled_fs.GetFromFileListing(self._api_path)[key]
+ return self._apis.get(key)

Powered by Google App Engine
This is Rietveld 408576698