| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 | 5 import json |
| 6 import logging | 6 import logging |
| 7 import operator | 7 import operator |
| 8 | 8 |
| 9 from appengine_url_fetcher import AppEngineUrlFetcher | 9 from appengine_url_fetcher import AppEngineUrlFetcher |
| 10 import url_constants | 10 import url_constants |
| 11 | 11 |
| 12 | 12 |
| 13 class ChannelInfo(object): | 13 class ChannelInfo(object): |
| 14 '''Represents a Chrome channel with three pieces of information. |channel| is | 14 '''Represents a Chrome channel with three pieces of information. |channel| is |
| 15 one of 'stable', 'beta', 'dev', or 'trunk'. |branch| and |version| correspond | 15 one of 'stable', 'beta', 'dev', or 'master'. |branch| and |version| correspond |
| 16 with each other, and represent different releases of Chrome. Note that | 16 with each other, and represent different releases of Chrome. Note that |
| 17 |branch| and |version| can occasionally be the same for separate channels | 17 |branch| and |version| can occasionally be the same for separate channels |
| 18 (i.e. 'beta' and 'dev'), so all three fields are required to uniquely | 18 (i.e. 'beta' and 'dev'), so all three fields are required to uniquely |
| 19 identify a channel. | 19 identify a channel. |
| 20 ''' | 20 ''' |
| 21 | 21 |
| 22 def __init__(self, channel, branch, version): | 22 def __init__(self, channel, branch, version): |
| 23 assert isinstance(channel, basestring), channel | 23 assert isinstance(channel, basestring), channel |
| 24 assert isinstance(branch, basestring), branch | 24 assert isinstance(branch, basestring), branch |
| 25 # TODO(kalman): Assert that this is a string. One day Chromium will probably | 25 # TODO(kalman): Assert that this is a string. One day Chromium will probably |
| 26 # be served out of a git repository and the versions will no longer be ints. | 26 # be served out of a git repository and the versions will no longer be ints. |
| 27 assert isinstance(version, int) or version == 'trunk', version | 27 assert isinstance(version, int) or version == 'master', version |
| 28 self.channel = channel | 28 self.channel = channel |
| 29 self.branch = branch | 29 self.branch = branch |
| 30 self.version = version | 30 self.version = version |
| 31 | 31 |
| 32 def __eq__(self, other): | 32 def __eq__(self, other): |
| 33 return self.__dict__ == other.__dict__ | 33 return self.__dict__ == other.__dict__ |
| 34 | 34 |
| 35 def __ne__(self, other): | 35 def __ne__(self, other): |
| 36 return not (self == other) | 36 return not (self == other) |
| 37 | 37 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 58 | 58 |
| 59 @staticmethod | 59 @staticmethod |
| 60 def Create(object_store_creator): | 60 def Create(object_store_creator): |
| 61 return BranchUtility(url_constants.OMAHA_PROXY_URL, | 61 return BranchUtility(url_constants.OMAHA_PROXY_URL, |
| 62 url_constants.OMAHA_DEV_HISTORY, | 62 url_constants.OMAHA_DEV_HISTORY, |
| 63 AppEngineUrlFetcher(), | 63 AppEngineUrlFetcher(), |
| 64 object_store_creator) | 64 object_store_creator) |
| 65 | 65 |
| 66 @staticmethod | 66 @staticmethod |
| 67 def GetAllChannelNames(): | 67 def GetAllChannelNames(): |
| 68 return ('stable', 'beta', 'dev', 'trunk') | 68 return ('stable', 'beta', 'dev', 'master') |
| 69 | 69 |
| 70 @staticmethod | 70 @staticmethod |
| 71 def NewestChannel(channels): | 71 def NewestChannel(channels): |
| 72 channels = set(channels) | 72 channels = set(channels) |
| 73 for channel in reversed(BranchUtility.GetAllChannelNames()): | 73 for channel in reversed(BranchUtility.GetAllChannelNames()): |
| 74 if channel in channels: | 74 if channel in channels: |
| 75 return channel | 75 return channel |
| 76 | 76 |
| 77 def Newer(self, channel_info): | 77 def Newer(self, channel_info): |
| 78 '''Given a ChannelInfo object, returns a new ChannelInfo object | 78 '''Given a ChannelInfo object, returns a new ChannelInfo object |
| 79 representing the next most recent Chrome version/branch combination. | 79 representing the next most recent Chrome version/branch combination. |
| 80 ''' | 80 ''' |
| 81 if channel_info.channel == 'trunk': | 81 if channel_info.channel == 'master': |
| 82 return None | 82 return None |
| 83 if channel_info.channel == 'stable': | 83 if channel_info.channel == 'stable': |
| 84 stable_info = self.GetChannelInfo('stable') | 84 stable_info = self.GetChannelInfo('stable') |
| 85 if channel_info.version < stable_info.version: | 85 if channel_info.version < stable_info.version: |
| 86 return self.GetStableChannelInfo(channel_info.version + 1) | 86 return self.GetStableChannelInfo(channel_info.version + 1) |
| 87 names = self.GetAllChannelNames() | 87 names = self.GetAllChannelNames() |
| 88 return self.GetAllChannelInfo()[names.index(channel_info.channel) + 1] | 88 return self.GetAllChannelInfo()[names.index(channel_info.channel) + 1] |
| 89 | 89 |
| 90 def Older(self, channel_info): | 90 def Older(self, channel_info): |
| 91 '''Given a ChannelInfo object, returns a new ChannelInfo object | 91 '''Given a ChannelInfo object, returns a new ChannelInfo object |
| (...skipping 29 matching lines...) Expand all Loading... |
| 121 return tuple(self.GetChannelInfo(channel).version | 121 return tuple(self.GetChannelInfo(channel).version |
| 122 for channel in BranchUtility.GetAllChannelNames()) | 122 for channel in BranchUtility.GetAllChannelNames()) |
| 123 | 123 |
| 124 def GetAllChannelInfo(self): | 124 def GetAllChannelInfo(self): |
| 125 return tuple(self.GetChannelInfo(channel) | 125 return tuple(self.GetChannelInfo(channel) |
| 126 for channel in BranchUtility.GetAllChannelNames()) | 126 for channel in BranchUtility.GetAllChannelNames()) |
| 127 | 127 |
| 128 | 128 |
| 129 def GetChannelInfo(self, channel): | 129 def GetChannelInfo(self, channel): |
| 130 version = self._ExtractFromVersionJson(channel, 'version') | 130 version = self._ExtractFromVersionJson(channel, 'version') |
| 131 if version != 'trunk': | 131 if version != 'master': |
| 132 version = int(version) | 132 version = int(version) |
| 133 return ChannelInfo(channel, | 133 return ChannelInfo(channel, |
| 134 self._ExtractFromVersionJson(channel, 'branch'), | 134 self._ExtractFromVersionJson(channel, 'branch'), |
| 135 version) | 135 version) |
| 136 | 136 |
| 137 def GetStableChannelInfo(self, version): | 137 def GetStableChannelInfo(self, version): |
| 138 '''Given a |version| corresponding to a 'stable' version of Chrome, returns | 138 '''Given a |version| corresponding to a 'stable' version of Chrome, returns |
| 139 a ChannelInfo object representing that version. | 139 a ChannelInfo object representing that version. |
| 140 ''' | 140 ''' |
| 141 return ChannelInfo('stable', self.GetBranchForVersion(version), version) | 141 return ChannelInfo('stable', self.GetBranchForVersion(version), version) |
| 142 | 142 |
| 143 def _ExtractFromVersionJson(self, channel_name, data_type): | 143 def _ExtractFromVersionJson(self, channel_name, data_type): |
| 144 '''Returns the branch or version number for a channel name. | 144 '''Returns the branch or version number for a channel name. |
| 145 ''' | 145 ''' |
| 146 if channel_name == 'trunk': | 146 if channel_name == 'master': |
| 147 return 'trunk' | 147 return 'master' |
| 148 | 148 |
| 149 if data_type == 'branch': | 149 if data_type == 'branch': |
| 150 object_store = self._branch_object_store | 150 object_store = self._branch_object_store |
| 151 elif data_type == 'version': | 151 elif data_type == 'version': |
| 152 object_store = self._version_object_store | 152 object_store = self._version_object_store |
| 153 | 153 |
| 154 data = object_store.Get(channel_name).Get() | 154 data = object_store.Get(channel_name).Get() |
| 155 if data is not None: | 155 if data is not None: |
| 156 return data | 156 return data |
| 157 | 157 |
| 158 try: | 158 try: |
| 159 version_json = json.loads(self._fetch_result.Get().content) | 159 version_json = json.loads(self._fetch_result.Get().content) |
| 160 except Exception as e: | 160 except Exception as e: |
| 161 # This can happen if omahaproxy is misbehaving, which we've seen before. | 161 # This can happen if omahaproxy is misbehaving, which we've seen before. |
| 162 # Quick hack fix: just serve from trunk until it's fixed. | 162 # Quick hack fix: just serve from master until it's fixed. |
| 163 logging.error('Failed to fetch or parse branch from omahaproxy: %s! ' | 163 logging.error('Failed to fetch or parse branch from omahaproxy: %s! ' |
| 164 'Falling back to "trunk".' % e) | 164 'Falling back to "master".' % e) |
| 165 return 'trunk' | 165 return 'master' |
| 166 | 166 |
| 167 numbers = {} | 167 numbers = {} |
| 168 for entry in version_json: | 168 for entry in version_json: |
| 169 if entry['os'] not in ('win', 'linux', 'mac', 'cros'): | 169 if entry['os'] not in ('win', 'linux', 'mac', 'cros'): |
| 170 continue | 170 continue |
| 171 for version in entry['versions']: | 171 for version in entry['versions']: |
| 172 if version['channel'] != channel_name: | 172 if version['channel'] != channel_name: |
| 173 continue | 173 continue |
| 174 if data_type == 'branch': | 174 if data_type == 'branch': |
| 175 number = version['version'].split('.')[2] | 175 number = version['version'].split('.')[2] |
| 176 elif data_type == 'version': | 176 elif data_type == 'version': |
| 177 number = version['version'].split('.')[0] | 177 number = version['version'].split('.')[0] |
| 178 if number not in numbers: | 178 if number not in numbers: |
| 179 numbers[number] = 0 | 179 numbers[number] = 0 |
| 180 else: | 180 else: |
| 181 numbers[number] += 1 | 181 numbers[number] += 1 |
| 182 | 182 |
| 183 sorted_numbers = sorted(numbers.iteritems(), | 183 sorted_numbers = sorted(numbers.iteritems(), |
| 184 key=operator.itemgetter(1), | 184 key=operator.itemgetter(1), |
| 185 reverse=True) | 185 reverse=True) |
| 186 object_store.Set(channel_name, sorted_numbers[0][0]) | 186 object_store.Set(channel_name, sorted_numbers[0][0]) |
| 187 return sorted_numbers[0][0] | 187 return sorted_numbers[0][0] |
| 188 | 188 |
| 189 def GetBranchForVersion(self, version): | 189 def GetBranchForVersion(self, version): |
| 190 '''Returns the most recent branch for a given chrome version number using | 190 '''Returns the most recent branch for a given chrome version number using |
| 191 data stored on omahaproxy (see url_constants). | 191 data stored on omahaproxy (see url_constants). |
| 192 ''' | 192 ''' |
| 193 if version == 'trunk': | 193 if version == 'master': |
| 194 return 'trunk' | 194 return 'master' |
| 195 | 195 |
| 196 branch = self._branch_object_store.Get(str(version)).Get() | 196 branch = self._branch_object_store.Get(str(version)).Get() |
| 197 if branch is not None: | 197 if branch is not None: |
| 198 return branch | 198 return branch |
| 199 | 199 |
| 200 version_json = json.loads(self._history_result.Get().content) | 200 version_json = json.loads(self._history_result.Get().content) |
| 201 for entry in version_json: | 201 for entry in version_json: |
| 202 version_title = entry['version'].split('.') | 202 version_title = entry['version'].split('.') |
| 203 if version_title[0] == str(version): | 203 if version_title[0] == str(version): |
| 204 self._branch_object_store.Set(str(version), version_title[2]) | 204 self._branch_object_store.Set(str(version), version_title[2]) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 227 version_json = json.loads(self._history_result.Get().content) | 227 version_json = json.loads(self._history_result.Get().content) |
| 228 latest_version = 0 | 228 latest_version = 0 |
| 229 for entry in version_json: | 229 for entry in version_json: |
| 230 version_title = entry['version'].split('.') | 230 version_title = entry['version'].split('.') |
| 231 version = int(version_title[0]) | 231 version = int(version_title[0]) |
| 232 if version > latest_version: | 232 if version > latest_version: |
| 233 latest_version = version | 233 latest_version = version |
| 234 | 234 |
| 235 self._version_object_store.Set('latest', latest_version) | 235 self._version_object_store.Set('latest', latest_version) |
| 236 return latest_version | 236 return latest_version |
| OLD | NEW |