Package buildbot :: Package util
[frames] | no frames]

Source Code for Package buildbot.util

  1  # -*- test-case-name: buildbot.test.test_util -*- 
  2   
  3  from twisted.python import threadable 
  4  import time, re, string 
  5   
6 -def naturalSort(l):
7 """Returns a sorted copy of l, so that numbers in strings are sorted in the 8 proper order. 9 10 e.g. ['foo10', 'foo1', 'foo2'] will be sorted as ['foo1', 'foo2', 'foo10'] 11 instead of the default ['foo1', 'foo10', 'foo2']""" 12 l = l[:] 13 def try_int(s): 14 try: 15 return int(s) 16 except ValueError: 17 return s
18 def key_func(item): 19 return [try_int(s) for s in re.split('(\d+)', item)] 20 # prepend integer keys to each element, sort them, then strip the keys 21 keyed_l = [ (key_func(i), i) for i in l ] 22 keyed_l.sort() 23 l = [ i[1] for i in keyed_l ] 24 return l 25
26 -def now(_reactor=None):
27 if _reactor and hasattr(_reactor, "seconds"): 28 return _reactor.seconds() 29 else: 30 return time.time()
31
32 -def formatInterval(eta):
33 eta_parts = [] 34 if eta > 3600: 35 eta_parts.append("%d hrs" % (eta / 3600)) 36 eta %= 3600 37 if eta > 60: 38 eta_parts.append("%d mins" % (eta / 60)) 39 eta %= 60 40 eta_parts.append("%d secs" % eta) 41 return ", ".join(eta_parts)
42
43 -class ComparableMixin:
44 """Specify a list of attributes that are 'important'. These will be used 45 for all comparison operations.""" 46 47 compare_attrs = [] 48
49 - class _None:
50 pass
51
52 - def __hash__(self):
53 alist = [self.__class__] + \ 54 [getattr(self, name, self._None) for name in self.compare_attrs] 55 return hash(tuple(map(str, alist)))
56
57 - def __cmp__(self, them):
58 result = cmp(type(self), type(them)) 59 if result: 60 return result 61 62 result = cmp(self.__class__.__name__, them.__class__.__name__) 63 if result: 64 return result 65 66 assert self.compare_attrs == them.compare_attrs 67 self_list = [getattr(self, name, self._None) 68 for name in self.compare_attrs] 69 them_list = [getattr(them, name, self._None) 70 for name in self.compare_attrs] 71 return cmp(self_list, them_list)
72 73 # Remove potentially harmful characters from builder name if it is to be 74 # used as the build dir. 75 badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~", 76 "______________________________")
77 -def safeTranslate(str):
78 if isinstance(str, unicode): 79 str = str.encode('utf8') 80 return str.translate(badchars_map)
81
82 -class LRUCache:
83 """ 84 A simple least-recently-used cache, with a fixed maximum size. Note that 85 an item's memory will not necessarily be free if other code maintains a reference 86 to it, but this class will "lose track" of it all the same. Without caution, this 87 can lead to duplicate items in memory simultaneously. 88 """ 89 90 synchronized = ["get", "add"] 91
92 - def __init__(self, max_size=50):
93 self._max_size = max_size 94 self._cache = {} # basic LRU cache 95 self._cached_ids = [] # = [LRU .. MRU]
96
97 - def get(self, id):
98 thing = self._cache.get(id, None) 99 if thing is not None: 100 self._cached_ids.remove(id) 101 self._cached_ids.append(id) 102 return thing
103 __getitem__ = get 104
105 - def add(self, id, thing):
106 if id in self._cache: 107 self._cached_ids.remove(id) 108 self._cached_ids.append(id) 109 return 110 while len(self._cached_ids) >= self._max_size: 111 del self._cache[self._cached_ids.pop(0)] 112 self._cache[id] = thing 113 self._cached_ids.append(id)
114 __setitem__ = add 115
116 - def setMaxSize(self, max_size):
117 self._max_size = max_size
118 119 threadable.synchronize(LRUCache) 120 121
122 -def none_or_str(x):
123 """Cast X to a str if it is not None""" 124 if x is not None and not isinstance(x, str): 125 return str(x) 126 return x
127 128 # place a working json module at 'buildbot.util.json'. Code is from 129 # Paul Wise <pabs@debian.org>: 130 # http://lists.debian.org/debian-python/2010/02/msg00016.html 131 try: 132 import json # python 2.6 133 except ImportError: 134 import simplejson as json # python 2.4 to 2.5 135 try: 136 _tmp = json.loads 137 except AttributeError: 138 import warnings 139 import sys 140 warnings.warn("Use simplejson, not the old json module.") 141 sys.modules.pop('json') # get rid of the bad json module 142 import simplejson as json 143 144 # changes and schedulers consider None to be a legitimate name for a branch, 145 # which makes default function keyword arguments hard to handle. This value 146 # is always false.
147 -class NotABranch:
148 - def __nonzero__(self):
149 return False
150 NotABranch = NotABranch() 151 152 __all__ = [ 153 'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json', 154 'safeTranslate', 'remove_userpassword', 'LRUCache', 'none_or_str', 155 'NotABranch'] 156