OLD | NEW |
---|---|
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 from operator import itemgetter | |
5 import os | 6 import os |
6 | 7 |
8 import features_utility as features | |
9 from third_party.json_schema_compiler.json_parse import Parse | |
7 import third_party.json_schema_compiler.model as model | 10 import third_party.json_schema_compiler.model as model |
8 import docs_server_utils as utils | 11 import docs_server_utils as utils |
9 | 12 |
13 def _GetAPICategory(api, public_apis): | |
14 name = api['name'] | |
15 if (name.endswith('Private') or | |
16 name not in public_apis): | |
17 return 'private' | |
18 if name.startswith('experimental.'): | |
19 return 'experimental' | |
20 return 'chrome' | |
21 | |
10 class APIListDataSource(object): | 22 class APIListDataSource(object): |
11 """ This class creates a list of chrome.* APIs and chrome.experimental.* APIs | 23 """ 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 | 24 for extensions and apps that are used in the api_index.html and |
13 experimental.html pages. | 25 experimental.html pages. |
14 |api_path| is the path to the API schemas. | 26 |
15 |public_path| is the path to the public HTML templates. | 27 An API is considered listable if it is listed in _api_features.json, |
16 An API is considered listable if it's in both |api_path| and |public_path| - | 28 it has a corresponding HTML file in the public template path, and one of |
17 the API schemas may contain undocumentable APIs, and the public HTML templates | 29 the following conditions is met: |
18 will contain non-API articles. | 30 - It has no "dependencies" or "extension_types" properties in _api_features |
31 - It has an "extension_types" property in _api_features with either/both | |
32 "extension"/"platform_app" values present. | |
33 - It has a dependency in _{api,manifest,permission}_features with an | |
34 "extension_types" property where either/both "extension"/"platform_app" | |
35 values are present. | |
19 """ | 36 """ |
20 class Factory(object): | 37 class Factory(object): |
21 def __init__(self, compiled_fs_factory, file_system, api_path, public_path): | 38 def __init__(self, |
22 self._compiled_fs = compiled_fs_factory.Create(self._ListAPIs, | 39 compiled_fs_factory, |
23 APIListDataSource) | 40 file_system, |
41 public_template_path, | |
42 features_bundle): | |
24 self._file_system = file_system | 43 self._file_system = file_system |
25 def Normalize(string): | 44 def NormalizePath(string): |
26 return string if string.endswith('/') else (string + '/') | 45 return string if string.endswith('/') else (string + '/') |
27 self._api_path = Normalize(api_path) | 46 self._public_template_path = NormalizePath(public_template_path) |
28 self._public_path = Normalize(public_path) | 47 self._cache = compiled_fs_factory.Create(self._CollectPublicAPIs, |
48 APIListDataSource) | |
49 self._features_bundle = features_bundle | |
29 | 50 |
30 def _GetAPIsInSubdirectory(self, api_names, doc_type): | 51 def _CollectPublicAPIs(self, base_dir, files): |
31 public_templates = [] | 52 def GetAPIsForPlatform(names, platform): |
32 for root, _, files in self._file_system.Walk( | 53 public_templates = [] |
33 self._public_path + doc_type): | 54 for root, _, files in self._file_system.Walk( |
34 public_templates.extend( | 55 self._public_template_path + platform): |
35 ('%s/%s' % (root, name)).lstrip('/') for name in files) | 56 public_templates.extend( |
36 template_names = set(os.path.splitext(name)[0] | 57 ('%s/%s' % (root, name)).lstrip('/') for name in files) |
37 for name in public_templates) | 58 template_names = set(os.path.splitext(name)[0] |
38 experimental_apis = [] | 59 for name in public_templates) |
39 chrome_apis = [] | 60 return sorted(map(lambda name: name.replace('_', '.'), template_names)) |
not at google - send to devlin
2013/10/01 16:34:34
see comments below (working my way from bottom to
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
Done.
| |
40 private_apis = [] | 61 api_names = set(utils.SanitizeAPIName(name) for name in files) |
41 for template_name in sorted(template_names): | |
42 if model.UnixName(template_name) not in api_names: | |
43 continue | |
44 entry = {'name': template_name.replace('_', '.')} | |
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 { | 62 return { |
58 'chrome': chrome_apis, | 63 'apps': GetAPIsForPlatform(api_names, 'apps'), |
59 'experimental': experimental_apis, | 64 'extensions': GetAPIsForPlatform(api_names, 'extensions') |
60 'private': private_apis | |
61 } | 65 } |
62 | 66 |
63 def _ListAPIs(self, base_dir, apis): | 67 def _GenerateAPIDict(self): |
64 api_names = set(utils.SanitizeAPIName(name) for name in apis) | 68 def MakeEmptyAPIDict(): |
65 return { | 69 return { 'chrome': [], 'experimental': [], 'private': [] } |
66 'apps': self._GetAPIsInSubdirectory(api_names, 'apps'), | 70 api_dict = { |
67 'extensions': self._GetAPIsInSubdirectory(api_names, 'extensions') | 71 'apps': MakeEmptyAPIDict(), |
72 'extensions': MakeEmptyAPIDict() | |
68 } | 73 } |
74 public_apis = self._cache.GetFromFileListing(self._public_template_path) | |
not at google - send to devlin
2013/10/01 16:34:34
this "public api" naming confuses me because it lo
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
Done.
| |
75 api_features = self._features_bundle.GetAPIFeatures() | |
76 for platform in api_dict.iterkeys(): | |
not at google - send to devlin
2013/10/01 16:34:34
to cut down on a level of nesting here you could w
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
Done.
| |
77 for api in api_features.itervalues(): | |
78 if platform in api['platforms']: | |
not at google - send to devlin
2013/10/01 16:34:34
platform in api['platforms'] or 'all' in api['plat
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
I think you're thinking of extension_types. platfo
| |
79 category = _GetAPICategory(api, public_apis[platform]) | |
80 api_dict[platform][category].append(api) | |
81 for platform in api_dict.iterkeys(): | |
not at google - send to devlin
2013/10/01 16:34:34
maybe I'm tired; but this inner loop is just to so
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
The sorting is actually enforced by tests. It look
| |
82 for category in api_dict[platform]: | |
83 apis = api_dict[platform][category] | |
84 apis = sorted(apis, key=itemgetter('name')) | |
85 if len(apis) > 0: | |
86 apis[-1]['last'] = True | |
not at google - send to devlin
2013/10/01 16:34:34
bleh this is so common. WDYT about adding a method
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
Done.
| |
87 api_dict[platform][category] = apis | |
88 return api_dict | |
69 | 89 |
70 def Create(self): | 90 def Create(self): |
71 return APIListDataSource(self._compiled_fs, self._api_path) | 91 return APIListDataSource(self) |
72 | 92 |
73 def __init__(self, compiled_fs, api_path): | 93 def __init__(self, factory): |
74 self._compiled_fs = compiled_fs | 94 self._factory = factory |
75 self._api_path = api_path | 95 self._apis = None |
76 | 96 |
77 def GetAllNames(self): | 97 def GetAllNames(self): |
78 names = [] | 98 apis = [] |
79 for platform in ['apps', 'extensions']: | 99 for platform in ['apps', 'extensions']: |
80 for category in ['chrome', 'experimental', 'private']: | 100 for category in ['chrome', 'experimental', 'private']: |
81 names.extend(self.get(platform).get(category)) | 101 apis.extend(self.get(platform).get(category)) |
82 return [api_name['name'] for api_name in names] | 102 return sorted(api['name'] for api in apis) |
not at google - send to devlin
2013/10/01 16:34:34
likewise, don't worry about sorting it.
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
Done.
| |
83 | 103 |
84 def get(self, key): | 104 def get(self, key): |
85 return self._compiled_fs.GetFromFileListing(self._api_path)[key] | 105 if self._apis is None: |
106 self._apis = self._factory._GenerateAPIDict() | |
107 return self._apis.get(key) | |
not at google - send to devlin
2013/10/01 16:34:34
it looks like it's ok to be using an ObjectStore t
Ken Rockot(use gerrit already)
2013/10/01 22:18:16
Done.
| |
OLD | NEW |