Chromium Code Reviews| OLD | NEW | 
|---|---|
| 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 json | 6 import json | 
| 7 import logging | |
| 7 import os | 8 import os | 
| 8 | 9 | 
| 9 from docs_server_utils import GetLinkToRefType | 10 from docs_server_utils import GetLinkToRefType | 
| 10 import compiled_file_system as compiled_fs | 11 import compiled_file_system as compiled_fs | 
| 11 from file_system import FileNotFoundError | 12 from file_system import FileNotFoundError | 
| 12 import third_party.json_schema_compiler.json_comment_eater as json_comment_eater | 13 import third_party.json_schema_compiler.json_comment_eater as json_comment_eater | 
| 13 import third_party.json_schema_compiler.model as model | 14 import third_party.json_schema_compiler.model as model | 
| 14 import third_party.json_schema_compiler.idl_schema as idl_schema | 15 import third_party.json_schema_compiler.idl_schema as idl_schema | 
| 15 import third_party.json_schema_compiler.idl_parser as idl_parser | 16 import third_party.json_schema_compiler.idl_parser as idl_parser | 
| 16 | 17 | 
| 17 # Increment this version when there are changes to the data stored in any of | 18 # Increment this version when there are changes to the data stored in any of | 
| 18 # the caches used by APIDataSource. This allows the cache to be invalidated | 19 # the caches used by APIDataSource. This allows the cache to be invalidated | 
| 19 # without having to flush memcache on the production server. | 20 # without having to flush memcache on the production server. | 
| 20 _VERSION = 2 | 21 _VERSION = 3 | 
| 21 | 22 | 
| 22 def _RemoveNoDocs(item): | 23 def _RemoveNoDocs(item): | 
| 23 if type(item) == dict: | 24 if type(item) == dict: | 
| 24 if item.get('nodoc', False): | 25 if item.get('nodoc', False): | 
| 25 return True | 26 return True | 
| 26 to_remove = [] | 27 to_remove = [] | 
| 27 for key, value in item.items(): | 28 for key, value in item.items(): | 
| 28 if _RemoveNoDocs(value): | 29 if _RemoveNoDocs(value): | 
| 29 to_remove.append(key) | 30 to_remove.append(key) | 
| 30 for k in to_remove: | 31 for k in to_remove: | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 42 if node.parent is not None and not isinstance(node.parent, model.Namespace): | 43 if node.parent is not None and not isinstance(node.parent, model.Namespace): | 
| 43 return '-'.join([prefix, node.parent.simple_name, node.simple_name]) | 44 return '-'.join([prefix, node.parent.simple_name, node.simple_name]) | 
| 44 return '-'.join([prefix, node.simple_name]) | 45 return '-'.join([prefix, node.simple_name]) | 
| 45 | 46 | 
| 46 def _FormatValue(value): | 47 def _FormatValue(value): | 
| 47 """Inserts commas every three digits for integer values. It is magic. | 48 """Inserts commas every three digits for integer values. It is magic. | 
| 48 """ | 49 """ | 
| 49 s = str(value) | 50 s = str(value) | 
| 50 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) | 51 return ','.join([s[max(0, i - 3):i] for i in range(len(s), 0, -3)][::-1]) | 
| 51 | 52 | 
| 52 class _JscModel(object): | 53 class _JSCModel(object): | 
| 53 """Uses a Model from the JSON Schema Compiler and generates a dict that | 54 """Uses a Model from the JSON Schema Compiler and generates a dict that | 
| 54 a Handlebar template can use for a data source. | 55 a Handlebar template can use for a data source. | 
| 55 """ | 56 """ | 
| 56 def __init__(self, json): | 57 def __init__(self, json, api_data_source, api_list_data_source): | 
| 58 self._api_data_source = api_data_source | |
| 59 self._api_list = api_list_data_source.GetAllNames() | |
| 
 
not at google - send to devlin
2012/11/01 22:00:49
These JSCModel objects are pickled, right? That's
 
cduvall
2012/11/02 01:53:53
Done.
 
 | |
| 57 clean_json = copy.deepcopy(json) | 60 clean_json = copy.deepcopy(json) | 
| 58 if _RemoveNoDocs(clean_json): | 61 if _RemoveNoDocs(clean_json): | 
| 59 self._namespace = None | 62 self._namespace = None | 
| 60 else: | 63 else: | 
| 61 self._namespace = model.Namespace(clean_json, clean_json['namespace']) | 64 self._namespace = model.Namespace(clean_json, clean_json['namespace']) | 
| 62 | 65 | 
| 63 def _FormatDescription(self, description): | 66 def _GetLinkToRefType(self, ref): | 
| 64 if description is None or '$ref:' not in description: | 67 ref_data = GetLinkToRefType(self._namespace.name, | 
| 68 ref, | |
| 69 self._api_data_source, | |
| 70 self._api_list) | |
| 71 if ref_data is None: | |
| 72 logging.error('$ref %s could not be resolved.' % ref) | |
| 73 if '.' in ref: | |
| 74 type_name = ref.rsplit('.', 1)[-1] | |
| 75 else: | |
| 76 type_name = ref | |
| 77 return { 'href': '#type-%s' % type_name, 'text': ref } | |
| 78 return ref_data | |
| 79 | |
| 80 def _FormatDescription(self, description, resolve_refs): | |
| 81 if description is None or '$ref:' not in description or not resolve_refs: | |
| 65 return description | 82 return description | 
| 66 refs = description.split('$ref:') | 83 refs = description.split('$ref:') | 
| 67 formatted_description = [refs[0]] | 84 formatted_description = [refs[0]] | 
| 68 for ref in refs[1:]: | 85 for ref in refs[1:]: | 
| 69 parts = ref.split(' ', 1) | 86 parts = ref.split(' ', 1) | 
| 70 if len(parts) == 1: | 87 if len(parts) == 1: | 
| 71 ref = parts[0] | 88 ref = parts[0] | 
| 72 rest = '' | 89 rest = '' | 
| 73 else: | 90 else: | 
| 74 ref, rest = parts | 91 ref, rest = parts | 
| 75 rest = ' ' + rest | 92 rest = ' ' + rest | 
| 76 if not ref[-1].isalnum(): | 93 if not ref[-1].isalnum(): | 
| 77 rest = ref[-1] + rest | 94 rest = ref[-1] + rest | 
| 78 ref = ref[:-1] | 95 ref = ref[:-1] | 
| 79 ref_dict = GetLinkToRefType(self._namespace.name, ref) | 96 ref_dict = self._GetLinkToRefType(ref) | 
| 80 formatted_description.append('<a href="%(href)s">%(text)s</a>%(rest)s' % | 97 formatted_description.append('<a href="%(href)s">%(text)s</a>%(rest)s' % | 
| 81 { 'href': ref_dict['href'], 'text': ref_dict['text'], 'rest': rest }) | 98 { 'href': ref_dict['href'], 'text': ref_dict['text'], 'rest': rest }) | 
| 82 return ''.join(formatted_description) | 99 return ''.join(formatted_description) | 
| 83 | 100 | 
| 84 def ToDict(self): | 101 def ToDict(self, resolve_refs): | 
| 85 if self._namespace is None: | 102 if self._namespace is None: | 
| 86 return {} | 103 return {} | 
| 87 return { | 104 return { | 
| 88 'name': self._namespace.name, | 105 'name': self._namespace.name, | 
| 89 'types': [self._GenerateType(t) for t in self._namespace.types.values() | 106 'types': [self._GenerateType(t, resolve_refs) | 
| 107 for t in self._namespace.types.values() | |
| 90 if t.type_ != model.PropertyType.ADDITIONAL_PROPERTIES], | 108 if t.type_ != model.PropertyType.ADDITIONAL_PROPERTIES], | 
| 91 'functions': self._GenerateFunctions(self._namespace.functions), | 109 'functions': self._GenerateFunctions(self._namespace.functions, | 
| 92 'events': self._GenerateEvents(self._namespace.events), | 110 resolve_refs), | 
| 93 'properties': self._GenerateProperties(self._namespace.properties) | 111 'events': self._GenerateEvents(self._namespace.events, resolve_refs), | 
| 112 'properties': self._GenerateProperties(self._namespace.properties, | |
| 113 resolve_refs) | |
| 94 } | 114 } | 
| 95 | 115 | 
| 96 def _GenerateType(self, type_): | 116 def _GenerateType(self, type_, resolve_refs): | 
| 97 type_dict = { | 117 type_dict = { | 
| 98 'name': type_.simple_name, | 118 'name': type_.simple_name, | 
| 99 'description': self._FormatDescription(type_.description), | 119 'description': self._FormatDescription(type_.description, resolve_refs), | 
| 100 'properties': self._GenerateProperties(type_.properties), | 120 'properties': self._GenerateProperties(type_.properties, resolve_refs), | 
| 101 'functions': self._GenerateFunctions(type_.functions), | 121 'functions': self._GenerateFunctions(type_.functions, resolve_refs), | 
| 102 'events': self._GenerateEvents(type_.events), | 122 'events': self._GenerateEvents(type_.events, resolve_refs), | 
| 103 'id': _CreateId(type_, 'type') | 123 'id': _CreateId(type_, 'type') | 
| 104 } | 124 } | 
| 105 self._RenderTypeInformation(type_, type_dict) | 125 self._RenderTypeInformation(type_, type_dict, resolve_refs) | 
| 106 return type_dict | 126 return type_dict | 
| 107 | 127 | 
| 108 def _GenerateFunctions(self, functions): | 128 def _GenerateFunctions(self, functions, resolve_refs): | 
| 109 return [self._GenerateFunction(f) for f in functions.values()] | 129 return [self._GenerateFunction(f, resolve_refs) for f in functions.values()] | 
| 110 | 130 | 
| 111 def _GenerateFunction(self, function): | 131 def _GenerateFunction(self, function, resolve_refs): | 
| 112 function_dict = { | 132 function_dict = { | 
| 113 'name': function.simple_name, | 133 'name': function.simple_name, | 
| 114 'description': self._FormatDescription(function.description), | 134 'description': self._FormatDescription(function.description, | 
| 115 'callback': self._GenerateCallback(function.callback), | 135 resolve_refs), | 
| 136 'callback': self._GenerateCallback(function.callback, resolve_refs), | |
| 116 'parameters': [], | 137 'parameters': [], | 
| 117 'returns': None, | 138 'returns': None, | 
| 118 'id': _CreateId(function, 'method') | 139 'id': _CreateId(function, 'method') | 
| 119 } | 140 } | 
| 120 if (function.parent is not None and | 141 if (function.parent is not None and | 
| 121 not isinstance(function.parent, model.Namespace)): | 142 not isinstance(function.parent, model.Namespace)): | 
| 122 function_dict['parent_name'] = function.parent.simple_name | 143 function_dict['parent_name'] = function.parent.simple_name | 
| 123 else: | 144 else: | 
| 124 function_dict['parent_name'] = None | 145 function_dict['parent_name'] = None | 
| 125 if function.returns: | 146 if function.returns: | 
| 126 function_dict['returns'] = self._GenerateProperty(function.returns) | 147 function_dict['returns'] = self._GenerateProperty(function.returns, | 
| 148 resolve_refs) | |
| 127 for param in function.params: | 149 for param in function.params: | 
| 128 function_dict['parameters'].append(self._GenerateProperty(param)) | 150 function_dict['parameters'].append(self._GenerateProperty(param, | 
| 151 resolve_refs)) | |
| 129 if function_dict['callback']: | 152 if function_dict['callback']: | 
| 130 function_dict['parameters'].append(function_dict['callback']) | 153 function_dict['parameters'].append(function_dict['callback']) | 
| 131 if len(function_dict['parameters']) > 0: | 154 if len(function_dict['parameters']) > 0: | 
| 132 function_dict['parameters'][-1]['last'] = True | 155 function_dict['parameters'][-1]['last'] = True | 
| 133 return function_dict | 156 return function_dict | 
| 134 | 157 | 
| 135 def _GenerateEvents(self, events): | 158 def _GenerateEvents(self, events, resolve_refs): | 
| 136 return [self._GenerateEvent(e) for e in events.values()] | 159 return [self._GenerateEvent(e, resolve_refs) for e in events.values()] | 
| 137 | 160 | 
| 138 def _GenerateEvent(self, event): | 161 def _GenerateEvent(self, event, resolve_refs): | 
| 139 event_dict = { | 162 event_dict = { | 
| 140 'name': event.simple_name, | 163 'name': event.simple_name, | 
| 141 'description': self._FormatDescription(event.description), | 164 'description': self._FormatDescription(event.description, | 
| 142 'parameters': map(self._GenerateProperty, event.params), | 165 resolve_refs), | 
| 143 'callback': self._GenerateCallback(event.callback), | 166 'parameters': [self._GenerateProperty(p, resolve_refs) | 
| 144 'conditions': [GetLinkToRefType(self._namespace.name, c) | 167 for p in event.params], | 
| 145 for c in event.conditions], | 168 'callback': self._GenerateCallback(event.callback, resolve_refs), | 
| 146 'actions': [GetLinkToRefType(self._namespace.name, a) | 169 'filters': [self._GenerateProperty(f, resolve_refs) | 
| 147 for a in event.actions], | 170 for f in event.filters], | 
| 148 'filters': map(self._GenerateProperty, event.filters), | |
| 149 'supportsRules': event.supports_rules, | 171 'supportsRules': event.supports_rules, | 
| 150 'id': _CreateId(event, 'event') | 172 'id': _CreateId(event, 'event') | 
| 151 } | 173 } | 
| 174 if resolve_refs: | |
| 175 event_dict['conditions'] = [self._GetLinkToRefType(condition) | |
| 176 for condition in event.conditions] | |
| 177 event_dict['actions'] = [self._GetLinkToRefType(action) | |
| 178 for action in event.actions] | |
| 152 if (event.parent is not None and | 179 if (event.parent is not None and | 
| 153 not isinstance(event.parent, model.Namespace)): | 180 not isinstance(event.parent, model.Namespace)): | 
| 154 event_dict['parent_name'] = event.parent.simple_name | 181 event_dict['parent_name'] = event.parent.simple_name | 
| 155 else: | 182 else: | 
| 156 event_dict['parent_name'] = None | 183 event_dict['parent_name'] = None | 
| 157 if event_dict['callback']: | 184 if event_dict['callback']: | 
| 158 event_dict['parameters'].append(event_dict['callback']) | 185 event_dict['parameters'].append(event_dict['callback']) | 
| 159 if len(event_dict['parameters']) > 0: | 186 if len(event_dict['parameters']) > 0: | 
| 160 event_dict['parameters'][-1]['last'] = True | 187 event_dict['parameters'][-1]['last'] = True | 
| 161 return event_dict | 188 return event_dict | 
| 162 | 189 | 
| 163 def _GenerateCallback(self, callback): | 190 def _GenerateCallback(self, callback, resolve_refs): | 
| 164 if not callback: | 191 if not callback: | 
| 165 return None | 192 return None | 
| 166 callback_dict = { | 193 callback_dict = { | 
| 167 'name': callback.simple_name, | 194 'name': callback.simple_name, | 
| 168 'description': self._FormatDescription(callback.description), | 195 'description': self._FormatDescription(callback.description, | 
| 196 resolve_refs), | |
| 169 'simple_type': {'simple_type': 'function'}, | 197 'simple_type': {'simple_type': 'function'}, | 
| 170 'optional': callback.optional, | 198 'optional': callback.optional, | 
| 171 'parameters': [] | 199 'parameters': [] | 
| 172 } | 200 } | 
| 173 for param in callback.params: | 201 for param in callback.params: | 
| 174 callback_dict['parameters'].append(self._GenerateProperty(param)) | 202 callback_dict['parameters'].append( | 
| 203 self._GenerateProperty(param, resolve_refs)) | |
| 175 if (len(callback_dict['parameters']) > 0): | 204 if (len(callback_dict['parameters']) > 0): | 
| 176 callback_dict['parameters'][-1]['last'] = True | 205 callback_dict['parameters'][-1]['last'] = True | 
| 177 return callback_dict | 206 return callback_dict | 
| 178 | 207 | 
| 179 def _GenerateProperties(self, properties): | 208 def _GenerateProperties(self, properties, resolve_refs): | 
| 180 return [self._GenerateProperty(v) for v in properties.values() | 209 return [self._GenerateProperty(v, resolve_refs) for v in properties.values() | 
| 181 if v.type_ != model.PropertyType.ADDITIONAL_PROPERTIES] | 210 if v.type_ != model.PropertyType.ADDITIONAL_PROPERTIES] | 
| 182 | 211 | 
| 183 def _GenerateProperty(self, property_): | 212 def _GenerateProperty(self, property_, resolve_refs): | 
| 184 property_dict = { | 213 property_dict = { | 
| 185 'name': property_.simple_name, | 214 'name': property_.simple_name, | 
| 186 'optional': property_.optional, | 215 'optional': property_.optional, | 
| 187 'description': self._FormatDescription(property_.description), | 216 'description': self._FormatDescription(property_.description, | 
| 188 'properties': self._GenerateProperties(property_.properties), | 217 resolve_refs), | 
| 218 'properties': self._GenerateProperties(property_.properties, | |
| 219 resolve_refs), | |
| 220 'functions': self._GenerateFunctions(property_.functions, resolve_refs), | |
| 189 'parameters': [], | 221 'parameters': [], | 
| 190 'functions': self._GenerateFunctions(property_.functions), | |
| 191 'returns': None, | 222 'returns': None, | 
| 192 'id': _CreateId(property_, 'property') | 223 'id': _CreateId(property_, 'property') | 
| 193 } | 224 } | 
| 194 for param in property_.params: | 225 for param in property_.params: | 
| 195 property_dict['parameters'].append(self._GenerateProperty(param)) | 226 property_dict['parameters'].append(self._GenerateProperty(param, | 
| 227 resolve_refs)) | |
| 196 if property_.returns: | 228 if property_.returns: | 
| 197 property_dict['returns'] = self._GenerateProperty(property_.returns) | 229 property_dict['returns'] = self._GenerateProperty(property_.returns) | 
| 198 if (property_.parent is not None and | 230 if (property_.parent is not None and | 
| 199 not isinstance(property_.parent, model.Namespace)): | 231 not isinstance(property_.parent, model.Namespace)): | 
| 200 property_dict['parent_name'] = property_.parent.simple_name | 232 property_dict['parent_name'] = property_.parent.simple_name | 
| 201 else: | 233 else: | 
| 202 property_dict['parent_name'] = None | 234 property_dict['parent_name'] = None | 
| 203 if property_.has_value: | 235 if property_.has_value: | 
| 204 if isinstance(property_.value, int): | 236 if isinstance(property_.value, int): | 
| 205 property_dict['value'] = _FormatValue(property_.value) | 237 property_dict['value'] = _FormatValue(property_.value) | 
| 206 else: | 238 else: | 
| 207 property_dict['value'] = property_.value | 239 property_dict['value'] = property_.value | 
| 208 else: | 240 else: | 
| 209 self._RenderTypeInformation(property_, property_dict) | 241 self._RenderTypeInformation(property_, property_dict, resolve_refs) | 
| 210 return property_dict | 242 return property_dict | 
| 211 | 243 | 
| 212 def _RenderTypeInformation(self, property_, dst_dict): | 244 def _RenderTypeInformation(self, property_, dst_dict, resolve_refs): | 
| 213 if property_.type_ == model.PropertyType.CHOICES: | 245 if property_.type_ == model.PropertyType.CHOICES: | 
| 214 dst_dict['choices'] = map(self._GenerateProperty, | 246 dst_dict['choices'] = [self._GenerateProperty(c, resolve_refs) | 
| 215 property_.choices.values()) | 247 for c in property_.choices.values()] | 
| 216 # We keep track of which is last for knowing when to add "or" between | 248 # We keep track of which is last for knowing when to add "or" between | 
| 217 # choices in templates. | 249 # choices in templates. | 
| 218 if len(dst_dict['choices']) > 0: | 250 if len(dst_dict['choices']) > 0: | 
| 219 dst_dict['choices'][-1]['last'] = True | 251 dst_dict['choices'][-1]['last'] = True | 
| 220 elif property_.type_ == model.PropertyType.REF: | 252 elif property_.type_ == model.PropertyType.REF: | 
| 221 dst_dict['link'] = GetLinkToRefType(self._namespace.name, | 253 if resolve_refs: | 
| 222 property_.ref_type) | 254 dst_dict['link'] = self._GetLinkToRefType(property_.ref_type) | 
| 223 elif property_.type_ == model.PropertyType.ARRAY: | 255 elif property_.type_ == model.PropertyType.ARRAY: | 
| 224 dst_dict['array'] = self._GenerateProperty(property_.item_type) | 256 dst_dict['array'] = self._GenerateProperty(property_.item_type, | 
| 257 resolve_refs) | |
| 225 elif property_.type_ == model.PropertyType.ENUM: | 258 elif property_.type_ == model.PropertyType.ENUM: | 
| 226 dst_dict['enum_values'] = [] | 259 dst_dict['enum_values'] = [] | 
| 227 for enum_value in property_.enum_values: | 260 for enum_value in property_.enum_values: | 
| 228 dst_dict['enum_values'].append({'name': enum_value}) | 261 dst_dict['enum_values'].append({'name': enum_value}) | 
| 229 if len(dst_dict['enum_values']) > 0: | 262 if len(dst_dict['enum_values']) > 0: | 
| 230 dst_dict['enum_values'][-1]['last'] = True | 263 dst_dict['enum_values'][-1]['last'] = True | 
| 231 elif property_.instance_of is not None: | 264 elif property_.instance_of is not None: | 
| 232 dst_dict['simple_type'] = property_.instance_of.lower() | 265 dst_dict['simple_type'] = property_.instance_of.lower() | 
| 233 else: | 266 else: | 
| 234 dst_dict['simple_type'] = property_.type_.name.lower() | 267 dst_dict['simple_type'] = property_.type_.name.lower() | 
| 235 | 268 | 
| 236 class _LazySamplesGetter(object): | 269 class _LazySamplesGetter(object): | 
| 237 """This class is needed so that an extensions API page does not have to fetch | 270 """This class is needed so that an extensions API page does not have to fetch | 
| 238 the apps samples page and vice versa. | 271 the apps samples page and vice versa. | 
| 239 """ | 272 """ | 
| 240 def __init__(self, api_name, samples): | 273 def __init__(self, api_name, samples): | 
| 241 self._api_name = api_name | 274 self._api_name = api_name | 
| 242 self._samples = samples | 275 self._samples = samples | 
| 243 | 276 | 
| 244 def get(self, key): | 277 def get(self, key): | 
| 245 return self._samples.FilterSamples(key, self._api_name) | 278 return self._samples.FilterSamples(key, self._api_name) | 
| 246 | 279 | 
| 247 class APIDataSource(object): | 280 class APIDataSource(object): | 
| 248 """This class fetches and loads JSON APIs from the FileSystem passed in with | 281 """This class fetches and loads JSON APIs from the FileSystem passed in with | 
| 249 |cache_factory|, so the APIs can be plugged into templates. | 282 |cache_factory|, so the APIs can be plugged into templates. | 
| 250 """ | 283 """ | 
| 251 class Factory(object): | 284 class Factory(object): | 
| 252 def __init__(self, cache_factory, base_path, samples_factory): | 285 def __init__(self, | 
| 286 cache_factory, | |
| 287 base_path, | |
| 288 api_list_data_source): | |
| 253 self._permissions_cache = cache_factory.Create(self._LoadPermissions, | 289 self._permissions_cache = cache_factory.Create(self._LoadPermissions, | 
| 254 compiled_fs.PERMS, | 290 compiled_fs.PERMS, | 
| 255 version=_VERSION) | 291 version=_VERSION) | 
| 256 self._json_cache = cache_factory.Create(self._LoadJsonAPI, | 292 self._json_cache = cache_factory.Create(self._LoadJsonAPI, | 
| 257 compiled_fs.JSON, | 293 compiled_fs.JSON, | 
| 258 version=_VERSION) | 294 version=_VERSION) | 
| 259 self._idl_cache = cache_factory.Create(self._LoadIdlAPI, | 295 self._idl_cache = cache_factory.Create(self._LoadIdlAPI, | 
| 260 compiled_fs.IDL, | 296 compiled_fs.IDL, | 
| 261 version=_VERSION) | 297 version=_VERSION) | 
| 262 self._idl_names_cache = cache_factory.Create(self._GetIDLNames, | 298 self._idl_names_cache = cache_factory.Create(self._GetIDLNames, | 
| 263 compiled_fs.IDL_NAMES, | 299 compiled_fs.IDL_NAMES, | 
| 264 version=_VERSION) | 300 version=_VERSION) | 
| 265 self._samples_factory = samples_factory | 301 self._names_cache = cache_factory.Create(self._GetAllNames, | 
| 302 compiled_fs.NAMES, | |
| 303 version=_VERSION) | |
| 266 self._base_path = base_path | 304 self._base_path = base_path | 
| 305 self._api_list_data_source = api_list_data_source | |
| 306 self._api_data_source = self.Create(None, None, resolve_refs=False) | |
| 267 | 307 | 
| 268 def Create(self, request): | 308 def Create(self, request, samples_data_source, resolve_refs=True): | 
| 269 return APIDataSource(self._permissions_cache, | 309 return APIDataSource(self._permissions_cache, | 
| 270 self._json_cache, | 310 self._json_cache, | 
| 271 self._idl_cache, | 311 self._idl_cache, | 
| 312 self._names_cache, | |
| 272 self._idl_names_cache, | 313 self._idl_names_cache, | 
| 273 self._base_path, | 314 self._base_path, | 
| 274 self._samples_factory.Create(request)) | 315 samples_data_source, | 
| 316 resolve_refs) | |
| 275 | 317 | 
| 276 def _LoadPermissions(self, json_str): | 318 def _LoadPermissions(self, json_str): | 
| 277 return json.loads(json_comment_eater.Nom(json_str)) | 319 return json.loads(json_comment_eater.Nom(json_str)) | 
| 278 | 320 | 
| 279 def _LoadJsonAPI(self, api): | 321 def _LoadJsonAPI(self, api): | 
| 280 return _JscModel(json.loads(json_comment_eater.Nom(api))[0]) | 322 return _JSCModel(json.loads(json_comment_eater.Nom(api))[0], | 
| 323 self._api_data_source, | |
| 324 self._api_list_data_source) | |
| 281 | 325 | 
| 282 def _LoadIdlAPI(self, api): | 326 def _LoadIdlAPI(self, api): | 
| 283 idl = idl_parser.IDLParser().ParseData(api) | 327 idl = idl_parser.IDLParser().ParseData(api) | 
| 284 return _JscModel(idl_schema.IDLSchema(idl).process()[0]) | 328 return _JSCModel(idl_schema.IDLSchema(idl).process()[0], | 
| 329 self._api_data_source, | |
| 330 self._api_list_data_source) | |
| 285 | 331 | 
| 286 def _GetIDLNames(self, apis): | 332 def _GetIDLNames(self, apis): | 
| 287 return [model.UnixName(os.path.splitext(api.split('/')[-1])[0]) | 333 return [ | 
| 288 for api in apis if api.endswith('.idl')] | 334 model.UnixName(os.path.splitext(api[len('%s/' % self._base_path):])[0]) | 
| 335 for api in apis if api.endswith('.idl') | |
| 336 ] | |
| 337 | |
| 338 def _GetAllNames(self, apis): | |
| 339 return [ | |
| 340 model.UnixName(os.path.splitext(api[len('%s/' % self._base_path):])[0]) | |
| 341 for api in apis | |
| 342 ] | |
| 289 | 343 | 
| 290 def __init__(self, | 344 def __init__(self, | 
| 291 permissions_cache, | 345 permissions_cache, | 
| 292 json_cache, | 346 json_cache, | 
| 293 idl_cache, | 347 idl_cache, | 
| 348 names_cache, | |
| 294 idl_names_cache, | 349 idl_names_cache, | 
| 295 base_path, | 350 base_path, | 
| 296 samples): | 351 samples, | 
| 352 resolve_refs): | |
| 297 self._base_path = base_path | 353 self._base_path = base_path | 
| 298 self._permissions_cache = permissions_cache | 354 self._permissions_cache = permissions_cache | 
| 299 self._json_cache = json_cache | 355 self._json_cache = json_cache | 
| 300 self._idl_cache = idl_cache | 356 self._idl_cache = idl_cache | 
| 357 self._names_cache = names_cache | |
| 301 self._idl_names_cache = idl_names_cache | 358 self._idl_names_cache = idl_names_cache | 
| 302 self._samples = samples | 359 self._samples = samples | 
| 360 self._resolve_refs = resolve_refs | |
| 303 | 361 | 
| 304 def _GetPermsFromFile(self, filename): | 362 def _GetPermsFromFile(self, filename): | 
| 305 try: | 363 try: | 
| 306 perms = self._permissions_cache.GetFromFile('%s/%s' % | 364 perms = self._permissions_cache.GetFromFile('%s/%s' % | 
| 307 (self._base_path, filename)) | 365 (self._base_path, filename)) | 
| 308 return dict((model.UnixName(k), v) for k, v in perms.iteritems()) | 366 return dict((model.UnixName(k), v) for k, v in perms.iteritems()) | 
| 309 except FileNotFoundError: | 367 except FileNotFoundError: | 
| 310 return {} | 368 return {} | 
| 311 | 369 | 
| 312 def _GetFeature(self, path): | 370 def _GetFeature(self, path): | 
| 313 # Remove 'experimental_' from path name to match the keys in | 371 # Remove 'experimental_' from path name to match the keys in | 
| 314 # _permissions_features.json. | 372 # _permissions_features.json. | 
| 315 path = model.UnixName(path.replace('experimental_', '')) | 373 path = model.UnixName(path.replace('experimental_', '')) | 
| 316 for filename in ['_permission_features.json', '_manifest_features.json']: | 374 for filename in ['_permission_features.json', '_manifest_features.json']: | 
| 317 api_perms = self._GetPermsFromFile(filename).get(path, None) | 375 api_perms = self._GetPermsFromFile(filename).get(path, None) | 
| 318 if api_perms is not None: | 376 if api_perms is not None: | 
| 319 break | 377 break | 
| 320 if api_perms and api_perms['channel'] in ('trunk', 'dev', 'beta'): | 378 if api_perms and api_perms['channel'] in ('trunk', 'dev', 'beta'): | 
| 321 api_perms[api_perms['channel']] = True | 379 api_perms[api_perms['channel']] = True | 
| 322 return api_perms | 380 return api_perms | 
| 323 | 381 | 
| 324 def _GenerateHandlebarContext(self, handlebar, path): | 382 def _GenerateHandlebarContext(self, handlebar, path): | 
| 325 return_dict = { | 383 return_dict = { | 
| 326 'permissions': self._GetFeature(path), | 384 'permissions': self._GetFeature(path), | 
| 327 'samples': _LazySamplesGetter(path, self._samples) | 385 'samples': _LazySamplesGetter(path, self._samples) | 
| 328 } | 386 } | 
| 329 return_dict.update(handlebar.ToDict()) | 387 return_dict.update(handlebar.ToDict(resolve_refs=self._resolve_refs)) | 
| 
 
not at google - send to devlin
2012/11/01 22:00:49
Perhaps you'll need to explain to me what all this
 
cduvall
2012/11/02 01:53:53
Done, explained in the Create method above.
 
 | |
| 330 return return_dict | 388 return return_dict | 
| 331 | 389 | 
| 390 def _GetAsSubdirectory(self, name): | |
| 391 if name.startswith('experimental_'): | |
| 392 parts = name[len('experimental_'):].split('_', 1) | |
| 393 parts[1] = 'experimental_%s' % parts[1] | |
| 394 return '/'.join(parts) | |
| 395 return name.replace('_', '/', 1) | |
| 396 | |
| 332 def __getitem__(self, key): | 397 def __getitem__(self, key): | 
| 333 return self.get(key) | 398 return self.get(key) | 
| 334 | 399 | 
| 335 def get(self, key): | 400 def get(self, key): | 
| 336 path, ext = os.path.splitext(key) | 401 if key.endswith('.html') or key.endswith('.json') or key.endswith('.idl'): | 
| 402 path, ext = os.path.splitext(key) | |
| 403 else: | |
| 404 path = key | |
| 337 unix_name = model.UnixName(path) | 405 unix_name = model.UnixName(path) | 
| 338 idl_names = self._idl_names_cache.GetFromFileListing(self._base_path) | 406 idl_names = self._idl_names_cache.GetFromFileListing(self._base_path) | 
| 407 names = self._names_cache.GetFromFileListing(self._base_path) | |
| 408 if unix_name not in names and self._GetAsSubdirectory(unix_name) in names: | |
| 409 unix_name = self._GetAsSubdirectory(unix_name) | |
| 410 | |
| 339 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else | 411 cache, ext = ((self._idl_cache, '.idl') if (unix_name in idl_names) else | 
| 340 (self._json_cache, '.json')) | 412 (self._json_cache, '.json')) | 
| 341 return self._GenerateHandlebarContext( | 413 return self._GenerateHandlebarContext( | 
| 342 cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)), | 414 cache.GetFromFile('%s/%s%s' % (self._base_path, unix_name, ext)), | 
| 343 path) | 415 path) | 
| OLD | NEW |