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

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

Issue 16410002: Docserver manifest follow up (rewrite) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gen-manifest-try-2
Patch Set: codereview Created 7 years, 4 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 from collections import OrderedDict
6 from copy import deepcopy 5 from copy import deepcopy
7 from operator import itemgetter 6 import json
8 7
8 from features_utility import FeatureFile
9 from third_party.json_schema_compiler.json_parse import Parse 9 from third_party.json_schema_compiler.json_parse import Parse
10 10
11 def _ConvertAndSortDocs(properties, platform):
12 '''Convert docs and subdocs into lists and sort them, first by level, then
13 by name.
14 '''
15 def sort_key(item):
16 '''Key function to sort items primarily by level (according to index into
17 levels) then subsort by name.
18 '''
19 levels = ('required', 'recommended', 'only_one', 'optional')
20
21 return (levels.index(item.get('level', 'optional')), item['name'])
22
23 def convert_and_sort(properties):
24 for key in properties.keys():
25 value = properties[key]
not at google - send to devlin 2013/07/29 23:30:09 for key, value in properties.items() ?
jshumway 2013/07/30 23:15:50 Done.
26 if 'example' in value:
27 value['has_example'] = True
28 example = json.dumps(value['example'])
29 if example == '{}':
30 value['example'] = '{...}'
31 elif example == '[]':
32 value['example'] = '[...]'
33 else:
34 value['example'] = example
35
36 if 'subdocs' in value:
37 properties[key]['subdocs'] = convert_and_sort(value['subdocs'])
38
39 return sorted(properties.values(), key=sort_key)
40
41 name = properties['name']
42 name['example'] = name['example'].replace('{{title}}', platform.capitalize())
43
44 return convert_and_sort(properties)
45
46 def _Annotate(properties):
47 '''Add level annotations to level groups in a manifest property list and
48 subdoc lists. Requeries a list of properties sorted by level, with subdocs
49 in sorted lists as well.
50 '''
51 annotations = {
52 'required': 'Required',
53 'recommended': 'Recommended',
54 'only_one': 'Pick one (or none)',
55 'optional': 'Optional'
56 }
57
58 def add_annotation(item, annotation):
59 if not 'annotations' in item:
60 item['annotations'] = []
61 item['annotations'].insert(0, annotation)
62
63 def annotate(parent_level, properties):
64 current_level = parent_level
65 for item in properties:
66 level = item.get('level', 'optional')
67 if level != current_level:
68 add_annotation(item, annotations[level])
69 current_level = level
70 if 'subdocs' in item:
71 annotate(level, item['subdocs'])
72 if properties:
73 properties[-1]['is_last'] = True
74
75 annotate('required', properties)
76 return properties
77
11 class ManifestDataSource(object): 78 class ManifestDataSource(object):
12 '''Provides a template with access to manifest properties specific to apps or 79 '''Provides a template with access to manifest properties specific to apps or
13 extensions. 80 extensions.
14 ''' 81 '''
15 def __init__(self, 82 def __init__(self,
16 compiled_fs_factory, 83 compiled_fs_factory,
17 file_system, 84 file_system,
18 manifest_path, 85 manifest_path,
19 features_path): 86 features_path):
20 self._manifest_path = manifest_path 87 self._manifest_path = manifest_path
21 self._features_path = features_path 88 self._features_path = features_path
22 self._file_system = file_system 89 self._file_system = file_system
23 self._cache = compiled_fs_factory.Create( 90 self._cache = compiled_fs_factory.Create(
24 self._CreateManifestData, ManifestDataSource) 91 self._CreateManifestData, ManifestDataSource)
25 92
26 def _ApplyAppsTransformations(self, manifest): 93 def _CreateManifestData(self, _, content):
27 manifest['required'][0]['example'] = 'Application' 94 '''Combine the contents of |_manifest_path| and |_features_path| into a
28 manifest['optional'][-1]['is_last'] = True 95 master dictionary then create filtered lists to be used by templates.
96 '''
97 manifest_json = Parse(content)
98 manifest_features = FeatureFile(
99 Parse(self._file_system.ReadSingle(self._features_path)))
100 manifest_features.MergeWith(manifest_json)
29 101
30 def _ApplyExtensionsTransformations(self, manifest): 102 apps_features = deepcopy(manifest_features).Filter('app').InsertSubDocs()
31 manifest['optional'][-1]['is_last'] = True 103 apps_features = _Annotate(_ConvertAndSortDocs(apps_features, 'app'))
32 104
33 def _CreateManifestData(self, _, content): 105 extensions_features = (
34 '''Take the contents of |_manifest_path| and create apps and extensions 106 deepcopy(manifest_features).Filter('extension').InsertSubDocs())
35 versions of a manifest example based on the contents of |_features_path|. 107 extensions_features = _Annotate(
36 ''' 108 _ConvertAndSortDocs(extensions_features, 'extension'))
not at google - send to devlin 2013/07/29 23:30:09 if we immutify the FeatureModel class the all this
jshumway 2013/07/30 23:15:50 Done.
37 def create_manifest_dict():
38 manifest_dict = OrderedDict()
39 for category in ('required', 'only_one', 'recommended', 'optional'):
40 manifest_dict[category] = []
41 return manifest_dict
42 109
43 apps = create_manifest_dict() 110 return {
44 extensions = create_manifest_dict() 111 'apps': apps_features,
45 112 'extensions': extensions_features,
46 manifest_json = Parse(content) 113 'all_features': manifest_features
47 features_json = Parse(self._file_system.ReadSingle( 114 }
48 self._features_path))
49
50 def add_property(feature, manifest_key, category):
51 '''If |feature|, from features_json, has the correct extension_types, add
52 |manifest_key| to either apps or extensions.
53 '''
54 added = False
55 extension_types = feature['extension_types']
56 if extension_types == 'all' or 'platform_app' in extension_types:
57 apps[category].append(deepcopy(manifest_key))
58 added = True
59 if extension_types == 'all' or 'extension' in extension_types:
60 extensions[category].append(deepcopy(manifest_key))
61 added = True
62 return added
63
64 # Property types are: required, only_one, recommended, and optional.
65 for category in manifest_json:
66 for manifest_key in manifest_json[category]:
67 # If a property is in manifest.json but not _manifest_features, this
68 # will cause an error.
69 feature = features_json[manifest_key['name']]
70 if add_property(feature, manifest_key, category):
71 del features_json[manifest_key['name']]
72
73 # All of the properties left in features_json are assumed to be optional.
74 for feature in features_json.keys():
75 item = features_json[feature]
76 # Handles instances where a features entry is a union with a whitelist.
77 if isinstance(item, list):
78 item = item[0]
79 add_property(item, {'name': feature}, 'optional')
80
81 apps['optional'].sort(key=itemgetter('name'))
82 extensions['optional'].sort(key=itemgetter('name'))
83
84 self._ApplyAppsTransformations(apps)
85 self._ApplyExtensionsTransformations(extensions)
86
87 return {'apps': apps, 'extensions': extensions}
88 115
89 def get(self, key): 116 def get(self, key):
90 return self._cache.GetFromFile(self._manifest_path)[key] 117 return self._cache.GetFromFile(self._manifest_path)[key]
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698