Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / common / extensions / docs / server2 / manifest_data_source.py
blob6495ccb5e0991f38787ac90c408497120467b2e9
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 import json
7 from data_source import DataSource
8 import features_utility
9 from future import Gettable, Future
10 from manifest_features import ConvertDottedKeysToNested
12 def _ListifyAndSortDocs(features, app_name):
13 '''Convert a |feautres| dictionary, and all 'children' dictionaries, into
14 lists recursively. Sort lists first by 'level' then by name.
15 '''
16 def sort_key(item):
17 '''Key function to sort items primarily by level (according to index into
18 levels) then subsort by name.
19 '''
20 levels = ('required', 'recommended', 'only_one', 'optional')
22 return (levels.index(item.get('level', 'optional')), item['name'])
24 def coerce_example_to_feature(feature):
25 '''To display json in examples more clearly, convert the example of
26 |feature| into the feature format, with a name and children, to be rendered
27 by the templates. Only applicable to examples that are dictionaries.
28 '''
29 if not isinstance(feature.get('example'), dict):
30 if 'example' in feature:
31 feature['example'] = json.dumps(feature['example'])
32 return
33 # Add any keys/value pairs in the dict as children
34 for key, value in feature['example'].iteritems():
35 if not 'children' in feature:
36 feature['children'] = {}
37 feature['children'][key] = { 'name': key, 'example': value }
38 del feature['example']
39 del feature['has_example']
41 def convert_and_sort(features):
42 for key, value in features.items():
43 if 'example' in value:
44 value['has_example'] = True
45 example = json.dumps(value['example'])
46 if example == '{}':
47 value['example'] = '{...}'
48 elif example == '[]':
49 value['example'] = '[...]'
50 elif example == '[{}]':
51 value['example'] = '[{...}]'
52 else:
53 coerce_example_to_feature(value)
54 if 'children' in value:
55 features[key]['children'] = convert_and_sort(value['children'])
56 return sorted(features.values(), key=sort_key)
58 # Replace {{platform}} in the 'name' manifest property example with
59 # |app_name|, the convention that the normal template rendering uses.
60 # TODO(kalman): Make the example a template and pass this through there.
61 if 'name' in features:
62 name = features['name']
63 name['example'] = name['example'].replace('{{platform}}', app_name)
65 features = convert_and_sort(features)
67 return features
69 def _AddLevelAnnotations(features):
70 '''Add level annotations to |features|. |features| and children lists must be
71 sorted by 'level'. Annotations are added to the first item in a group of
72 features of the same 'level'.
74 The last item in a list has 'is_last' set to True.
75 '''
76 annotations = {
77 'required': 'Required',
78 'recommended': 'Recommended',
79 'only_one': 'Pick one (or none)',
80 'optional': 'Optional'
83 def add_annotation(item, annotation):
84 if not 'annotations' in item:
85 item['annotations'] = []
86 item['annotations'].insert(0, annotation)
88 def annotate(parent_level, features):
89 current_level = parent_level
90 for item in features:
91 level = item.get('level', 'optional')
92 if level != current_level:
93 add_annotation(item, annotations[level])
94 current_level = level
95 if 'children' in item:
96 annotate(level, item['children'])
97 if features:
98 features[-1]['is_last'] = True
100 annotate('required', features)
101 return features
103 class ManifestDataSource(DataSource):
104 '''Provides access to the properties in manifest features.
106 def __init__(self, server_instance, _):
107 self._features_bundle = server_instance.features_bundle
108 self._object_store = server_instance.object_store_creator.Create(
109 ManifestDataSource)
111 def _CreateManifestData(self):
112 future_manifest_features = self._features_bundle.GetManifestFeatures()
113 def resolve():
114 manifest_features = future_manifest_features.Get()
115 def for_templates(manifest_features, platform):
116 return _AddLevelAnnotations(_ListifyAndSortDocs(
117 ConvertDottedKeysToNested(
118 features_utility.Filtered(manifest_features, platform + 's')),
119 app_name=platform.capitalize()))
120 return {
121 'apps': for_templates(manifest_features, 'app'),
122 'extensions': for_templates(manifest_features, 'extension')
124 return Future(delegate=Gettable(resolve))
126 def _GetCachedManifestData(self):
127 data = self._object_store.Get('manifest_data').Get()
128 if data is None:
129 data = self._CreateManifestData().Get()
130 self._object_store.Set('manifest_data', data)
131 return data
133 def Cron(self):
134 return self._CreateManifestData()
136 def get(self, key):
137 return self._GetCachedManifestData().get(key)