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

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

Issue 12996003: Dynamically generate a heading for Extension Docs API pages (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moving logic into availability_data_source Created 7 years, 8 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 copy 5 import copy
6 import logging 6 import logging
7 import os 7 import os
8 8
9 from file_system import FileNotFoundError 9 from file_system import FileNotFoundError
10 import third_party.json_schema_compiler.json_parse as json_parse 10 import third_party.json_schema_compiler.json_parse as json_parse
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 def _FormatValue(value): 43 def _FormatValue(value):
44 """Inserts commas every three digits for integer values. It is magic. 44 """Inserts commas every three digits for integer values. It is magic.
45 """ 45 """
46 s = str(value) 46 s = str(value)
47 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) 47 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1])
48 48
49 class _JSCModel(object): 49 class _JSCModel(object):
50 """Uses a Model from the JSON Schema Compiler and generates a dict that 50 """Uses a Model from the JSON Schema Compiler and generates a dict that
51 a Handlebar template can use for a data source. 51 a Handlebar template can use for a data source.
52 """ 52 """
53 def __init__(self, json, ref_resolver, disable_refs): 53 def __init__(self,
54 json,
55 ref_resolver,
56 disable_refs,
57 availability_data_source):
54 self._ref_resolver = ref_resolver 58 self._ref_resolver = ref_resolver
55 self._disable_refs = disable_refs 59 self._disable_refs = disable_refs
60 self._availability_data_source = availability_data_source
56 clean_json = copy.deepcopy(json) 61 clean_json = copy.deepcopy(json)
57 if _RemoveNoDocs(clean_json): 62 if _RemoveNoDocs(clean_json):
58 self._namespace = None 63 self._namespace = None
59 else: 64 else:
60 self._namespace = model.Namespace(clean_json, clean_json['namespace']) 65 self._namespace = model.Namespace(clean_json, clean_json['namespace'])
61 66
62 def _FormatDescription(self, description): 67 def _FormatDescription(self, description):
63 if self._disable_refs: 68 if self._disable_refs:
64 return description 69 return description
65 return self._ref_resolver.ResolveAllLinks(description, 70 return self._ref_resolver.ResolveAllLinks(description,
66 namespace=self._namespace.name) 71 namespace=self._namespace.name)
67 72
68 def _GetLink(self, link): 73 def _GetLink(self, link):
69 if self._disable_refs: 74 if self._disable_refs:
70 type_name = link.split('.', 1)[-1] 75 type_name = link.split('.', 1)[-1]
71 return { 'href': '#type-%s' % type_name, 'text': link, 'name': link } 76 return { 'href': '#type-%s' % type_name, 'text': link, 'name': link }
72 return self._ref_resolver.SafeGetLink(link, namespace=self._namespace.name) 77 return self._ref_resolver.SafeGetLink(link, namespace=self._namespace.name)
73 78
74 def ToDict(self): 79 def ToDict(self):
75 if self._namespace is None: 80 if self._namespace is None:
76 return {} 81 return {}
77 return { 82 return {
78 'name': self._namespace.name, 83 'name': self._namespace.name,
84 'description': self._namespace.description,
85 'availability': self._GetAvailability(),
79 'types': self._GenerateTypes(self._namespace.types.values()), 86 'types': self._GenerateTypes(self._namespace.types.values()),
80 'functions': self._GenerateFunctions(self._namespace.functions), 87 'functions': self._GenerateFunctions(self._namespace.functions),
81 'events': self._GenerateEvents(self._namespace.events), 88 'events': self._GenerateEvents(self._namespace.events),
82 'properties': self._GenerateProperties(self._namespace.properties) 89 'properties': self._GenerateProperties(self._namespace.properties)
83 } 90 }
84 91
92 def _GetAvailability(self):
93 """Finds the earliest version of chrome where an API was available using
94 AvailabilityDataSource. Also [temporarily] creates a string describing the
95 availability depending on its original format.
96 """
97 availability_string = 'Not Currently Available'
98 availability = self._availability_data_source.FindEarliestAvailability(
99 self._namespace.name)
100
101 if availability is not None:
102 if availability.isdigit():
103 availability_string = 'Chrome %s' % availability
104 else:
105 availability_string = ('Chrome %s Channel Only' %
106 availability.capitalize())
107 return availability_string
108
85 def _GenerateTypes(self, types): 109 def _GenerateTypes(self, types):
86 return [self._GenerateType(t) for t in types] 110 return [self._GenerateType(t) for t in types]
87 111
88 def _GenerateType(self, type_): 112 def _GenerateType(self, type_):
89 type_dict = { 113 type_dict = {
90 'name': type_.simple_name, 114 'name': type_.simple_name,
91 'description': self._FormatDescription(type_.description), 115 'description': self._FormatDescription(type_.description),
92 'properties': self._GenerateProperties(type_.properties), 116 'properties': self._GenerateProperties(type_.properties),
93 'functions': self._GenerateFunctions(type_.functions), 117 'functions': self._GenerateFunctions(type_.functions),
94 'events': self._GenerateEvents(type_.events), 118 'events': self._GenerateEvents(type_.events),
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 self._samples = samples 285 self._samples = samples
262 286
263 def get(self, key): 287 def get(self, key):
264 return self._samples.FilterSamples(key, self._api_name) 288 return self._samples.FilterSamples(key, self._api_name)
265 289
266 class APIDataSource(object): 290 class APIDataSource(object):
267 """This class fetches and loads JSON APIs from the FileSystem passed in with 291 """This class fetches and loads JSON APIs from the FileSystem passed in with
268 |compiled_fs_factory|, so the APIs can be plugged into templates. 292 |compiled_fs_factory|, so the APIs can be plugged into templates.
269 """ 293 """
270 class Factory(object): 294 class Factory(object):
271 def __init__(self, compiled_fs_factory, base_path): 295 def __init__(self,
296 compiled_fs_factory,
297 base_path,
298 availability_data_source_factory):
272 def create_compiled_fs(fn, category): 299 def create_compiled_fs(fn, category):
273 return compiled_fs_factory.Create( 300 return compiled_fs_factory.Create(
274 fn, APIDataSource, category=category, version=_VERSION) 301 fn, APIDataSource, category=category, version=_VERSION)
275 302
276 self._permissions_cache = create_compiled_fs(self._LoadPermissions, 303 self._permissions_cache = create_compiled_fs(self._LoadPermissions,
277 'permissions') 304 'permissions')
278 305
279 self._json_cache = create_compiled_fs( 306 self._json_cache = create_compiled_fs(
280 lambda api_name, api: self._LoadJsonAPI(api, False), 307 lambda api_name, api: self._LoadJsonAPI(api, False),
281 'json') 308 'json')
282 self._idl_cache = create_compiled_fs( 309 self._idl_cache = create_compiled_fs(
283 lambda api_name, api: self._LoadIdlAPI(api, False), 310 lambda api_name, api: self._LoadIdlAPI(api, False),
284 'idl') 311 'idl')
285 312
286 # These caches are used if an APIDataSource does not want to resolve the 313 # These caches are used if an APIDataSource does not want to resolve the
287 # $refs in an API. This is needed to prevent infinite recursion in 314 # $refs in an API. This is needed to prevent infinite recursion in
288 # ReferenceResolver. 315 # ReferenceResolver.
289 self._json_cache_no_refs = create_compiled_fs( 316 self._json_cache_no_refs = create_compiled_fs(
290 lambda api_name, api: self._LoadJsonAPI(api, True), 317 lambda api_name, api: self._LoadJsonAPI(api, True),
291 'json-no-refs') 318 'json-no-refs')
292 self._idl_cache_no_refs = create_compiled_fs( 319 self._idl_cache_no_refs = create_compiled_fs(
293 lambda api_name, api: self._LoadIdlAPI(api, True), 320 lambda api_name, api: self._LoadIdlAPI(api, True),
294 'idl-no-refs') 321 'idl-no-refs')
295 322
296 self._idl_names_cache = create_compiled_fs(self._GetIDLNames, 'idl-names') 323 self._idl_names_cache = create_compiled_fs(self._GetIDLNames, 'idl-names')
297 self._names_cache = create_compiled_fs(self._GetAllNames, 'names') 324 self._names_cache = create_compiled_fs(self._GetAllNames, 'names')
298 325
299 self._base_path = base_path 326 self._base_path = base_path
300 327 self._availability_data_source = availability_data_source_factory.Create()
301 # These must be set later via the SetFooDataSourceFactory methods. 328 # These must be set later via the SetFooDataSourceFactory methods.
302 self._ref_resolver_factory = None 329 self._ref_resolver_factory = None
303 self._samples_data_source_factory = None 330 self._samples_data_source_factory = None
304 331
305 def SetSamplesDataSourceFactory(self, samples_data_source_factory): 332 def SetSamplesDataSourceFactory(self, samples_data_source_factory):
306 self._samples_data_source_factory = samples_data_source_factory 333 self._samples_data_source_factory = samples_data_source_factory
307 334
308 def SetReferenceResolverFactory(self, ref_resolver_factory): 335 def SetReferenceResolverFactory(self, ref_resolver_factory):
309 self._ref_resolver_factory = ref_resolver_factory 336 self._ref_resolver_factory = ref_resolver_factory
310 337
(...skipping 25 matching lines...) Expand all
336 samples, 363 samples,
337 disable_refs) 364 disable_refs)
338 365
339 def _LoadPermissions(self, file_name, json_str): 366 def _LoadPermissions(self, file_name, json_str):
340 return json_parse.Parse(json_str) 367 return json_parse.Parse(json_str)
341 368
342 def _LoadJsonAPI(self, api, disable_refs): 369 def _LoadJsonAPI(self, api, disable_refs):
343 return _JSCModel( 370 return _JSCModel(
344 json_parse.Parse(api)[0], 371 json_parse.Parse(api)[0],
345 self._ref_resolver_factory.Create() if not disable_refs else None, 372 self._ref_resolver_factory.Create() if not disable_refs else None,
346 disable_refs).ToDict() 373 disable_refs,
374 self._availability_data_source).ToDict()
347 375
348 def _LoadIdlAPI(self, api, disable_refs): 376 def _LoadIdlAPI(self, api, disable_refs):
349 idl = idl_parser.IDLParser().ParseData(api) 377 idl = idl_parser.IDLParser().ParseData(api)
350 return _JSCModel( 378 return _JSCModel(
351 idl_schema.IDLSchema(idl).process()[0], 379 idl_schema.IDLSchema(idl).process()[0],
352 self._ref_resolver_factory.Create() if not disable_refs else None, 380 self._ref_resolver_factory.Create() if not disable_refs else None,
353 disable_refs).ToDict() 381 disable_refs,
382 self._availability_data_source).ToDict()
354 383
355 def _GetIDLNames(self, base_dir, apis): 384 def _GetIDLNames(self, base_dir, apis):
356 return self._GetExtNames(apis, ['idl']) 385 return self._GetExtNames(apis, ['idl'])
357 386
358 def _GetAllNames(self, base_dir, apis): 387 def _GetAllNames(self, base_dir, apis):
359 return self._GetExtNames(apis, ['json', 'idl']) 388 return self._GetExtNames(apis, ['json', 'idl'])
360 389
361 def _GetExtNames(self, apis, exts): 390 def _GetExtNames(self, apis, exts):
362 return [model.UnixName(os.path.splitext(api)[0]) for api in apis 391 return [model.UnixName(os.path.splitext(api)[0]) for api in apis
363 if os.path.splitext(api)[1][1:] in exts] 392 if os.path.splitext(api)[1][1:] in exts]
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 return feature_data 452 return feature_data
424 453
425 def _GenerateHandlebarContext(self, handlebar_dict, path): 454 def _GenerateHandlebarContext(self, handlebar_dict, path):
426 handlebar_dict['permissions'] = self._GetFeatureData(path) 455 handlebar_dict['permissions'] = self._GetFeatureData(path)
427 handlebar_dict['samples'] = _LazySamplesGetter(path, self._samples) 456 handlebar_dict['samples'] = _LazySamplesGetter(path, self._samples)
428 return handlebar_dict 457 return handlebar_dict
429 458
430 def _GetAsSubdirectory(self, name): 459 def _GetAsSubdirectory(self, name):
431 if name.startswith('experimental_'): 460 if name.startswith('experimental_'):
432 parts = name[len('experimental_'):].split('_', 1) 461 parts = name[len('experimental_'):].split('_', 1)
433 parts[1] = 'experimental_%s' % parts[1] 462 if len(parts) > 1:
434 return '/'.join(parts) 463 parts[1] = 'experimental_%s' % parts[1]
464 return '/'.join(parts)
465 else:
466 return '%s/%s' % (parts[0], name)
435 return name.replace('_', '/', 1) 467 return name.replace('_', '/', 1)
436 468
437 def get(self, key): 469 def _DetermineNamesForGet(self, key):
438 if key.endswith('.html') or key.endswith('.json') or key.endswith('.idl'): 470 if key.endswith('.html') or key.endswith('.json') or key.endswith('.idl'):
439 path, ext = os.path.splitext(key) 471 path, ext = os.path.splitext(key)
440 else: 472 else:
441 path = key 473 path = key
442 unix_name = model.UnixName(path) 474 unix_name = model.UnixName(path)
443 idl_names = self._idl_names_cache.GetFromFileListing(self._base_path)
444 names = self._names_cache.GetFromFileListing(self._base_path) 475 names = self._names_cache.GetFromFileListing(self._base_path)
445 if unix_name not in names and self._GetAsSubdirectory(unix_name) in names: 476 if unix_name not in names and self._GetAsSubdirectory(unix_name) in names:
446 unix_name = self._GetAsSubdirectory(unix_name) 477 unix_name = self._GetAsSubdirectory(unix_name)
478 return (path, unix_name)
447 479
480 def _DetermineCacheForGet(self, unix_name):
481 idl_names = self._idl_names_cache.GetFromFileListing(self._base_path)
448 if self._disable_refs: 482 if self._disable_refs:
449 cache, ext = ( 483 cache, ext = (
450 (self._idl_cache_no_refs, '.idl') if (unix_name in idl_names) else 484 (self._idl_cache_no_refs, '.idl') if (unix_name in idl_names) else
451 (self._json_cache_no_refs, '.json')) 485 (self._json_cache_no_refs, '.json'))
452 else: 486 else:
453 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else 487 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else
454 (self._json_cache, '.json')) 488 (self._json_cache, '.json'))
489 return (cache, ext)
490
491 def get(self, key):
492 path, unix_name = self._DetermineNamesForGet(key)
493 cache, ext = self._DetermineCacheForGet(unix_name)
455 return self._GenerateHandlebarContext( 494 return self._GenerateHandlebarContext(
456 cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)), 495 cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)),
457 path) 496 path)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698