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

Side by Side Diff: chrome/common/extensions/docs/server2/api_models.py

Issue 429723005: Docserver: Only fetch content versions in the crons, not their contents. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: no getfileversion Created 6 years, 4 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 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 posixpath 5 import posixpath
6 6
7 from compiled_file_system import SingleFile, Unicode 7 from compiled_file_system import SingleFile, Unicode
8 from extensions_paths import API_PATHS 8 from extensions_paths import API_PATHS
9 from features_bundle import HasParent, GetParentName 9 from features_bundle import HasParent, GetParentName
10 from file_system import FileNotFoundError 10 from file_system import FileNotFoundError
11 from future import All, Future 11 from future import All, Future, Race
12 from operator import itemgetter 12 from operator import itemgetter
13 from path_util import Join
13 from platform_util import PlatformToExtensionType 14 from platform_util import PlatformToExtensionType
14 from schema_util import ProcessSchema 15 from schema_util import ProcessSchema
15 from third_party.json_schema_compiler.json_schema import DeleteNodes 16 from third_party.json_schema_compiler.json_schema import DeleteNodes
16 from third_party.json_schema_compiler.model import Namespace, UnixName 17 from third_party.json_schema_compiler.model import Namespace, UnixName
17 18
18 19
19 def GetNodeCategories(): 20 def GetNodeCategories():
20 '''Returns a tuple of the possible categories a node may belong to. 21 '''Returns a tuple of the possible categories a node may belong to.
21 ''' 22 '''
22 return ('types', 'functions', 'events', 'properties') 23 return ('types', 'functions', 'events', 'properties')
(...skipping 28 matching lines...) Expand all
51 '''Tracks APIs and their Models. 52 '''Tracks APIs and their Models.
52 ''' 53 '''
53 54
54 def __init__(self, 55 def __init__(self,
55 features_bundle, 56 features_bundle,
56 compiled_fs_factory, 57 compiled_fs_factory,
57 file_system, 58 file_system,
58 object_store_creator, 59 object_store_creator,
59 platform): 60 platform):
60 self._features_bundle = features_bundle 61 self._features_bundle = features_bundle
62 self._file_system = file_system
61 self._platform = PlatformToExtensionType(platform) 63 self._platform = PlatformToExtensionType(platform)
62 self._model_cache = compiled_fs_factory.Create( 64 self._model_cache = compiled_fs_factory.Create(
63 file_system, self._CreateAPIModel, APIModels, category=self._platform) 65 file_system, self._CreateAPIModel, APIModels, category=self._platform)
64 self._object_store = object_store_creator.Create(APIModels) 66 self._object_store = object_store_creator.Create(APIModels)
65 67
66 @SingleFile 68 @SingleFile
67 @Unicode 69 @Unicode
68 def _CreateAPIModel(self, path, data): 70 def _CreateAPIModel(self, path, data):
69 def does_not_include_platform(node): 71 def does_not_include_platform(node):
70 return ('extension_types' in node and 72 return ('extension_types' in node and
71 node['extension_types'] != 'all' and 73 node['extension_types'] != 'all' and
72 self._platform not in node['extension_types']) 74 self._platform not in node['extension_types'])
73 75
74 schema = ProcessSchema(path, data)[0] 76 schema = ProcessSchema(path, data)[0]
75 if not schema: 77 if not schema:
76 raise ValueError('No schema for %s' % path) 78 raise ValueError('No schema for %s' % path)
77 return Namespace(DeleteNodes( 79 return Namespace(DeleteNodes(
78 schema, matcher=does_not_include_platform), schema['namespace']) 80 schema, matcher=does_not_include_platform), schema['namespace'])
79 81
80 def GetNames(self): 82 def GetNames(self):
81 # API names appear alongside some of their methods/events/etc in the 83 # API names appear alongside some of their methods/events/etc in the
82 # features file. APIs are those which either implicitly or explicitly have 84 # features file. APIs are those which either implicitly or explicitly have
83 # no parent feature (e.g. app, app.window, and devtools.inspectedWindow are 85 # no parent feature (e.g. app, app.window, and devtools.inspectedWindow are
84 # APIs; runtime.onConnectNative is not). 86 # APIs; runtime.onConnectNative is not).
85 api_features = self._features_bundle.GetAPIFeatures().Get() 87 api_features = self._features_bundle.GetAPIFeatures().Get()
86 return [name for name, feature in api_features.iteritems() 88 return [name for name, feature in api_features.iteritems()
87 if not HasParent(name, feature, api_features)] 89 if not HasParent(name, feature, api_features)]
88 90
89 def GetModel(self, api_name): 91 def _GetPotentialPathsForModel(self, api_name):
92 '''Returns the list of file system paths that the model for |api_name|
93 might be located at.
94 '''
90 # By default |api_name| is assumed to be given without a path or extension, 95 # By default |api_name| is assumed to be given without a path or extension,
91 # so combinations of known paths and extension types will be searched. 96 # so combinations of known paths and extension types will be searched.
92 api_extensions = ('.json', '.idl') 97 api_extensions = ('.json', '.idl')
93 api_paths = API_PATHS 98 api_paths = API_PATHS
94 99
95 # Callers sometimes include a file extension and/or prefix path with the 100 # Callers sometimes include a file extension and/or prefix path with the
96 # |api_name| argument. We believe them and narrow the search space 101 # |api_name| argument. We believe them and narrow the search space
97 # accordingly. 102 # accordingly.
98 name, ext = posixpath.splitext(api_name) 103 name, ext = posixpath.splitext(api_name)
99 if ext in api_extensions: 104 if ext in api_extensions:
100 api_extensions = (ext,) 105 api_extensions = (ext,)
101 api_name = name 106 api_name = name
102 for api_path in api_paths: 107 for api_path in api_paths:
103 if api_name.startswith(api_path): 108 if api_name.startswith(api_path):
104 api_name = api_name[len(api_path):] 109 api_name = api_name[len(api_path):]
105 api_paths = (api_path,) 110 api_paths = (api_path,)
106 break 111 break
107 112
108 # API names are given as declarativeContent and app.window but file names 113 # API names are given as declarativeContent and app.window but file names
109 # will be declarative_content and app_window. 114 # will be declarative_content and app_window.
110 file_name = UnixName(api_name).replace('.', '_') 115 file_name = UnixName(api_name).replace('.', '_')
111 # Devtools APIs are in API/devtools/ not API/, and have their 116 # Devtools APIs are in API/devtools/ not API/, and have their
112 # "devtools" names removed from the file names. 117 # "devtools" names removed from the file names.
113 basename = posixpath.basename(file_name) 118 basename = posixpath.basename(file_name)
114 if 'devtools_' in basename: 119 if 'devtools_' in basename:
115 file_name = posixpath.join( 120 file_name = posixpath.join(
116 'devtools', file_name.replace(basename, 121 'devtools', file_name.replace(basename,
117 basename.replace('devtools_' , ''))) 122 basename.replace('devtools_' , '')))
118 123
119 futures = [self._model_cache.GetFromFile( 124 return [Join(path, file_name + ext) for ext in api_extensions
120 posixpath.join(path, '%s%s' % (file_name, ext))) 125 for path in api_paths]
121 for ext in api_extensions 126
122 for path in api_paths] 127 def GetModel(self, api_name):
123 def resolve(): 128 futures = [self._model_cache.GetFromFile(path)
124 for future in futures: 129 for path in self._GetPotentialPathsForModel(api_name)]
125 try: 130 return Race(futures, except_pass=(FileNotFoundError, ValueError))
126 return future.Get()
127 # Either the file wasn't found or there was no schema for the file
128 except (FileNotFoundError, ValueError): pass
129 # Propagate the first error if neither were found.
130 futures[0].Get()
131 return Future(callback=resolve)
132 131
133 def GetContentScriptAPIs(self): 132 def GetContentScriptAPIs(self):
134 '''Creates a dict of APIs and nodes supported by content scripts in 133 '''Creates a dict of APIs and nodes supported by content scripts in
135 this format: 134 this format:
136 135
137 { 136 {
138 'extension': '<ContentScriptAPI name='extension', 137 'extension': '<ContentScriptAPI name='extension',
139 restrictedTo=[{'node': 'onRequest'}]>', 138 restrictedTo=[{'node': 'onRequest'}]>',
140 ... 139 ...
141 } 140 }
(...skipping 20 matching lines...) Expand all
162 content_script_apis[parent] = ContentScriptAPI(parent) 161 content_script_apis[parent] = ContentScriptAPI(parent)
163 if content_script_apis[parent].restrictedTo: 162 if content_script_apis[parent].restrictedTo:
164 content_script_apis[parent].restrictedTo.append(node) 163 content_script_apis[parent].restrictedTo.append(node)
165 else: 164 else:
166 content_script_apis[parent].restrictedTo = [node] 165 content_script_apis[parent].restrictedTo = [node]
167 166
168 self._object_store.Set('content_script_apis', content_script_apis) 167 self._object_store.Set('content_script_apis', content_script_apis)
169 return content_script_apis 168 return content_script_apis
170 return Future(callback=resolve) 169 return Future(callback=resolve)
171 170
172 def Cron(self):
173 futures = [self.GetModel(name) for name in self.GetNames()]
174 return All(futures, except_pass=(FileNotFoundError, ValueError))
175
176 def IterModels(self): 171 def IterModels(self):
177 future_models = [(name, self.GetModel(name)) for name in self.GetNames()] 172 future_models = [(name, self.GetModel(name)) for name in self.GetNames()]
178 for name, future_model in future_models: 173 for name, future_model in future_models:
179 try: 174 try:
180 model = future_model.Get() 175 model = future_model.Get()
181 except FileNotFoundError: 176 except FileNotFoundError:
182 continue 177 continue
183 if model: 178 if model:
184 yield name, model 179 yield name, model
180
181 def Cron(self):
182 def map_cron_paths(op):
183 results = []
184 for name in self.GetNames():
185 results += [op(path) for path in self._GetPotentialPathsForModel(name)]
186 return results
187
188 # Immediately stat everything so that files are guaranteed to be eventually
189 # up to date. See http://crbug.com/398042 for background.
190 # XXX see comment below, return a future for this, hopefully crons will
191 # complete and we don't need to immediately resolve?
192 All(map_cron_paths(self._file_system.StatAsync),
193 except_pass=(FileNotFoundError, ValueError)).Get()
194
195 # Update content in the future.
196 # XXX don't do this for now, see how the crons and instances behave with
197 # just getting the versions.
198 return All(map_cron_paths(self.GetModel),
199 except_pass=(FileNotFoundError, ValueError))
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/server2/api_categorizer.py ('k') | chrome/common/extensions/docs/server2/app.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698