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

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

Issue 354073004: Docserver: Add template support for object level availability (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup Created 6 years, 5 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 from copy import copy 5 from copy import copy
6 import logging 6 import logging
7 import os 7 import os
8 import posixpath 8 import posixpath
9 9
10 from data_source import DataSource 10 from data_source import DataSource
11 from docs_server_utils import StringIdentity 11 from docs_server_utils import StringIdentity
12 from environment import IsPreviewServer 12 from environment import IsPreviewServer
13 from extensions_paths import JSON_TEMPLATES, PRIVATE_TEMPLATES 13 from extensions_paths import JSON_TEMPLATES, PRIVATE_TEMPLATES
14 from file_system import FileNotFoundError 14 from file_system import FileNotFoundError
15 from future import Future, Collect 15 from future import Future, Collect
16 from platform_util import GetPlatforms 16 from platform_util import GetPlatforms
17 import third_party.json_schema_compiler.json_parse as json_parse 17 import third_party.json_schema_compiler.json_parse as json_parse
18 import third_party.json_schema_compiler.model as model 18 import third_party.json_schema_compiler.model as model
19 from environment import IsPreviewServer 19 from environment import IsPreviewServer
20 from third_party.json_schema_compiler.memoize import memoize 20 from third_party.json_schema_compiler.memoize import memoize
21 21
22 22
23 # The set of possible categories a node may belong to.
24 _NODE_CATEGORIES = ('types', 'functions', 'events', 'properties')
25
26
23 def _CreateId(node, prefix): 27 def _CreateId(node, prefix):
24 if node.parent is not None and not isinstance(node.parent, model.Namespace): 28 if node.parent is not None and not isinstance(node.parent, model.Namespace):
25 return '-'.join([prefix, node.parent.simple_name, node.simple_name]) 29 return '-'.join([prefix, node.parent.simple_name, node.simple_name])
26 return '-'.join([prefix, node.simple_name]) 30 return '-'.join([prefix, node.simple_name])
27 31
28 32
29 def _FormatValue(value): 33 def _FormatValue(value):
30 '''Inserts commas every three digits for integer values. It is magic. 34 '''Inserts commas every three digits for integer values. It is magic.
31 ''' 35 '''
32 s = str(value) 36 s = str(value)
33 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) 37 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1])
34 38
35 39
36 def _GetByNameDict(namespace): 40 def _GetByNameDict(namespace):
37 '''Returns a dictionary mapping names to named items from |namespace|. 41 '''Returns a dictionary mapping names to named items from |namespace|.
38 42
39 This lets us render specific API entities rather than the whole thing at once, 43 This lets us render specific API entities rather than the whole thing at once,
40 for example {{apis.manifestTypes.byName.ExternallyConnectable}}. 44 for example {{apis.manifestTypes.byName.ExternallyConnectable}}.
41 45
42 Includes items from namespace['types'], namespace['functions'], 46 Includes items from namespace['types'], namespace['functions'],
43 namespace['events'], and namespace['properties']. 47 namespace['events'], and namespace['properties'].
44 ''' 48 '''
45 by_name = {} 49 by_name = {}
46 for item_type in ('types', 'functions', 'events', 'properties'): 50 for item_type in _NODE_CATEGORIES:
47 if item_type in namespace: 51 if item_type in namespace:
48 old_size = len(by_name) 52 old_size = len(by_name)
49 by_name.update( 53 by_name.update(
50 (item['name'], item) for item in namespace[item_type]) 54 (item['name'], item) for item in namespace[item_type])
51 assert len(by_name) == old_size + len(namespace[item_type]), ( 55 assert len(by_name) == old_size + len(namespace[item_type]), (
52 'Duplicate name in %r' % namespace) 56 'Duplicate name in %r' % namespace)
53 return by_name 57 return by_name
54 58
55 59
56 def _GetEventByNameFromEvents(events): 60 def _GetEventByNameFromEvents(events):
57 '''Parses the dictionary |events| to find the definitions of members of the 61 '''Parses the dictionary |events| to find the definitions of members of the
58 type Event. Returns a dictionary mapping the name of a member to that 62 type Event. Returns a dictionary mapping the name of a member to that
59 member's definition. 63 member's definition.
60 ''' 64 '''
61 assert 'types' in events, \ 65 assert 'types' in events, \
62 'The dictionary |events| must contain the key "types".' 66 'The dictionary |events| must contain the key "types".'
63 event_list = [t for t in events['types'] if t.get('name') == 'Event'] 67 event_list = [t for t in events['types'] if t.get('name') == 'Event']
64 assert len(event_list) == 1, 'Exactly one type must be called "Event".' 68 assert len(event_list) == 1, 'Exactly one type must be called "Event".'
65 return _GetByNameDict(event_list[0]) 69 return _GetByNameDict(event_list[0])
66 70
67 71
72 class _APINodeCursor(object):
73 '''An abstract representation of a node in an APISchemaGraph.
74 The current position in the graph is represented by a path into the
75 underlying dictionary. So if the APISchemaGraph is:
76
77 {
78 'tabs': {
79 'types': {
80 'Tab': {
81 'properties': {
82 'url': {
83 ...
84 }
85 }
86 }
87 }
88 }
89 }
90
91 then the 'url' property would be represented by:
92
93 ['tabs', 'types', 'Tab', 'properties', 'url']
94 '''
95
96 def __init__(self, availability_finder, namespace_name):
97 self._lookup_path = []
98 self._node_availabilities = availability_finder.GetAPINodeAvailability(
99 namespace_name)
100 self._namespace_name = namespace_name
101
102 def _AssertIsValidCategory(self, category):
103 assert category in _NODE_CATEGORIES, \
104 '%s is not a valid category. Full path: %s' % (category,
105 self._lookup_path)
106
107 def _GetParentPath(self):
108 '''Returns the path pointing to this node's parent.
109 '''
110 assert len(self._lookup_path) > 1, \
111 'Tried to look up parent for the top-level node.'
112
113 # lookup_path[-1] is the name of the current node or is 'callback' if the
114 # lookup_path describes an event callback. However, a node may be named
115 # 'callback'; if this is the case, then self._lookup_path[-2] will be a
116 # node category. If it's not, then we are dealing with an event callback.
117 if self._lookup_path[-2] not in _NODE_CATEGORIES:
118 assert self._lookup_path[-1] == 'callback'
119 # This is an event callback, so lookup_path[-2] is the event
120 # node name, thus lookup_path[-3] must be a node category.
not at google - send to devlin 2014/07/01 20:58:50 maybe I'm misunderstanding, but if this is an even
ahernandez 2014/07/01 21:04:34 Yes it should. Will change.
121 self._AssertIsValidCategory(self._lookup_path[-3])
122 return self._lookup_path[:-1]
123 # This is not an event callback, so lookup_path[-2] should
124 # be a node category.
125 self._AssertIsValidCategory(self._lookup_path[-2])
126 return self._lookup_path[:-2]
127
128 def _LookupNodeAvailability(self):
129 '''Returns the ChannelInfo object for this node.
130 '''
131 return self._node_availabilities.Lookup(self._namespace_name,
132 *self._lookup_path).annotation
133
134 def _LookupParentNodeAvailability(self):
135 '''Returns the ChannelInfo object for this node's parent.
136 '''
137 return self._node_availabilities.Lookup(self._namespace_name,
138 *self._GetParentPath()).annotation
139
140 def _CheckNamespacePrefix(self):
141 '''API schemas may prepend the namespace name to top-level types
142 (e.g. declarativeWebRequest > types > declarativeWebRequest.IgnoreRules),
143 but just the base name (here, 'IgnoreRules') will be in the |lookup_path|.
144 Try creating an alternate |lookup_path| by adding the namespace name.
145 '''
146 # lookup_path[0] is always the node category (e.g. types, functions, etc.).
147 # Thus, lookup_path[1] is always the top-level node name.
148 self._AssertIsValidCategory(self._lookup_path[0])
149 base_name = self._lookup_path[1]
150 self._lookup_path[1] = '%s.%s' % (self._namespace_name, base_name)
151 try:
152 node_availability = self._LookupNodeAvailability()
153 if node_availability is not None:
154 return node_availability
155 finally:
156 # Restore lookup_path.
157 self._lookup_path[1] = base_name
158 return None
159
160 def _CheckEventCallback(self):
161 '''Within API schemas, an event has a list of 'properties' that the event's
162 callback expects. The callback itself is not explicitly represented in the
163 schema. However, when creating an event node in _JSCModel, a callback node
164 is generated and acts as the parent for the event's properties.
165 Modify |lookup_path| to check the original schema format.
166 '''
167 if 'events' in self._lookup_path:
168 assert 'callback' in self._lookup_path
169 try:
170 callback_index = self._lookup_path.index('callback')
not at google - send to devlin 2014/07/01 20:58:50 nit: do this outside of the try block
171 self._lookup_path.pop(callback_index)
172 node_availability = self._LookupNodeAvailability()
173 finally:
174 self._lookup_path.insert(callback_index, 'callback')
175 return node_availability
176 return None
177
178 def GetAvailability(self):
179 '''Returns availability information for this node.
180 '''
181 for lookup in (self._LookupNodeAvailability,
182 self._CheckEventCallback,
183 self._CheckNamespacePrefix):
184 node_availability = lookup()
185 if node_availability is not None:
186 break
187
188 if node_availability is None:
189 logging.warning('No availability found for: %s > %s' %
190 (self._namespace_name, ' > '.join(self._lookup_path)))
191 return None
192
193 # Only render this node's availability if it differs from the parent
194 # node's availability.
195 if node_availability == self._LookupParentNodeAvailability():
196 return None
197 return node_availability
198
199 def Descend(self, *path):
200 '''Moves down the APISchemaGraph, following |path|.
201 '''
202 class scope(object):
203 def __enter__(self2):
204 self._lookup_path.extend(path)
205 def __exit__(self2, _, __, ___):
206 self._lookup_path[:] = self._lookup_path[:-len(path)]
207 return scope()
208
209
68 class _JSCModel(object): 210 class _JSCModel(object):
69 '''Uses a Model from the JSON Schema Compiler and generates a dict that 211 '''Uses a Model from the JSON Schema Compiler and generates a dict that
70 a Handlebar template can use for a data source. 212 a Handlebar template can use for a data source.
71 ''' 213 '''
72 214
73 def __init__(self, 215 def __init__(self,
74 namespace, 216 namespace,
75 availability_finder, 217 availability_finder,
76 json_cache, 218 json_cache,
77 template_cache, 219 template_cache,
78 features_bundle, 220 features_bundle,
79 event_byname_future): 221 event_byname_future):
80 self._availability = availability_finder.GetAPIAvailability(namespace.name) 222 self._availability = availability_finder.GetAPIAvailability(namespace.name)
223 self._current_node = _APINodeCursor(availability_finder, namespace.name)
81 self._api_availabilities = json_cache.GetFromFile( 224 self._api_availabilities = json_cache.GetFromFile(
82 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json')) 225 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json'))
83 self._intro_tables = json_cache.GetFromFile( 226 self._intro_tables = json_cache.GetFromFile(
84 posixpath.join(JSON_TEMPLATES, 'intro_tables.json')) 227 posixpath.join(JSON_TEMPLATES, 'intro_tables.json'))
85 self._api_features = features_bundle.GetAPIFeatures() 228 self._api_features = features_bundle.GetAPIFeatures()
86 self._template_cache = template_cache 229 self._template_cache = template_cache
87 self._event_byname_future = event_byname_future 230 self._event_byname_future = event_byname_future
88 self._namespace = namespace 231 self._namespace = namespace
89 232
90 def _GetLink(self, link): 233 def _GetLink(self, link):
(...skipping 29 matching lines...) Expand all
120 if not self._IsExperimental(): 263 if not self._IsExperimental():
121 return { 264 return {
122 self._availability.channel_info.channel: True 265 self._availability.channel_info.channel: True
123 } 266 }
124 return None 267 return None
125 268
126 def _IsExperimental(self): 269 def _IsExperimental(self):
127 return self._namespace.name.startswith('experimental') 270 return self._namespace.name.startswith('experimental')
128 271
129 def _GenerateTypes(self, types): 272 def _GenerateTypes(self, types):
130 return [self._GenerateType(t) for t in types] 273 with self._current_node.Descend('types'):
274 return [self._GenerateType(t) for t in types]
131 275
132 def _GenerateType(self, type_): 276 def _GenerateType(self, type_):
133 type_dict = { 277 with self._current_node.Descend(type_.simple_name):
134 'name': type_.simple_name, 278 type_dict = {
135 'description': type_.description, 279 'name': type_.simple_name,
136 'properties': self._GenerateProperties(type_.properties), 280 'description': type_.description,
137 'functions': self._GenerateFunctions(type_.functions), 281 'properties': self._GenerateProperties(type_.properties),
138 'events': self._GenerateEvents(type_.events), 282 'functions': self._GenerateFunctions(type_.functions),
139 'id': _CreateId(type_, 'type') 283 'events': self._GenerateEvents(type_.events),
140 } 284 'id': _CreateId(type_, 'type'),
141 self._RenderTypeInformation(type_, type_dict) 285 }
142 return type_dict 286 self._RenderTypeInformation(type_, type_dict)
287 return type_dict
143 288
144 def _GenerateFunctions(self, functions): 289 def _GenerateFunctions(self, functions):
145 return [self._GenerateFunction(f) for f in functions.values()] 290 with self._current_node.Descend('functions'):
291 return [self._GenerateFunction(f) for f in functions.values()]
146 292
147 def _GenerateFunction(self, function): 293 def _GenerateFunction(self, function):
148 function_dict = { 294 with self._current_node.Descend(function.simple_name):
149 'name': function.simple_name, 295 function_dict = {
150 'description': function.description, 296 'name': function.simple_name,
151 'callback': self._GenerateCallback(function.callback), 297 'description': function.description,
152 'parameters': [], 298 'callback': self._GenerateCallback(function.callback),
153 'returns': None, 299 'parameters': [],
154 'id': _CreateId(function, 'method') 300 'returns': None,
155 } 301 'id': _CreateId(function, 'method'),
156 self._AddCommonProperties(function_dict, function) 302 'availability': self._GetAvailabilityTemplate()
157 if function.returns: 303 }
158 function_dict['returns'] = self._GenerateType(function.returns) 304 self._AddCommonProperties(function_dict, function)
159 for param in function.params: 305 if function.returns:
160 function_dict['parameters'].append(self._GenerateProperty(param)) 306 function_dict['returns'] = self._GenerateType(function.returns)
161 if function.callback is not None: 307 for param in function.params:
162 # Show the callback as an extra parameter. 308 function_dict['parameters'].append(self._GenerateProperty(param))
163 function_dict['parameters'].append( 309 if function.callback is not None:
164 self._GenerateCallbackProperty(function.callback)) 310 # Show the callback as an extra parameter.
165 if len(function_dict['parameters']) > 0: 311 function_dict['parameters'].append(
166 function_dict['parameters'][-1]['last'] = True 312 self._GenerateCallbackProperty(function.callback))
167 return function_dict 313 if len(function_dict['parameters']) > 0:
314 function_dict['parameters'][-1]['last'] = True
315 return function_dict
168 316
169 def _GenerateEvents(self, events): 317 def _GenerateEvents(self, events):
170 return [self._GenerateEvent(e) for e in events.values() 318 with self._current_node.Descend('events'):
171 if not e.supports_dom] 319 return [self._GenerateEvent(e) for e in events.values()
320 if not e.supports_dom]
172 321
173 def _GenerateDomEvents(self, events): 322 def _GenerateDomEvents(self, events):
174 return [self._GenerateEvent(e) for e in events.values() 323 with self._current_node.Descend('events'):
175 if e.supports_dom] 324 return [self._GenerateEvent(e) for e in events.values()
325 if e.supports_dom]
176 326
177 def _GenerateEvent(self, event): 327 def _GenerateEvent(self, event):
178 event_dict = { 328 with self._current_node.Descend(event.simple_name):
179 'name': event.simple_name, 329 event_dict = {
180 'description': event.description, 330 'name': event.simple_name,
181 'filters': [self._GenerateProperty(f) for f in event.filters], 331 'description': event.description,
182 'conditions': [self._GetLink(condition) 332 'filters': [self._GenerateProperty(f) for f in event.filters],
183 for condition in event.conditions], 333 'conditions': [self._GetLink(condition)
184 'actions': [self._GetLink(action) for action in event.actions], 334 for condition in event.conditions],
185 'supportsRules': event.supports_rules, 335 'actions': [self._GetLink(action) for action in event.actions],
186 'supportsListeners': event.supports_listeners, 336 'supportsRules': event.supports_rules,
187 'properties': [], 337 'supportsListeners': event.supports_listeners,
188 'id': _CreateId(event, 'event'), 338 'properties': [],
189 'byName': {}, 339 'id': _CreateId(event, 'event'),
190 } 340 'byName': {},
191 self._AddCommonProperties(event_dict, event)
192 # Add the Event members to each event in this object.
193 if self._event_byname_future:
194 event_dict['byName'].update(self._event_byname_future.Get())
195 # We need to create the method description for addListener based on the
196 # information stored in |event|.
197 if event.supports_listeners:
198 callback_object = model.Function(parent=event,
199 name='callback',
200 json={},
201 namespace=event.parent,
202 origin='')
203 callback_object.params = event.params
204 if event.callback:
205 callback_object.callback = event.callback
206 callback_parameters = self._GenerateCallbackProperty(callback_object)
207 callback_parameters['last'] = True
208 event_dict['byName']['addListener'] = {
209 'name': 'addListener',
210 'callback': self._GenerateFunction(callback_object),
211 'parameters': [callback_parameters]
212 } 341 }
213 if event.supports_dom: 342 self._AddCommonProperties(event_dict, event)
214 # Treat params as properties of the custom Event object associated with 343 # Add the Event members to each event in this object.
215 # this DOM Event. 344 if self._event_byname_future:
216 event_dict['properties'] += [self._GenerateProperty(param) 345 event_dict['byName'].update(self._event_byname_future.Get())
217 for param in event.params] 346 # We need to create the method description for addListener based on the
218 return event_dict 347 # information stored in |event|.
348 if event.supports_listeners:
349 callback_object = model.Function(parent=event,
350 name='callback',
351 json={},
352 namespace=event.parent,
353 origin='')
354 callback_object.params = event.params
355 if event.callback:
356 callback_object.callback = event.callback
357 callback_parameters = self._GenerateCallbackProperty(callback_object)
358 callback_parameters['last'] = True
359 event_dict['byName']['addListener'] = {
360 'name': 'addListener',
361 'callback': self._GenerateFunction(callback_object),
362 'parameters': [callback_parameters]
363 }
364 if event.supports_dom:
365 # Treat params as properties of the custom Event object associated with
366 # this DOM Event.
367 event_dict['properties'] += [self._GenerateProperty(param)
368 for param in event.params]
369 return event_dict
219 370
220 def _GenerateCallback(self, callback): 371 def _GenerateCallback(self, callback):
221 if not callback: 372 if not callback:
222 return None 373 return None
223 callback_dict = { 374 callback_dict = {
224 'name': callback.simple_name, 375 'name': callback.simple_name,
225 'simple_type': {'simple_type': 'function'}, 376 'simple_type': {'simple_type': 'function'},
226 'optional': callback.optional, 377 'optional': callback.optional,
227 'parameters': [] 378 'parameters': []
228 } 379 }
(...skipping 21 matching lines...) Expand all
250 properties = type_.properties 401 properties = type_.properties
251 402
252 property_dict = { 403 property_dict = {
253 'name': property_.simple_name, 404 'name': property_.simple_name,
254 'optional': property_.optional, 405 'optional': property_.optional,
255 'description': property_.description, 406 'description': property_.description,
256 'properties': self._GenerateProperties(type_.properties), 407 'properties': self._GenerateProperties(type_.properties),
257 'functions': self._GenerateFunctions(type_.functions), 408 'functions': self._GenerateFunctions(type_.functions),
258 'parameters': [], 409 'parameters': [],
259 'returns': None, 410 'returns': None,
260 'id': _CreateId(property_, 'property') 411 'id': _CreateId(property_, 'property'),
261 } 412 }
262 self._AddCommonProperties(property_dict, property_) 413 self._AddCommonProperties(property_dict, property_)
263 414
264 if type_.property_type == model.PropertyType.FUNCTION: 415 if type_.property_type == model.PropertyType.FUNCTION:
265 function = type_.function 416 function = type_.function
266 for param in function.params: 417 for param in function.params:
267 property_dict['parameters'].append(self._GenerateProperty(param)) 418 property_dict['parameters'].append(self._GenerateProperty(param))
268 if function.returns: 419 if function.returns:
269 property_dict['returns'] = self._GenerateType(function.returns) 420 property_dict['returns'] = self._GenerateType(function.returns)
270 421
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 # if they share the same 'title' attribute. 480 # if they share the same 'title' attribute.
330 row_titles = [row['title'] for row in intro_rows] 481 row_titles = [row['title'] for row in intro_rows]
331 for misc_row in self._GetMiscIntroRows(): 482 for misc_row in self._GetMiscIntroRows():
332 if misc_row['title'] in row_titles: 483 if misc_row['title'] in row_titles:
333 intro_rows[row_titles.index(misc_row['title'])] = misc_row 484 intro_rows[row_titles.index(misc_row['title'])] = misc_row
334 else: 485 else:
335 intro_rows.append(misc_row) 486 intro_rows.append(misc_row)
336 487
337 return intro_rows 488 return intro_rows
338 489
490 def _GetAvailabilityTemplate(self, status=None, version=None, scheduled=None):
491 '''Returns an object that the templates use to display availability
492 information.
493 '''
494 if status is None:
495 availability_info = self._current_node.GetAvailability()
496 if availability_info is None:
497 return None
498 status = availability_info.channel
499 version = availability_info.version
500 return {
501 'partial': self._template_cache.GetFromFile(
502 '%sintro_tables/%s_message.html' % (PRIVATE_TEMPLATES, status)).Get(),
503 'scheduled': scheduled,
504 'version': version
505 }
506
339 def _GetIntroDescriptionRow(self): 507 def _GetIntroDescriptionRow(self):
340 ''' Generates the 'Description' row data for an API intro table. 508 ''' Generates the 'Description' row data for an API intro table.
341 ''' 509 '''
342 return { 510 return {
343 'title': 'Description', 511 'title': 'Description',
344 'content': [ 512 'content': [
345 { 'text': self._namespace.description } 513 { 'text': self._namespace.description }
346 ] 514 ]
347 } 515 }
348 516
349 def _GetIntroAvailabilityRow(self): 517 def _GetIntroAvailabilityRow(self):
350 ''' Generates the 'Availability' row data for an API intro table. 518 ''' Generates the 'Availability' row data for an API intro table.
351 ''' 519 '''
352 if self._IsExperimental(): 520 if self._IsExperimental():
353 status = 'experimental' 521 status = 'experimental'
354 version = None 522 version = None
355 scheduled = None 523 scheduled = None
356 else: 524 else:
357 status = self._availability.channel_info.channel 525 status = self._availability.channel_info.channel
358 version = self._availability.channel_info.version 526 version = self._availability.channel_info.version
359 scheduled = self._availability.scheduled 527 scheduled = self._availability.scheduled
360 return { 528 return {
361 'title': 'Availability', 529 'title': 'Availability',
362 'content': [{ 530 'content': [
363 'partial': self._template_cache.GetFromFile( 531 self._GetAvailabilityTemplate(status=status,
364 posixpath.join(PRIVATE_TEMPLATES, 532 version=version,
365 'intro_tables', 533 scheduled=scheduled)
366 '%s_message.html' % status)).Get(), 534 ]
367 'version': version,
368 'scheduled': scheduled
369 }]
370 } 535 }
371 536
372 def _GetIntroDependencyRows(self): 537 def _GetIntroDependencyRows(self):
373 # Devtools aren't in _api_features. If we're dealing with devtools, bail. 538 # Devtools aren't in _api_features. If we're dealing with devtools, bail.
374 if 'devtools' in self._namespace.name: 539 if 'devtools' in self._namespace.name:
375 return [] 540 return []
376 541
377 api_feature = self._api_features.Get().get(self._namespace.name) 542 api_feature = self._api_features.Get().get(self._namespace.name)
378 if not api_feature: 543 if not api_feature:
379 logging.error('"%s" not found in _api_features.json' % 544 logging.error('"%s" not found in _api_features.json' %
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 getter = lambda: 0 700 getter = lambda: 0
536 getter.get = lambda api_name: self._GetImpl(platform, api_name).Get() 701 getter.get = lambda api_name: self._GetImpl(platform, api_name).Get()
537 return getter 702 return getter
538 703
539 def Cron(self): 704 def Cron(self):
540 futures = [] 705 futures = []
541 for platform in GetPlatforms(): 706 for platform in GetPlatforms():
542 futures += [self._GetImpl(platform, name) 707 futures += [self._GetImpl(platform, name)
543 for name in self._platform_bundle.GetAPIModels(platform).GetNames()] 708 for name in self._platform_bundle.GetAPIModels(platform).GetNames()]
544 return Collect(futures, except_pass=FileNotFoundError) 709 return Collect(futures, except_pass=FileNotFoundError)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698