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 threadable.synchronize(LRUCache) 117 118
119 -def none_or_str(x):
120 """Cast X to a str if it is not None""" 121 if x is not None and not isinstance(x, str): 122 return str(x) 123 return x
124 125 # place a working json module at 'buildbot.util.json'. Code is from 126 # Paul Wise <pabs@debian.org>: 127 # http://lists.debian.org/debian-python/2010/02/msg00016.html 128 try: 129 import json # python 2.6 130 except ImportError: 131 import simplejson as json # python 2.4 to 2.5 132 try: 133 _tmp = json.loads 134 except AttributeError: 135 import warnings 136 import sys 137 warnings.warn("Use simplejson, not the old json module.") 138 sys.modules.pop('json') # get rid of the bad json module 139 import simplejson as json 140 141 # changes and schedulers consider None to be a legitimate name for a branch, 142 # which makes default function keyword arguments hard to handle. This value 143 # is always false.
144 -class NotABranch:
145 - def __nonzero__(self):
146 return False
147 NotABranch = NotABranch() 148 149 __all__ = [ 150 'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json', 151 'safeTranslate', 'remove_userpassword', 'LRUCache', 'none_or_str', 152 'NotABranch'] 153