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

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

Issue 18323018: Linking AvailabilityFinder with APIDataSource and intro-table templates. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: HostFileSystemCreator, Intro Table data structure changes Created 7 years, 5 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 collections 5 import collections
6 import os 6 import os
7 7
8 from branch_utility import BranchUtility 8 from branch_utility import BranchUtility
9 from compiled_file_system import CompiledFileSystem 9 from compiled_file_system import CompiledFileSystem
10 from file_system import FileNotFoundError 10 from file_system import FileNotFoundError
11 import svn_constants 11 import svn_constants
12 from third_party.json_schema_compiler import json_parse, model 12 from third_party.json_schema_compiler import json_parse, model
13 from third_party.json_schema_compiler.memoize import memoize 13 from third_party.json_schema_compiler.memoize import memoize
14 14
15 _API_AVAILABILITIES = svn_constants.JSON_PATH + '/api_availabilities.json' 15 _API_AVAILABILITIES = svn_constants.JSON_PATH + '/api_availabilities.json'
16 _API_FEATURES = svn_constants.API_PATH + '/_api_features.json' 16 _API_FEATURES = svn_constants.API_PATH + '/_api_features.json'
17 _EXTENSION_API = svn_constants.API_PATH + '/extension_api.json' 17 _EXTENSION_API = svn_constants.API_PATH + '/extension_api.json'
18 _MANIFEST_FEATURES = svn_constants.API_PATH + '/_manifest_features.json' 18 _MANIFEST_FEATURES = svn_constants.API_PATH + '/_manifest_features.json'
19 _PERMISSION_FEATURES = svn_constants.API_PATH + '/_permission_features.json' 19 _PERMISSION_FEATURES = svn_constants.API_PATH + '/_permission_features.json'
20 _STABLE = 'stable' 20 _STABLE = 'stable'
21 21
22 _EXPERIMENTAL_MESSAGE = ('Experimental only (see' +
23 '<a href="experimental.html#using">How to use experimental APIs</a>).')
not at google - send to devlin 2013/07/09 23:11:55 ah. so maybe we need to actually pass _templates_
epeterson 2013/07/16 00:28:23 Solution to this no longer involves availability_f
24
22 class AvailabilityInfo(object): 25 class AvailabilityInfo(object):
23 def __init__(self, channel, version): 26 def __init__(self, channel, version):
24 self.channel = channel 27 self.channel = channel
25 self.version = version 28 self.version = version
26 29
27 def _GetChannelFromFeatures(api_name, file_system, path): 30 def _GetChannelFromFeatures(api_name, file_system, path):
28 '''Finds API channel information within _features.json files at the given 31 '''Finds API channel information within _features.json files at the given
29 |path| for the given |file_system|. Returns None if channel information for 32 |path| for the given |file_system|. Returns None if channel information for
30 the API cannot be located. 33 the API cannot be located.
31 ''' 34 '''
32 feature = file_system.GetFromFile(path).get(api_name) 35 feature = file_system.GetFromFile(path).get(api_name)
33 36
34 if feature is None: 37 if feature is None:
35 return None 38 return None
36 if isinstance(feature, collections.Mapping): 39 if isinstance(feature, collections.Mapping):
37 # The channel information dict is nested within a list for whitelisting 40 # The channel information dict is nested within a list for whitelisting
38 # purposes. 41 # purposes.
39 return feature.get('channel') 42 return feature.get('channel')
40 # Features can contain a list of entries. Take the newest branch. 43 # Features can contain a list of entries. Take the newest branch.
41 return BranchUtility.NewestChannel(entry.get('channel') 44 return BranchUtility.NewestChannel(entry.get('channel')
42 for entry in feature) 45 for entry in feature)
43 46
44 def _GetChannelFromApiFeatures(api_name, file_system): 47 def _GetChannelFromApiFeatures(api_name, file_system):
45 try: 48 try:
46 return _GetChannelFromFeatures(api_name, file_system, _API_FEATURES) 49 return _GetChannelFromFeatures(api_name, file_system, _API_FEATURES)
47 except FileNotFoundError as e: 50 except FileNotFoundError:
48 # TODO(epeterson) Remove except block once _api_features is in all channels. 51 # TODO(epeterson) Remove except block once _api_features is in all channels.
49 return None 52 return None
50 53
51 def _GetChannelFromPermissionFeatures(api_name, file_system): 54 def _GetChannelFromPermissionFeatures(api_name, file_system):
52 return _GetChannelFromFeatures(api_name, file_system, _PERMISSION_FEATURES) 55 return _GetChannelFromFeatures(api_name, file_system, _PERMISSION_FEATURES)
53 56
54 def _GetChannelFromManifestFeatures(api_name, file_system): 57 def _GetChannelFromManifestFeatures(api_name, file_system):
55 return _GetChannelFromFeatures(#_manifest_features uses unix_style API names 58 return _GetChannelFromFeatures(#_manifest_features uses unix_style API names
56 model.UnixName(api_name), 59 model.UnixName(api_name),
57 file_system, 60 file_system,
(...skipping 10 matching lines...) Expand all
68 def _ExistsInExtensionApi(api_name, file_system): 71 def _ExistsInExtensionApi(api_name, file_system):
69 '''Parses the api/extension_api.json file (available in Chrome versions 72 '''Parses the api/extension_api.json file (available in Chrome versions
70 before 18) for an API namespace. If this is successfully found, then the API 73 before 18) for an API namespace. If this is successfully found, then the API
71 is considered to have been 'stable' for the given version. 74 is considered to have been 'stable' for the given version.
72 ''' 75 '''
73 try: 76 try:
74 extension_api_json = file_system.GetFromFile(_EXTENSION_API) 77 extension_api_json = file_system.GetFromFile(_EXTENSION_API)
75 api_rows = [row.get('namespace') for row in extension_api_json 78 api_rows = [row.get('namespace') for row in extension_api_json
76 if 'namespace' in row] 79 if 'namespace' in row]
77 return True if api_name in api_rows else False 80 return True if api_name in api_rows else False
78 except FileNotFoundError as e: 81 except FileNotFoundError:
79 # This should only happen on preview.py since extension_api.json is no 82 # This should only happen on preview.py since extension_api.json is no
80 # longer present in trunk. 83 # longer present in trunk.
81 return False 84 return False
82 85
83 class AvailabilityFinder(object): 86 class AvailabilityFinder(object):
84 '''Uses API data sources generated by a ChromeVersionDataSource in order to 87 '''Uses API data sources generated by a ChromeVersionDataSource in order to
85 search the filesystem for the earliest existence of a specified API throughout 88 search the filesystem for the earliest existence of a specified API throughout
86 the different versions of Chrome; this constitutes an API's availability. 89 the different versions of Chrome; this constitutes an API's availability.
87 ''' 90 '''
88 class Factory(object): 91 class Factory(object):
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 on the stable channel. When a version is found where the API is no longer 149 on the stable channel. When a version is found where the API is no longer
147 available on stable, returns the previous version number (the last known 150 available on stable, returns the previous version number (the last known
148 version where the API was stable). 151 version where the API was stable).
149 ''' 152 '''
150 available = True 153 available = True
151 while available: 154 while available:
152 if version < 5: 155 if version < 5:
153 # SVN data isn't available below version 5. 156 # SVN data isn't available below version 5.
154 return version + 1 157 return version + 1
155 available = False 158 available = False
159 available_channel = None
156 features_fs, names_fs = self._CreateFeaturesAndNamesFileSystems(version) 160 features_fs, names_fs = self._CreateFeaturesAndNamesFileSystems(version)
157 if version >= 28: 161 if version >= 28:
158 # The _api_features.json file first appears in version 28 and should be 162 # The _api_features.json file first appears in version 28 and should be
159 # the most reliable for finding API availabilities, so it gets checked 163 # the most reliable for finding API availabilities, so it gets checked
160 # first. The _permission_features.json and _manifest_features.json files 164 # first. The _permission_features.json and _manifest_features.json files
161 # are present in Chrome 20 and onwards. Fall back to a check for file 165 # are present in Chrome 20 and onwards. Fall back to a check for file
162 # system existence if the API is not stable in any of the _features.json 166 # system existence if the API is not stable in any of the _features.json
163 # files. 167 # files.
164 available = _GetChannelFromApiFeatures(api_name, features_fs) == _STABLE 168 available_channel = _GetChannelFromApiFeatures(api_name, features_fs)
165 if version >= 20: 169 if version >= 20:
166 # Check other _features.json files/file existence if the API wasn't 170 # Check other _features.json files/file existence if the API wasn't
167 # found in _api_features.json, or if _api_features.json wasn't present. 171 # found in _api_features.json, or if _api_features.json wasn't present.
168 available = available or ( 172 available_channel = available_channel or (
169 _GetChannelFromPermissionFeatures(api_name, features_fs) == _STABLE 173 _GetChannelFromPermissionFeatures(api_name, features_fs)
170 or _GetChannelFromManifestFeatures(api_name, features_fs) == _STABLE 174 or _GetChannelFromManifestFeatures(api_name, features_fs))
171 or _ExistsInFileSystem(api_name, names_fs)) 175 if available_channel is None:
176 available = _ExistsInFileSystem(api_name, names_fs)
177 else:
178 available = available_channel == _STABLE
172 elif version >= 18: 179 elif version >= 18:
173 # These versions are a little troublesome. Version 19 has 180 # These versions are a little troublesome. Version 19 has
174 # _permission_features.json, but it lacks 'channel' information. 181 # _permission_features.json, but it lacks 'channel' information.
175 # Version 18 lacks all of the _features.json files. For now, we're using 182 # Version 18 lacks all of the _features.json files. For now, we're using
176 # a simple check for filesystem existence here. 183 # a simple check for filesystem existence here.
177 available = _ExistsInFileSystem(api_name, names_fs) 184 available = _ExistsInFileSystem(api_name, names_fs)
178 elif version >= 5: 185 elif version >= 5:
179 # Versions 17 and down to 5 have an extension_api.json file which 186 # Versions 17 and down to 5 have an extension_api.json file which
180 # contains namespaces for each API that was available at the time. We 187 # contains namespaces for each API that was available at the time. We
181 # can use this file to check for API existence. 188 # can use this file to check for API existence.
182 available = _ExistsInExtensionApi(api_name, features_fs) 189 available = _ExistsInExtensionApi(api_name, features_fs)
183 190
184 if not available: 191 if not available:
185 return version + 1 192 return version + 1
186 version -= 1 193 version -= 1
187 194
188 def _GetAvailableChannelForVersion(self, api_name, version): 195 def _GetAvailableChannelForVersion(self, api_name, version):
189 '''Searches through the _features files for a given |version| and returns 196 '''Searches through the _features files for a given |version| and returns
190 the channel that the given API is determined to be available on. 197 the channel that the given API is determined to be available on.
191 ''' 198 '''
192 features_fs, names_fs = self._CreateFeaturesAndNamesFileSystems(version) 199 features_fs, names_fs = self._CreateFeaturesAndNamesFileSystems(version)
193 channel = (_GetChannelFromApiFeatures(api_name, features_fs) 200 available_channel = (_GetChannelFromApiFeatures(api_name, features_fs)
194 or _GetChannelFromPermissionFeatures(api_name, features_fs) 201 or _GetChannelFromPermissionFeatures(api_name, features_fs)
195 or _GetChannelFromManifestFeatures(api_name, features_fs)) 202 or _GetChannelFromManifestFeatures(api_name, features_fs))
196 if channel is None and _ExistsInFileSystem(api_name, names_fs): 203 if available_channel is None and _ExistsInFileSystem(api_name, names_fs):
197 # If an API is not represented in any of the _features files, but exists 204 # If an API is not represented in any of the _features files, but exists
198 # in the filesystem, then assume it is available in this version. 205 # in the filesystem, then assume it is available in this version.
199 # The windows API is an example of this. 206 # The windows API is an example of this.
200 return self._branch_utility.GetChannelForVersion(version) 207 return self._branch_utility.GetChannelForVersion(version)
201 208
202 return channel 209 return available_channel
203 210
204 def GetApiAvailability(self, api_name): 211 def GetApiAvailability(self, api_name):
205 '''Determines the availability for an API by testing several scenarios. 212 '''Determines the availability for an API by testing several scenarios.
206 (i.e. Is the API experimental? Only available on certain development 213 (i.e. Is the API experimental? Only available on certain development
207 channels? If it's stable, when did it first become stable? etc.) 214 channels? If it's stable, when did it first become stable? etc.)
208 ''' 215 '''
209 availability = self._object_store.Get(api_name).Get() 216 availability = self._object_store.Get(api_name).Get()
210 if availability is not None: 217 if availability is not None:
211 return availability 218 return availability
212 219
(...skipping 25 matching lines...) Expand all
238 245
239 # If the API is in stable, find the chrome version in which it became 246 # If the API is in stable, find the chrome version in which it became
240 # stable. 247 # stable.
241 if availability.channel == _STABLE: 248 if availability.channel == _STABLE:
242 availability.version = self._FindEarliestStableAvailability( 249 availability.version = self._FindEarliestStableAvailability(
243 api_name, 250 api_name,
244 availability.version) 251 availability.version)
245 252
246 self._object_store.Set(api_name, availability) 253 self._object_store.Set(api_name, availability)
247 return availability 254 return availability
255
256 @staticmethod
257 def StringifyAvailability(availability):
258 '''Given an AvailabilityInfo struct, provides a message that can be
259 displayed in an API intro table
260 '''
261 availability_id = 'intro-availability'
262 if availability.channel == 'stable':
263 return '<span id="%s" class="%s">Stable</span> since version %s.' % (
264 availability_id, availability.channel, availability.version)
265 else:
266 return 'Available on <span id="%s" class="%s">%s</span>.' % (
267 availability_id, availability.channel, availability.channel)
not at google - send to devlin 2013/07/09 23:11:55 Yeah ok so same thing with the partials. We'll nee
epeterson 2013/07/16 00:28:23 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698