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

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

Issue 11315018: Extensions Docs Server: Generalize $ref's to work for any schema node (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 1 month 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 | Annotate | Revision Log
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 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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698