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

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

Issue 23867003: Docserver: Consolidate features caching and access. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 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 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 json
6
7 from data_source import DataSource 5 from data_source import DataSource
8 import features_utility
9 from manifest_features import CreateManifestFeatures, ConvertDottedKeysToNested
10 from third_party.json_schema_compiler.json_parse import Parse
11
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')
21
22 return (levels.index(item.get('level', 'optional')), item['name'])
23
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']
40
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 else:
51 coerce_example_to_feature(value)
52 if 'children' in value:
53 features[key]['children'] = convert_and_sort(value['children'])
54 return sorted(features.values(), key=sort_key)
55
56 # Replace {{title}} in the 'name' manifest property example with |app_name|
57 if 'name' in features:
58 name = features['name']
59 name['example'] = name['example'].replace('{{title}}', app_name)
60
61 features = convert_and_sort(features)
62
63 return features
64
65 def _AddLevelAnnotations(features):
66 '''Add level annotations to |features|. |features| and children lists must be
67 sorted by 'level'. Annotations are added to the first item in a group of
68 features of the same 'level'.
69
70 The last item in a list has 'is_last' set to True.
71 '''
72 annotations = {
73 'required': 'Required',
74 'recommended': 'Recommended',
75 'only_one': 'Pick one (or none)',
76 'optional': 'Optional'
77 }
78
79 def add_annotation(item, annotation):
80 if not 'annotations' in item:
81 item['annotations'] = []
82 item['annotations'].insert(0, annotation)
83
84 def annotate(parent_level, features):
85 current_level = parent_level
86 for item in features:
87 level = item.get('level', 'optional')
88 if level != current_level:
89 add_annotation(item, annotations[level])
90 current_level = level
91 if 'children' in item:
92 annotate(level, item['children'])
93 if features:
94 features[-1]['is_last'] = True
95
96 annotate('required', features)
97 return features
98 6
99 class ManifestDataSource(DataSource): 7 class ManifestDataSource(DataSource):
100 '''Provides access to the properties in manifest features. 8 '''Provides access to the properties in manifest features.
101 ''' 9 '''
102 def __init__(self, server_instance, _): 10 def __init__(self, server_instance, _):
103 self._manifest_path = server_instance.manifest_json_path 11 self._features_bundle = server_instance.features_bundle
104 self._features_path = server_instance.manifest_features_path 12 self._features_path = server_instance.manifest_features_path
105 self._file_system = server_instance.host_file_system 13 self._file_system = server_instance.host_file_system
106 self._cache = server_instance.compiled_host_fs_factory.Create(
107 self._CreateManifestData, ManifestDataSource)
108
109 def _CreateManifestData(self, _, content):
110 '''Combine the contents of |_manifest_path| and |_features_path| and filter
111 the results into lists specific to apps or extensions for templates. Marks
112 up features with annotations.
113 '''
114 def for_templates(manifest_features, platform):
115 return _AddLevelAnnotations(
116 _ListifyAndSortDocs(
117 ConvertDottedKeysToNested(
118 features_utility.Filtered(manifest_features, platform)),
119 app_name=platform.capitalize()))
120
121 manifest_json = Parse(self._file_system.ReadSingle(self._manifest_path))
122 manifest_features = CreateManifestFeatures(
123 features_json=Parse(content), manifest_json=manifest_json)
124
125 return {
126 'apps': for_templates(manifest_features, 'app'),
127 'extensions': for_templates(manifest_features, 'extension')
128 }
129
130 def Cron(self):
131 self._cache.GetFromFile(self._features_path)
132 self._file_system.ReadSingle(self._manifest_path)
133 14
134 def get(self, key): 15 def get(self, key):
135 return self._cache.GetFromFile(self._features_path)[key] 16 return self._features_bundle.get('manifest').get(key)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698