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

Side by Side 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 unified diff | Download patch
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 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 os 5 import os
6 6
7 from third_party.json_schema_compiler.json_parse import Parse
7 import third_party.json_schema_compiler.model as model 8 import third_party.json_schema_compiler.model as model
8 import docs_server_utils as utils 9 import docs_server_utils as utils
9 10
10 class APIListDataSource(object): 11 class APIListDataSource(object):
11 """ This class creates a list of chrome.* APIs and chrome.experimental.* APIs 12 """ This class creates a list of chrome.* APIs and chrome.experimental.* APIs
12 for extensions and apps that are used in the api_index.html and 13 for extensions and apps that are used in the api_index.html and
13 experimental.html pages. 14 experimental.html pages.
14 |api_path| is the path to the API schemas. 15 |file_system| is the host file system.
15 |public_path| is the path to the public HTML templates. 16 |public_template_path| is the relative path to public API HTML templates.
16 An API is considered listable if it's in both |api_path| and |public_path| - 17 |api_features_path| is the path to _api_features.json.
17 the API schemas may contain undocumentable APIs, and the public HTML templates 18 |manifest_features_path| is the path to _manifest_features.json.
18 will contain non-API articles. 19 |permission_features_path| is the path to _permission_features.json.
20
21 An API is considered listable if it is listed in _api_features.json,
22 it has a corresponding HTML file in the public template path, and one of
23 the following conditions is met:
24 - It has no "dependencies" or "extension_types" properties in _api_features
25 - It has an "extension_types" property in _api_features with either/both
26 "extension"/"platform_app" values present.
27 - It has a dependency in _{api,manifest,permission}_features with an
28 "extension_types" property where either/both "extension"/"platform_app"
29 values are present.
19 """ 30 """
20 class Factory(object): 31 class Factory(object):
21 def __init__(self, compiled_fs_factory, file_system, api_path, public_path): 32 def __init__(self,
22 self._compiled_fs = compiled_fs_factory.Create(self._ListAPIs, 33 file_system,
23 APIListDataSource) 34 public_template_path,
35 api_features_path,
36 manifest_features_path,
37 permission_features_path):
24 self._file_system = file_system 38 self._file_system = file_system
25 def Normalize(string): 39 def NormalizePath(string):
26 return string if string.endswith('/') else (string + '/') 40 return string if string.endswith('/') else (string + '/')
27 self._api_path = Normalize(api_path) 41 self._public_template_path = NormalizePath(public_template_path)
28 self._public_path = Normalize(public_path) 42 self._api_features = Parse(file_system.ReadSingle(api_features_path))
43 self._manifest_features = Parse(
44 file_system.ReadSingle(manifest_features_path))
45 self._permission_features = Parse(
46 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
47 self._public_apis = {
48 'apps': self._GetPublicAPIs('apps'),
49 'extensions': self._GetPublicAPIs('extensions')
50 }
51 self._apis = self._GenerateAPIDict()
29 52
30 def _GetAPIsInSubdirectory(self, api_names, doc_type): 53 def _GetPublicAPIs(self, platform):
31 public_templates = [] 54 public_templates = []
32 for root, _, files in self._file_system.Walk( 55 for root, _, files in self._file_system.Walk(
33 self._public_path + doc_type): 56 self._public_template_path + platform):
34 public_templates.extend( 57 public_templates.extend(
35 ('%s/%s' % (root, name)).lstrip('/') for name in files) 58 ('%s/%s' % (root, name)).lstrip('/') for name in files)
36 template_names = set(os.path.splitext(name)[0] 59 template_names = set(os.path.splitext(name)[0]
37 for name in public_templates) 60 for name in public_templates)
38 experimental_apis = [] 61 return map(lambda name: name.replace('_', '.'), template_names)
39 chrome_apis = [] 62
40 private_apis = [] 63 def _GetExtensionTypesForDependency(self, dependency):
41 for template_name in sorted(template_names): 64 feature_sources = {
42 if model.UnixName(template_name) not in api_names: 65 'api': self._api_features,
43 continue 66 'manifest': self._manifest_features,
44 entry = {'name': template_name.replace('_', '.')} 67 'permission': self._permission_features
45 if template_name.startswith('experimental'):
46 experimental_apis.append(entry)
47 elif template_name.endswith('Private'):
48 private_apis.append(entry)
49 else:
50 chrome_apis.append(entry)
51 if len(chrome_apis):
52 chrome_apis[-1]['last'] = True
53 if len(experimental_apis):
54 experimental_apis[-1]['last'] = True
55 if len(private_apis):
56 private_apis[-1]['last'] = True
57 return {
58 'chrome': chrome_apis,
59 'experimental': experimental_apis,
60 'private': private_apis
61 } 68 }
69 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
70 feature = feature_sources[feature_type].get(feature_name, None)
71 if feature is None:
72 logging.error('Unable to resolve feature dependency %s' % dependency)
73 return []
74 if type(feature) is list:
not at google - send to devlin 2013/09/19 19:21:52 isinstance(feature, list): but again feature_util
75 extension_types = []
76 for branch in feature:
77 extension_types.extend(branch.get('extension_types', []))
78 else:
79 extension_types = feature.get('extension_types', [])
80 return extension_types
62 81
63 def _ListAPIs(self, base_dir, apis): 82 def _GetAPIPlatforms(self, api):
64 api_names = set(utils.SanitizeAPIName(name) for name in apis) 83 def MapExtensionTypesToAPIPlatforms(extension_types):
65 return { 84 mapping = { 'extension': 'extensions', 'platform_app': 'apps' }
66 'apps': self._GetAPIsInSubdirectory(api_names, 'apps'), 85 platforms = set()
67 'extensions': self._GetAPIsInSubdirectory(api_names, 'extensions') 86 for extension_type in extension_types:
87 if extension_type in mapping:
88 platforms.add(mapping[extension_type])
89 return platforms
90 extension_types = api.get('extension_types', None)
91 if extension_types is not None:
92 return MapExtensionTypesToAPIPlatforms(extension_types)
93 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.
94 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.
95 platforms = platforms.intersection(MapExtensionTypesToAPIPlatforms(
96 self._GetExtensionTypesForDependency(dependency)))
97 return list(platforms)
98
99 def _GetAPICategory(self, api, platform):
100 name = api['name']
101 if name.startswith('experimental.'):
102 return 'experimental'
103 elif (name.endswith('Private') or
104 name not in self._public_apis[platform]):
105 return 'private'
106 else:
107 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.
108
109 def _GenerateAPIDict(self):
110 def MakeEmptyAPIDict():
111 return { 'chrome': [], 'experimental': [], 'private': [] }
112 api_dict = {
113 'apps': MakeEmptyAPIDict(),
114 'extensions': MakeEmptyAPIDict()
68 } 115 }
116 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.
117 api['name'] = name
118 for platform in self._GetAPIPlatforms(api):
119 api_dict[platform][self._GetAPICategory(api, platform)].append(api)
120 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.
121 for category in api_dict[platform]:
122 api_dict[platform][category][-1]['last'] = True
123 return api_dict
69 124
70 def Create(self): 125 def Create(self):
71 return APIListDataSource(self._compiled_fs, self._api_path) 126 return APIListDataSource(self._apis)
72 127
73 def __init__(self, compiled_fs, api_path): 128 def __init__(self, apis):
74 self._compiled_fs = compiled_fs 129 self._apis = apis
75 self._api_path = api_path
76 130
77 def GetAllNames(self): 131 def GetAllNames(self):
78 names = [] 132 apis = []
79 for platform in ['apps', 'extensions']: 133 for platform in ['apps', 'extensions']:
80 for category in ['chrome', 'experimental', 'private']: 134 for category in ['chrome', 'experimental', 'private']:
81 names.extend(self.get(platform).get(category)) 135 apis.extend(self._apis[platform][category])
82 return [api_name['name'] for api_name in names] 136 return [api['name'] for api in apis]
83 137
84 def get(self, key): 138 def get(self, key):
85 return self._compiled_fs.GetFromFileListing(self._api_path)[key] 139 return self._apis.get(key)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698