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

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

Issue 344453003: Docserver: separate models for apps and extensions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase/Add comment 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 import third_party.json_schema_compiler.json_parse as json_parse 17 import third_party.json_schema_compiler.json_parse as json_parse
17 import third_party.json_schema_compiler.model as model 18 import third_party.json_schema_compiler.model as model
18 from environment import IsPreviewServer 19 from environment import IsPreviewServer
19 from third_party.json_schema_compiler.memoize import memoize 20 from third_party.json_schema_compiler.memoize import memoize
20 21
21 22
22 def _CreateId(node, prefix): 23 def _CreateId(node, prefix):
23 if node.parent is not None and not isinstance(node.parent, model.Namespace): 24 if node.parent is not None and not isinstance(node.parent, model.Namespace):
24 return '-'.join([prefix, node.parent.simple_name, node.simple_name]) 25 return '-'.join([prefix, node.parent.simple_name, node.simple_name])
25 return '-'.join([prefix, node.simple_name]) 26 return '-'.join([prefix, node.simple_name])
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 return _GetByNameDict(event_list[0]) 65 return _GetByNameDict(event_list[0])
65 66
66 67
67 class _JSCModel(object): 68 class _JSCModel(object):
68 '''Uses a Model from the JSON Schema Compiler and generates a dict that 69 '''Uses a Model from the JSON Schema Compiler and generates a dict that
69 a Handlebar template can use for a data source. 70 a Handlebar template can use for a data source.
70 ''' 71 '''
71 72
72 def __init__(self, 73 def __init__(self,
73 namespace, 74 namespace,
74 availability_finder, 75 availability,
75 json_cache, 76 json_cache,
76 template_cache, 77 template_cache,
77 features_bundle, 78 features_bundle,
78 event_byname_function): 79 event_byname_future):
79 self._availability_finder = availability_finder 80 self._availability = availability
80 self._api_availabilities = json_cache.GetFromFile( 81 self._api_availabilities = json_cache.GetFromFile(
81 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json')) 82 posixpath.join(JSON_TEMPLATES, 'api_availabilities.json'))
82 self._intro_tables = json_cache.GetFromFile( 83 self._intro_tables = json_cache.GetFromFile(
83 posixpath.join(JSON_TEMPLATES, 'intro_tables.json')) 84 posixpath.join(JSON_TEMPLATES, 'intro_tables.json'))
84 self._api_features = features_bundle.GetAPIFeatures() 85 self._api_features = features_bundle.GetAPIFeatures()
85 self._template_cache = template_cache 86 self._template_cache = template_cache
86 self._event_byname_function = event_byname_function 87 self._event_byname_future = event_byname_future
87 self._namespace = namespace 88 self._namespace = namespace
88 89
89 def _GetLink(self, link): 90 def _GetLink(self, link):
90 ref = link if '.' in link else (self._namespace.name + '.' + link) 91 ref = link if '.' in link else (self._namespace.name + '.' + link)
91 return { 'ref': ref, 'text': link, 'name': link } 92 return { 'ref': ref, 'text': link, 'name': link }
92 93
93 def ToDict(self): 94 def ToDict(self):
94 if self._namespace is None: 95 if self._namespace is None:
95 return {} 96 return {}
96 chrome_dot_name = 'chrome.%s' % self._namespace.name 97 chrome_dot_name = 'chrome.%s' % self._namespace.name
(...skipping 11 matching lines...) Expand all
108 'properties': self._GenerateProperties(self._namespace.properties), 109 'properties': self._GenerateProperties(self._namespace.properties),
109 'introList': self._GetIntroTableList(), 110 'introList': self._GetIntroTableList(),
110 'channelWarning': self._GetChannelWarning(), 111 'channelWarning': self._GetChannelWarning(),
111 } 112 }
112 if self._namespace.deprecated: 113 if self._namespace.deprecated:
113 as_dict['deprecated'] = self._namespace.deprecated 114 as_dict['deprecated'] = self._namespace.deprecated
114 115
115 as_dict['byName'] = _GetByNameDict(as_dict) 116 as_dict['byName'] = _GetByNameDict(as_dict)
116 return as_dict 117 return as_dict
117 118
118 def _GetAPIAvailability(self):
119 return self._availability_finder.GetAPIAvailability(self._namespace.name)
120
121 def _GetChannelWarning(self): 119 def _GetChannelWarning(self):
122 if not self._IsExperimental(): 120 if not self._IsExperimental():
123 return { self._GetAPIAvailability().channel_info.channel: True } 121 return {
122 self._availability.channel_info.channel: True
123 }
124 return None 124 return None
125 125
126 def _IsExperimental(self): 126 def _IsExperimental(self):
127 return self._namespace.name.startswith('experimental') 127 return self._namespace.name.startswith('experimental')
128 128
129 def _GenerateTypes(self, types): 129 def _GenerateTypes(self, types):
130 return [self._GenerateType(t) for t in types] 130 return [self._GenerateType(t) for t in types]
131 131
132 def _GenerateType(self, type_): 132 def _GenerateType(self, type_):
133 type_dict = { 133 type_dict = {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 for condition in event.conditions], 183 for condition in event.conditions],
184 'actions': [self._GetLink(action) for action in event.actions], 184 'actions': [self._GetLink(action) for action in event.actions],
185 'supportsRules': event.supports_rules, 185 'supportsRules': event.supports_rules,
186 'supportsListeners': event.supports_listeners, 186 'supportsListeners': event.supports_listeners,
187 'properties': [], 187 'properties': [],
188 'id': _CreateId(event, 'event'), 188 'id': _CreateId(event, 'event'),
189 'byName': {}, 189 'byName': {},
190 } 190 }
191 self._AddCommonProperties(event_dict, event) 191 self._AddCommonProperties(event_dict, event)
192 # Add the Event members to each event in this object. 192 # Add the Event members to each event in this object.
193 if self._event_byname_function: 193 if self._event_byname_future:
194 event_dict['byName'].update(self._event_byname_function()) 194 event_dict['byName'].update(self._event_byname_future.Get())
195 # We need to create the method description for addListener based on the 195 # We need to create the method description for addListener based on the
196 # information stored in |event|. 196 # information stored in |event|.
197 if event.supports_listeners: 197 if event.supports_listeners:
198 callback_object = model.Function(parent=event, 198 callback_object = model.Function(parent=event,
199 name='callback', 199 name='callback',
200 json={}, 200 json={},
201 namespace=event.parent, 201 namespace=event.parent,
202 origin='') 202 origin='')
203 callback_object.params = event.params 203 callback_object.params = event.params
204 if event.callback: 204 if event.callback:
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 } 347 }
348 348
349 def _GetIntroAvailabilityRow(self): 349 def _GetIntroAvailabilityRow(self):
350 ''' Generates the 'Availability' row data for an API intro table. 350 ''' Generates the 'Availability' row data for an API intro table.
351 ''' 351 '''
352 if self._IsExperimental(): 352 if self._IsExperimental():
353 status = 'experimental' 353 status = 'experimental'
354 version = None 354 version = None
355 scheduled = None 355 scheduled = None
356 else: 356 else:
357 availability = self._GetAPIAvailability() 357 status = self._availability.channel_info.channel
358 status = availability.channel_info.channel 358 version = self._availability.channel_info.version
359 version = availability.channel_info.version 359 scheduled = self._availability.scheduled
360 scheduled = availability.scheduled
361 return { 360 return {
362 'title': 'Availability', 361 'title': 'Availability',
363 'content': [{ 362 'content': [{
364 'partial': self._template_cache.GetFromFile( 363 'partial': self._template_cache.GetFromFile(
365 posixpath.join(PRIVATE_TEMPLATES, 364 posixpath.join(PRIVATE_TEMPLATES,
366 'intro_tables', 365 'intro_tables',
367 '%s_message.html' % status)).Get(), 366 '%s_message.html' % status)).Get(),
368 'version': version, 367 'version': version,
369 'scheduled': scheduled 368 'scheduled': scheduled
370 }] 369 }]
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 467
469 class APIDataSource(DataSource): 468 class APIDataSource(DataSource):
470 '''This class fetches and loads JSON APIs from the FileSystem passed in with 469 '''This class fetches and loads JSON APIs from the FileSystem passed in with
471 |compiled_fs_factory|, so the APIs can be plugged into templates. 470 |compiled_fs_factory|, so the APIs can be plugged into templates.
472 ''' 471 '''
473 def __init__(self, server_instance, request): 472 def __init__(self, server_instance, request):
474 file_system = server_instance.host_file_system_provider.GetTrunk() 473 file_system = server_instance.host_file_system_provider.GetTrunk()
475 self._json_cache = server_instance.compiled_fs_factory.ForJson(file_system) 474 self._json_cache = server_instance.compiled_fs_factory.ForJson(file_system)
476 self._template_cache = server_instance.compiled_fs_factory.ForTemplates( 475 self._template_cache = server_instance.compiled_fs_factory.ForTemplates(
477 file_system) 476 file_system)
478 self._availability_finder = server_instance.availability_finder 477 self._platform_bundle = server_instance.platform_bundle
479 self._api_models = server_instance.api_models
480 self._features_bundle = server_instance.features_bundle
481 self._model_cache = server_instance.object_store_creator.Create( 478 self._model_cache = server_instance.object_store_creator.Create(
482 APIDataSource, 479 APIDataSource,
483 # Update the models when any of templates, APIs, or Features change. 480 # Update the models when any of templates, APIs, or Features change.
484 category=StringIdentity(self._json_cache.GetIdentity(), 481 category=StringIdentity(self._json_cache.GetIdentity(),
485 self._template_cache.GetIdentity(), 482 self._template_cache.GetIdentity(),
486 self._api_models.GetIdentity(), 483 self._platform_bundle.GetIdentity()))
487 self._features_bundle.GetIdentity()))
488 484
489 # This caches the result of _LoadEventByName. 485 # This caches the result of _LoadEventByName.
490 self._event_byname = None 486 self._event_byname_futures = {}
491 self._samples = server_instance.samples_data_source_factory.Create(request) 487 self._samples = server_instance.samples_data_source_factory.Create(request)
492 488
493 def _LoadEventByName(self): 489 def _LoadEventByName(self, platform):
494 '''All events have some members in common. We source their description 490 '''All events have some members in common. We source their description
495 from Event in events.json. 491 from Event in events.json.
496 ''' 492 '''
497 if self._event_byname is None: 493 if platform not in self._event_byname_futures:
498 self._event_byname = _GetEventByNameFromEvents( 494 future = self._GetSchemaModel(platform, 'events')
499 self._GetSchemaModel('events').Get()) 495 self._event_byname_futures[platform] = Future(
500 return self._event_byname 496 callback=lambda: _GetEventByNameFromEvents(future.Get()))
497 return self._event_byname_futures[platform]
501 498
502 def _GetSchemaModel(self, api_name): 499 def _GetSchemaModel(self, platform, api_name):
503 jsc_model_future = self._model_cache.Get(api_name) 500 object_store_key = '/'.join((platform, api_name))
504 model_future = self._api_models.GetModel(api_name) 501 jsc_model_future = self._model_cache.Get(object_store_key)
502 model_future = self._platform_bundle.GetAPIModels(platform).GetModel(
503 api_name)
505 def resolve(): 504 def resolve():
506 jsc_model = jsc_model_future.Get() 505 jsc_model = jsc_model_future.Get()
507 if jsc_model is None: 506 if jsc_model is None:
508 jsc_model = _JSCModel( 507 jsc_model = _JSCModel(
509 model_future.Get(), 508 model_future.Get(),
510 self._availability_finder, 509 self._platform_bundle.GetAvailabilityFinder(
510 platform).GetAPIAvailability(api_name),
511 self._json_cache, 511 self._json_cache,
512 self._template_cache, 512 self._template_cache,
513 self._features_bundle, 513 self._platform_bundle.GetFeaturesBundle(platform),
514 self._LoadEventByName).ToDict() 514 self._LoadEventByName(platform)).ToDict()
515 self._model_cache.Set(api_name, jsc_model) 515 self._model_cache.Set(object_store_key, jsc_model)
516 return jsc_model 516 return jsc_model
517 return Future(callback=resolve) 517 return Future(callback=resolve)
518 518
519 def _GetImpl(self, api_name): 519 def _GetImpl(self, platform, api_name):
520 handlebar_dict_future = self._GetSchemaModel(api_name) 520 handlebar_dict_future = self._GetSchemaModel(platform, api_name)
521 def resolve(): 521 def resolve():
522 handlebar_dict = handlebar_dict_future.Get() 522 handlebar_dict = handlebar_dict_future.Get()
523 # Parsing samples on the preview server takes seconds and doesn't add 523 # Parsing samples on the preview server takes seconds and doesn't add
524 # anything. Don't do it. 524 # anything. Don't do it.
525 if not IsPreviewServer(): 525 if not IsPreviewServer():
526 handlebar_dict['samples'] = _LazySamplesGetter( 526 handlebar_dict['samples'] = _LazySamplesGetter(
527 handlebar_dict['name'], 527 handlebar_dict['name'],
528 self._samples) 528 self._samples)
529 return handlebar_dict 529 return handlebar_dict
530 return Future(callback=resolve) 530 return Future(callback=resolve)
531 531
532 def get(self, api_name): 532 def get(self, platform):
533 return self._GetImpl(api_name).Get() 533 '''Return a getter object so that templates can perform lookups such
534 as apis.extensions.runtime.
535 '''
536 getter = lambda: 0
537 getter.get = lambda api_name: self._GetImpl(platform, api_name).Get()
538 return getter
534 539
535 def Cron(self): 540 def Cron(self):
536 futures = [self._GetImpl(name) for name in self._api_models.GetNames()] 541 futures = []
542 for platform in GetPlatforms():
543 futures += [self._GetImpl(platform, name)
544 for name in self._platform_bundle.GetAPIModels(platform).GetNames()]
537 return Collect(futures, except_pass=FileNotFoundError) 545 return Collect(futures, except_pass=FileNotFoundError)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698