api_list_data_source.py revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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
3# found in the LICENSE file.
4
5from operator import itemgetter
6import os
7import posixpath
8
9from svn_constants import PUBLIC_TEMPLATE_PATH
10import docs_server_utils as utils
11
12def _GetAPICategory(api, documented_apis):
13  name = api['name']
14  if (name.endswith('Private') or
15      name not in documented_apis):
16    return 'private'
17  if name.startswith('experimental.'):
18    return 'experimental'
19  return 'chrome'
20
21
22class APIListDataSource(object):
23  """ This class creates a list of chrome.* APIs and chrome.experimental.* APIs
24  for extensions and apps that are used in the api_index.html and
25  experimental.html pages.
26
27  An API is considered listable if it is listed in _api_features.json,
28  it has a corresponding HTML file in the public template path, and one of
29  the following conditions is met:
30    - It has no "dependencies" or "extension_types" properties in _api_features
31    - It has an "extension_types" property in _api_features with either/both
32      "extension"/"platform_app" values present.
33    - It has a dependency in _{api,manifest,permission}_features with an
34      "extension_types" property where either/both "extension"/"platform_app"
35      values are present.
36  """
37  class Factory(object):
38    def __init__(self,
39                 compiled_fs_factory,
40                 file_system,
41                 features_bundle,
42                 object_store_creator):
43      self._file_system = file_system
44      self._cache = compiled_fs_factory.Create(file_system,
45                                               self._CollectDocumentedAPIs,
46                                               APIListDataSource)
47      self._features_bundle = features_bundle
48      self._object_store_creator = object_store_creator
49
50    def _CollectDocumentedAPIs(self, base_dir, files):
51      def GetDocumentedAPIsForPlatform(names, platform):
52        public_templates = []
53        for root, _, files in self._file_system.Walk(posixpath.join(
54            PUBLIC_TEMPLATE_PATH, platform)):
55          public_templates.extend(
56              ('%s/%s' % (root, name)).lstrip('/') for name in files)
57        template_names = set(os.path.splitext(name)[0]
58                             for name in public_templates)
59        return [name.replace('_', '.') for name in template_names]
60      api_names = set(utils.SanitizeAPIName(name) for name in files)
61      return {
62        'apps': GetDocumentedAPIsForPlatform(api_names, 'apps'),
63        'extensions': GetDocumentedAPIsForPlatform(api_names, 'extensions')
64      }
65
66    def _GenerateAPIDict(self):
67      documented_apis = self._cache.GetFromFileListing(
68          PUBLIC_TEMPLATE_PATH).Get()
69      api_features = self._features_bundle.GetAPIFeatures()
70
71      def FilterAPIs(platform):
72        return (api for api in api_features.itervalues()
73            if platform in api['platforms'])
74
75      def MakeDictForPlatform(platform):
76        platform_dict = { 'chrome': [], 'experimental': [], 'private': [] }
77        for api in FilterAPIs(platform):
78          category = _GetAPICategory(api, documented_apis[platform])
79          platform_dict[category].append(api)
80        for category, apis in platform_dict.iteritems():
81          platform_dict[category] = sorted(apis, key=itemgetter('name'))
82          utils.MarkLast(platform_dict[category])
83        return platform_dict
84
85      return {
86        'apps': MakeDictForPlatform('apps'),
87        'extensions': MakeDictForPlatform('extensions')
88      }
89
90    def Create(self):
91      return APIListDataSource(self, self._object_store_creator)
92
93  def __init__(self, factory, object_store_creator):
94    self._factory = factory
95    self._object_store = object_store_creator.Create(APIListDataSource)
96
97  def _GetCachedAPIData(self):
98    data = self._object_store.Get('api_data').Get()
99    if data is None:
100      data = self._factory._GenerateAPIDict()
101      self._object_store.Set('api_data', data)
102    return data
103
104  def get(self, key):
105    return self._GetCachedAPIData().get(key)
106