summaryrefslogtreecommitdiffstats
path: root/chrome/common/extensions/docs/server2/branch_utility.py
blob: 0dd43d102637f061a065074980889ebebb71a404 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import logging
import operator

from appengine_url_fetcher import AppEngineUrlFetcher
import url_constants

class BranchUtility(object):
  def __init__(self, fetch_url, fetcher, object_store_creator):
    self._fetch_url = fetch_url
    self._fetcher = fetcher
    # BranchUtility is obviously cross-channel, so set the channel to None.
    self._object_store = object_store_creator.Create(BranchUtility,
                                                     channel=None)

  @staticmethod
  def Create(object_store_creator):
    return BranchUtility(url_constants.OMAHA_PROXY_URL,
                         AppEngineUrlFetcher(),
                         object_store_creator)

  @staticmethod
  def GetAllChannelNames():
    return ['stable', 'beta', 'dev', 'trunk']

  @staticmethod
  def SplitChannelNameFromPath(path):
    """Splits the channel name out of |path|, returning the tuple
    (channel_name, real_path). If the channel cannot be determined then returns
    (None, path).
    """
    if '/' in path:
      first, second = path.split('/', 1)
    else:
      first, second = (path, '')
    if first in ['trunk', 'dev', 'beta', 'stable']:
      return (first, second)
    return (None, path)

  def GetBranchForChannel(self, channel_name):
    """Returns the branch number for a channel name.
    """
    if channel_name == 'trunk':
      return 'trunk'

    branch_number = self._object_store.Get(channel_name).Get()
    if branch_number is not None:
      return branch_number

    try:
      version_json = json.loads(self._fetcher.Fetch(self._fetch_url).content)
    except Exception as e:
      # This can happen if omahaproxy is misbehaving, which we've seen before.
      # Quick hack fix: just serve from trunk until it's fixed.
      logging.error('Failed to fetch or parse branch from omahaproxy: %s! '
                    'Falling back to "trunk".' % e)
      return 'trunk'

    branch_numbers = {}
    for entry in version_json:
      if entry['os'] not in ['win', 'linux', 'mac', 'cros']:
        continue
      for version in entry['versions']:
        if version['channel'] != channel_name:
          continue
        branch = version['version'].split('.')[2]
        if branch not in branch_numbers:
          branch_numbers[branch] = 0
        else:
          branch_numbers[branch] += 1

    sorted_branches = sorted(branch_numbers.iteritems(),
                             None,
                             operator.itemgetter(1),
                             True)
    self._object_store.Set(channel_name, sorted_branches[0][0])

    return sorted_branches[0][0]