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.
4
5from itertools import groupby
6from operator import itemgetter
7import posixpath
8
9from data_source import DataSource
10from extensions_paths import JSON_TEMPLATES, PUBLIC_TEMPLATES
11from future import Future
12from platform_util import GetPlatforms
13
14
15class WhatsNewDataSource(DataSource):
16  ''' This class creates a list of "what is new" by chrome version.
17  '''
18
19  def __init__(self, server_instance, _):
20    self._parse_cache = server_instance.compiled_fs_factory.ForJson(
21        server_instance.host_file_system_provider.GetMaster())
22    self._object_store = server_instance.object_store_creator.Create(
23        WhatsNewDataSource)
24    self._platform_bundle = server_instance.platform_bundle
25
26  def _GenerateChangesListWithVersion(self, platform, whats_new_json):
27    return [{
28      'id': change_id,
29      'type': change['type'],
30      'description': change['description'],
31      'version': change['version']
32    } for change_id, change in whats_new_json.iteritems()]
33
34  def _GetAPIVersion(self, platform, api_name):
35    version = None
36    category = self._platform_bundle.GetAPICategorizer(platform).GetCategory(
37        api_name)
38    if category == 'chrome':
39      channel_info = self._platform_bundle.GetAvailabilityFinder(
40          platform).GetAPIAvailability(api_name).channel_info
41      channel = channel_info.channel
42      if channel == 'stable':
43        version = channel_info.version
44    return version
45
46  def _GenerateAPIListWithVersion(self, platform):
47    data = []
48    for api_name, api_model in self._platform_bundle.GetAPIModels(
49        platform).IterModels():
50      version = self._GetAPIVersion(platform, api_name)
51      if version:
52        api = {
53          'name': api_name,
54          'description': api_model.description,
55          'version' : version,
56          'type': 'apis',
57        }
58        data.append(api)
59    data.sort(key=itemgetter('version'))
60    return data
61
62  def _GenerateWhatsNewDict(self):
63    whats_new_json_future = self._parse_cache.GetFromFile(
64        posixpath.join(JSON_TEMPLATES, 'whats_new.json'))
65    def _MakeDictByPlatform(platform):
66      whats_new_json = whats_new_json_future.Get()
67      platform_list = []
68      apis = self._GenerateAPIListWithVersion(platform)
69      apis.extend(self._GenerateChangesListWithVersion(platform,
70          whats_new_json))
71      apis.sort(key=itemgetter('version'), reverse=True)
72      for version, group in groupby(apis, key=itemgetter('version')):
73        whats_new_by_version = {
74          'version': version,
75        }
76        for item in group:
77          item_type = item['type']
78          if item_type not in whats_new_by_version:
79            whats_new_by_version[item_type] = []
80          whats_new_by_version[item_type].append(item)
81        platform_list.append(whats_new_by_version)
82      return platform_list
83
84    def resolve():
85      return dict((platform, _MakeDictByPlatform(platform))
86          for platform in GetPlatforms())
87    return Future(callback=resolve)
88
89  def _GetCachedWhatsNewData(self):
90    data = self._object_store.Get('whats_new_data').Get()
91    if data is None:
92      data = self._GenerateWhatsNewDict().Get()
93      self._object_store.Set('whats_new_data', data)
94    return data
95
96  def get(self, key):
97    return self._GetCachedWhatsNewData().get(key)
98
99  def Refresh(self, path):
100    return self._GenerateWhatsNewDict()
101