1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17  import time, re, string 
 18  import datetime 
 19  import calendar 
 20  from buildbot.util.misc import deferredLocked, SerializedInvocation 
 21   
 23      """Returns a sorted copy of l, so that numbers in strings are sorted in the 
 24      proper order. 
 25   
 26      e.g. ['foo10', 'foo1', 'foo2'] will be sorted as ['foo1', 'foo2', 'foo10'] 
 27      instead of the default ['foo1', 'foo10', 'foo2']""" 
 28      l = l[:] 
 29      def try_int(s): 
 30          try: 
 31              return int(s) 
 32          except ValueError: 
 33              return s 
  34      def key_func(item): 
 35          return [try_int(s) for s in re.split('(\d+)', item)] 
 36       
 37      keyed_l = [ (key_func(i), i) for i in l ] 
 38      keyed_l.sort() 
 39      l = [ i[1] for i in keyed_l ] 
 40      return l 
 41   
 43      """Flatten nested lists into a single-level list""" 
 44      if l and type(l[0]) == list: 
 45          rv = [] 
 46          for e in l: 
 47              if type(e) == list: 
 48                  rv.extend(e) 
 49              else: 
 50                  rv.append(e) 
 51          return rv 
 52      else: 
 53          return l 
  54   
 55 -def now(_reactor=None): 
  56      """Get the time, using reactor.seconds or time.time""" 
 57      if _reactor and hasattr(_reactor, "seconds"): 
 58          return _reactor.seconds() 
 59      else: 
 60          return time.time() 
  61   
 72   
 74      """Specify a list of attributes that are 'important'. These will be used 
 75      for all comparison operations.""" 
 76   
 77      compare_attrs = [] 
 78   
 81   
 83          alist = [self.__class__] + \ 
 84                  [getattr(self, name, self._None) for name in self.compare_attrs] 
 85          return hash(tuple(map(str, alist))) 
  86   
 88          result = cmp(type(self), type(them)) 
 89          if result: 
 90              return result 
 91   
 92          result = cmp(self.__class__.__name__, them.__class__.__name__) 
 93          if result: 
 94              return result 
 95   
 96          result = cmp(self.compare_attrs, them.compare_attrs) 
 97          if result: 
 98              return result 
 99   
100          self_list = [getattr(self, name, self._None) 
101                       for name in self.compare_attrs] 
102          them_list = [getattr(them, name, self._None) 
103                       for name in self.compare_attrs] 
104          return cmp(self_list, them_list) 
  105   
106   
107   
108  badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~", 
109                                  "______________________________") 
111      if isinstance(str, unicode): 
112          str = str.encode('utf8') 
113      return str.translate(badchars_map) 
 114   
116      """Cast X to a str if it is not None""" 
117      if x is not None and not isinstance(x, str): 
118          return str(x) 
119      return x 
 120   
121   
122   
123   
124   
125   
126   
127  try: 
128      import simplejson as json 
129      assert json 
130  except ImportError: 
131      import json  
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')  
139      import simplejson as json 
140   
141   
142   
143   
147  NotABranch = NotABranch() 
148   
149   
150   
151 -class UTC(datetime.tzinfo): 
 152      """Simple definition of UTC timezone""" 
154          return datetime.timedelta(0) 
 155   
157          return datetime.timedelta(0) 
 158   
 161  UTC = UTC() 
162   
164      """Convert a UNIX epoch time to a datetime object, in the UTC timezone""" 
165      return datetime.datetime.fromtimestamp(epoch, tz=UTC) 
 166   
168      """Convert a non-naive datetime object to a UNIX epoch timestamp""" 
169      return calendar.timegm(dt.utctimetuple()) 
 170   
171  __all__ = [ 
172      'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json', 
173      'safeTranslate', 'remove_userpassword', 'LRUCache', 'none_or_str', 
174      'NotABranch', 'deferredLocked', 'SerializedInvocation', 'UTC' ] 
175