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 twisted.python import reflect
21
22 from buildbot.util.misc import deferredLocked, SerializedInvocation
23
25 l = l[:]
26 def try_int(s):
27 try:
28 return int(s)
29 except ValueError:
30 return s
31 def key_func(item):
32 return [try_int(s) for s in re.split('(\d+)', item)]
33
34 keyed_l = [ (key_func(i), i) for i in l ]
35 keyed_l.sort()
36 l = [ i[1] for i in keyed_l ]
37 return l
38
40 if l and isinstance(l, types):
41 rv = []
42 for e in l:
43 if isinstance(e, types):
44 rv.extend(flatten(e))
45 else:
46 rv.append(e)
47 return rv
48 else:
49 return l
50
51 -def now(_reactor=None):
56
67
69
70 compare_attrs = []
71
74
76 compare_attrs = []
77 reflect.accumulateClassList(self.__class__, 'compare_attrs', compare_attrs)
78
79 alist = [self.__class__] + \
80 [getattr(self, name, self._None) for name in compare_attrs]
81 return hash(tuple(map(str, alist)))
82
84 result = cmp(type(self), type(them))
85 if result:
86 return result
87
88 result = cmp(self.__class__, them.__class__)
89 if result:
90 return result
91
92 compare_attrs = []
93 reflect.accumulateClassList(self.__class__, 'compare_attrs', compare_attrs)
94
95 self_list = [getattr(self, name, self._None)
96 for name in compare_attrs]
97 them_list = [getattr(them, name, self._None)
98 for name in compare_attrs]
99 return cmp(self_list, them_list)
100
102 if not isinstance(old, set):
103 old = set(old)
104 if not isinstance(new, set):
105 new = set(new)
106 return old - new, new - old
107
108
109
110 badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~",
111 "______________________________")
113 if isinstance(str, unicode):
114 str = str.encode('utf8')
115 return str.translate(badchars_map)
116
118 if x is not None and not isinstance(x, str):
119 return str(x)
120 return x
121
122
123
124
125
126
127
128 try:
129 import simplejson as json
130 assert json
131 except ImportError:
132 import json
133 try:
134 _tmp = json.loads
135 except AttributeError:
136 import warnings
137 import sys
138 warnings.warn("Use simplejson, not the old json module.")
139 sys.modules.pop('json')
140 import simplejson as json
141
142
143
144
148 NotABranch = NotABranch()
149
150
151
152 -class UTC(datetime.tzinfo):
153 """Simple definition of UTC timezone"""
155 return datetime.timedelta(0)
156
158 return datetime.timedelta(0)
159
162 UTC = UTC()
163
165 """Convert a UNIX epoch time to a datetime object, in the UTC timezone"""
166 if epoch is not None:
167 return datetime.datetime.fromtimestamp(epoch, tz=UTC)
168
170 """Convert a non-naive datetime object to a UNIX epoch timestamp"""
171 if dt is not None:
172 return calendar.timegm(dt.utctimetuple())
173
175 if isinstance(input, basestring):
176 return [ input ]
177 elif input is None:
178 return [ ]
179 else:
180 return list(input)
181
183 """decorate a function by running it with maybeDeferred in a reactor"""
184 def wrap(*args, **kwargs):
185 from twisted.internet import reactor, defer
186 result = [ ]
187 def async():
188 d = defer.maybeDeferred(f, *args, **kwargs)
189 def eb(f):
190 f.printTraceback()
191 d.addErrback(eb)
192 def do_stop(r):
193 result.append(r)
194 reactor.stop()
195 d.addBoth(do_stop)
196 reactor.callWhenRunning(async)
197 reactor.run()
198 return result[0]
199 wrap.__doc__ = f.__doc__
200 wrap.__name__ = f.__name__
201 wrap._orig = f
202 return wrap
203
204 __all__ = [
205 'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json',
206 'safeTranslate', 'LRUCache', 'none_or_str',
207 'NotABranch', 'deferredLocked', 'SerializedInvocation', 'UTC',
208 'diffLists', 'makeList', 'in_reactor' ]
209