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

Source Code for Package buildbot.util

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