api_data_source.py revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import copy 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import json 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import logging 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import compiled_file_system as compiled_fs 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from file_system import FileNotFoundError 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import third_party.json_schema_compiler.json_comment_eater as json_comment_eater 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import third_party.json_schema_compiler.model as model 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import third_party.json_schema_compiler.idl_schema as idl_schema 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import third_party.json_schema_compiler.idl_parser as idl_parser 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Increment this version when there are changes to the data stored in any of 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the caches used by APIDataSource. This allows the cache to be invalidated 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# without having to flush memcache on the production server. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_VERSION = 3 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _RemoveNoDocs(item): 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if type(item) == dict: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if item.get('nodoc', False): 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_remove = [] 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for key, value in item.items(): 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if _RemoveNoDocs(value): 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_remove.append(key) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for k in to_remove: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del item[k] 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif type(item) == list: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_remove = [] 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in item: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if _RemoveNoDocs(i): 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) to_remove.append(i) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for i in to_remove: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item.remove(i) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _CreateId(node, prefix): 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if node.parent is not None and not isinstance(node.parent, model.Namespace): 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '-'.join([prefix, node.parent.simple_name, node.simple_name]) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '-'.join([prefix, node.simple_name]) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _FormatValue(value): 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Inserts commas every three digits for integer values. It is magic. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s = str(value) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class _JSCModel(object): 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Uses a Model from the JSON Schema Compiler and generates a dict that 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a Handlebar template can use for a data source. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, json, ref_resolver, disable_refs): 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver = ref_resolver 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._disable_refs = disable_refs 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clean_json = copy.deepcopy(json) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if _RemoveNoDocs(clean_json): 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._namespace = None 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._namespace = model.Namespace(clean_json, clean_json['namespace']) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GetLink(self, ref): 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self._disable_refs: 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_data = self._ref_resolver.GetLink(self._namespace.name, ref) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ref_data is not None: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ref_data 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.error('$ref %s could not be resolved.' % ref) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if '.' in ref: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_name = ref.rsplit('.', 1)[-1] 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_name = ref 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return { 'href': '#type-%s' % type_name, 'text': ref } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _FormatDescription(self, description): 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if description is None or '$ref:' not in description: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) refs = description.split('$ref:') 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatted_description = [refs[0]] 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ref in refs[1:]: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parts = ref.split(' ', 1) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(parts) == 1: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref = parts[0] 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rest = '' 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref, rest = parts 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rest = ' ' + rest 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not ref[-1].isalnum(): 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rest = ref[-1] + rest 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref = ref[:-1] 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ref_dict = self._GetLink(ref) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatted_description.append('<a href="%(href)s">%(text)s</a>%(rest)s' % 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 'href': ref_dict['href'], 'text': ref_dict['text'], 'rest': rest }) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ''.join(formatted_description) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def ToDict(self): 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._namespace is None: 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return {} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': self._namespace.name, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'types': [self._GenerateType(t) for t in self._namespace.types.values() 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if t.type_ != model.PropertyType.ADDITIONAL_PROPERTIES], 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'functions': self._GenerateFunctions(self._namespace.functions), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'events': self._GenerateEvents(self._namespace.events), 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'properties': self._GenerateProperties(self._namespace.properties) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateType(self, type_): 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_dict = { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': type_.simple_name, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(type_.description), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'properties': self._GenerateProperties(type_.properties), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'functions': self._GenerateFunctions(type_.functions), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'events': self._GenerateEvents(type_.events), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id': _CreateId(type_, 'type') 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._RenderTypeInformation(type_, type_dict) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type_dict 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateFunctions(self, functions): 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [self._GenerateFunction(f) for f in functions.values()] 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateFunction(self, function): 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict = { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': function.simple_name, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(function.description), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'callback': self._GenerateCallback(function.callback), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'parameters': [], 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'returns': None, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id': _CreateId(function, 'method') 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (function.parent is not None and 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) not isinstance(function.parent, model.Namespace)): 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['parent_name'] = function.parent.simple_name 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['parent_name'] = None 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if function.returns: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['returns'] = self._GenerateProperty(function.returns) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for param in function.params: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['parameters'].append(self._GenerateProperty(param)) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if function_dict['callback']: 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['parameters'].append(function_dict['callback']) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(function_dict['parameters']) > 0: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) function_dict['parameters'][-1]['last'] = True 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return function_dict 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateEvents(self, events): 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [self._GenerateEvent(e) for e in events.values()] 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateEvent(self, event): 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dict = { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': event.simple_name, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(event.description), 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'parameters': [self._GenerateProperty(p) for p in event.params], 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'callback': self._GenerateCallback(event.callback), 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'filters': [self._GenerateProperty(f) for f in event.filters], 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'conditions': [self._GetLink(condition) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for condition in event.conditions], 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'actions': [self._GetLink(action) for action in event.actions], 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'supportsRules': event.supports_rules, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id': _CreateId(event, 'event') 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event.parent is not None and 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) not isinstance(event.parent, model.Namespace)): 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dict['parent_name'] = event.parent.simple_name 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dict['parent_name'] = None 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if event_dict['callback']: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dict['parameters'].append(event_dict['callback']) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(event_dict['parameters']) > 0: 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event_dict['parameters'][-1]['last'] = True 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return event_dict 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateCallback(self, callback): 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not callback: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_dict = { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': callback.simple_name, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(callback.description), 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'simple_type': {'simple_type': 'function'}, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'optional': callback.optional, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'parameters': [] 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for param in callback.params: 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_dict['parameters'].append(self._GenerateProperty(param)) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len(callback_dict['parameters']) > 0): 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_dict['parameters'][-1]['last'] = True 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return callback_dict 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateProperties(self, properties): 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [self._GenerateProperty(v) for v in properties.values() 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if v.type_ != model.PropertyType.ADDITIONAL_PROPERTIES] 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateProperty(self, property_): 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict = { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'name': property_.simple_name, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'optional': property_.optional, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'description': self._FormatDescription(property_.description), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'properties': self._GenerateProperties(property_.properties), 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'functions': self._GenerateFunctions(property_.functions), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'parameters': [], 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'returns': None, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'id': _CreateId(property_, 'property') 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for param in property_.params: 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict['parameters'].append(self._GenerateProperty(param)) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if property_.returns: 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict['returns'] = self._GenerateProperty(property_.returns) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (property_.parent is not None and 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) not isinstance(property_.parent, model.Namespace)): 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict['parent_name'] = property_.parent.simple_name 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict['parent_name'] = None 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if property_.has_value: 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if isinstance(property_.value, int): 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict['value'] = _FormatValue(property_.value) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_dict['value'] = property_.value 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._RenderTypeInformation(property_, property_dict) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return property_dict 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _RenderTypeInformation(self, property_, dst_dict): 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if property_.type_ == model.PropertyType.CHOICES: 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['choices'] = [self._GenerateProperty(c) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for c in property_.choices.values()] 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # We keep track of which is last for knowing when to add "or" between 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # choices in templates. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(dst_dict['choices']) > 0: 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['choices'][-1]['last'] = True 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif property_.type_ == model.PropertyType.REF: 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['link'] = self._GetLink(property_.ref_type) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif property_.type_ == model.PropertyType.ARRAY: 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['array'] = self._GenerateProperty(property_.item_type) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif property_.type_ == model.PropertyType.ENUM: 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['enum_values'] = [] 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for enum_value in property_.enum_values: 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['enum_values'].append({'name': enum_value}) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(dst_dict['enum_values']) > 0: 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['enum_values'][-1]['last'] = True 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) elif property_.instance_of is not None: 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['simple_type'] = property_.instance_of.lower() 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dst_dict['simple_type'] = property_.type_.name.lower() 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class _LazySamplesGetter(object): 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This class is needed so that an extensions API page does not have to fetch 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) the apps samples page and vice versa. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, api_name, samples): 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._api_name = api_name 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples = samples 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get(self, key): 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._samples.FilterSamples(key, self._api_name) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class APIDataSource(object): 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This class fetches and loads JSON APIs from the FileSystem passed in with 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) |cache_factory|, so the APIs can be plugged into templates. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Factory(object): 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache_factory, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_path): 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._permissions_cache = cache_factory.Create(self._LoadPermissions, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiled_fs.PERMS, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version=_VERSION) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._json_cache = cache_factory.Create( 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lambda api: self._LoadJsonAPI(api, False), 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiled_fs.JSON, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version=_VERSION) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_cache = cache_factory.Create( 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lambda api: self._LoadIdlAPI(api, False), 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiled_fs.IDL, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version=_VERSION) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # These caches are used if an APIDataSource does not want to resolve the 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # $refs in an API. This is needed to prevent infinite recursion in 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # ReferenceResolver. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._json_cache_no_refs = cache_factory.Create( 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lambda api: self._LoadJsonAPI(api, True), 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiled_fs.JSON_NO_REFS, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version=_VERSION) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_cache_no_refs = cache_factory.Create( 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lambda api: self._LoadIdlAPI(api, True), 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiled_fs.IDL_NO_REFS, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version=_VERSION) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_names_cache = cache_factory.Create(self._GetIDLNames, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiled_fs.IDL_NAMES, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version=_VERSION) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._names_cache = cache_factory.Create(self._GetAllNames, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compiled_fs.NAMES, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) version=_VERSION) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._base_path = base_path 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # These must be set later via the SetFooDataSourceFactory methods. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver_factory = None 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples_data_source_factory = None 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def SetSamplesDataSourceFactory(self, samples_data_source_factory): 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples_data_source_factory = samples_data_source_factory 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def SetReferenceResolverFactory(self, ref_resolver_factory): 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver_factory = ref_resolver_factory 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def Create(self, request, disable_refs=False): 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Create an APIDataSource. |disable_refs| specifies whether $ref's in 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) APIs being processed by the |ToDict| method of _JSCModel follows $ref's 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in the API. This prevents endless recursion in ReferenceResolver. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """ 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._samples_data_source_factory is None: 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Only error if there is a request, which means this APIDataSource is 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # actually being used to render a page. 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if request is not None: 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.error('SamplesDataSource.Factory was never set in ' 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'APIDataSource.Factory.') 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples = None 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples = self._samples_data_source_factory.Create(request) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not disable_refs and self._ref_resolver_factory is None: 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging.error('ReferenceResolver.Factory was never set in ' 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'APIDataSource.Factory.') 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return APIDataSource(self._permissions_cache, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._json_cache, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_cache, 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._json_cache_no_refs, 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_cache_no_refs, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._names_cache, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_names_cache, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._base_path, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples, 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disable_refs) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _LoadPermissions(self, json_str): 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return json.loads(json_comment_eater.Nom(json_str)) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _LoadJsonAPI(self, api, disable_refs): 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return _JSCModel( 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) json.loads(json_comment_eater.Nom(api))[0], 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver_factory.Create() if not disable_refs else None, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disable_refs).ToDict() 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _LoadIdlAPI(self, api, disable_refs): 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idl = idl_parser.IDLParser().ParseData(api) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return _JSCModel( 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idl_schema.IDLSchema(idl).process()[0], 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._ref_resolver_factory.Create() if not disable_refs else None, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disable_refs).ToDict() 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GetIDLNames(self, apis): 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [ 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.UnixName(os.path.splitext(api[len('%s/' % self._base_path):])[0]) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for api in apis if api.endswith('.idl') 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ] 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GetAllNames(self, apis): 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [ 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) model.UnixName(os.path.splitext(api[len('%s/' % self._base_path):])[0]) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for api in apis 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ] 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) permissions_cache, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) json_cache, 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idl_cache, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) json_cache_no_refs, 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idl_cache_no_refs, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names_cache, 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idl_names_cache, 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_path, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples, 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disable_refs): 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._base_path = base_path 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._permissions_cache = permissions_cache 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._json_cache = json_cache 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_cache = idl_cache 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._json_cache_no_refs = json_cache_no_refs 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_cache_no_refs = idl_cache_no_refs 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._names_cache = names_cache 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._idl_names_cache = idl_names_cache 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._samples = samples 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._disable_refs = disable_refs 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GetPermsFromFile(self, filename): 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) perms = self._permissions_cache.GetFromFile('%s/%s' % 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (self._base_path, filename)) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict((model.UnixName(k), v) for k, v in perms.iteritems()) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except FileNotFoundError: 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return {} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GetFeature(self, path): 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Remove 'experimental_' from path name to match the keys in 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # _permissions_features.json. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = model.UnixName(path.replace('experimental_', '')) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for filename in ['_permission_features.json', '_manifest_features.json']: 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) api_perms = self._GetPermsFromFile(filename).get(path, None) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if api_perms is not None: 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if api_perms and api_perms['channel'] in ('trunk', 'dev', 'beta'): 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) api_perms[api_perms['channel']] = True 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return api_perms 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GenerateHandlebarContext(self, handlebar_dict, path): 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_dict = { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'permissions': self._GetFeature(path), 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'samples': _LazySamplesGetter(path, self._samples) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return_dict.update(handlebar_dict) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return return_dict 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _GetAsSubdirectory(self, name): 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if name.startswith('experimental_'): 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parts = name[len('experimental_'):].split('_', 1) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parts[1] = 'experimental_%s' % parts[1] 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '/'.join(parts) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return name.replace('_', '/', 1) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def get(self, key): 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if key.endswith('.html') or key.endswith('.json') or key.endswith('.idl'): 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path, ext = os.path.splitext(key) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = key 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unix_name = model.UnixName(path) 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idl_names = self._idl_names_cache.GetFromFileListing(self._base_path) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) names = self._names_cache.GetFromFileListing(self._base_path) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if unix_name not in names and self._GetAsSubdirectory(unix_name) in names: 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unix_name = self._GetAsSubdirectory(unix_name) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self._disable_refs: 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache, ext = ( 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (self._idl_cache_no_refs, '.idl') if (unix_name in idl_names) else 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (self._json_cache_no_refs, '.json')) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (self._json_cache, '.json')) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self._GenerateHandlebarContext( 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)), 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path) 442