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
107 if not isinstance(old, set):
108 old = set(old)
109 if not isinstance(new, set):
110 new = set(new)
111 return old - new, new - old
112
113
114
115 badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~",
116 "______________________________")
118 if isinstance(str, unicode):
119 str = str.encode('utf8')
120 return str.translate(badchars_map)
121
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
129
130
131
132
133
134 try:
135 import simplejson as json
136 assert json
137 except ImportError:
138 import json
139 try:
140 _tmp = json.loads
141 except AttributeError:
142 import warnings
143 import sys
144 warnings.warn("Use simplejson, not the old json module.")
145 sys.modules.pop('json')
146 import simplejson as json
147
148
149
150
154 NotABranch = NotABranch()
155
156
157
158 -class UTC(datetime.tzinfo):
159 """Simple definition of UTC timezone"""
161 return datetime.timedelta(0)
162
164 return datetime.timedelta(0)
165
168 UTC = UTC()
169
171 """Convert a UNIX epoch time to a datetime object, in the UTC timezone"""
172 if epoch is not None:
173 return datetime.datetime.fromtimestamp(epoch, tz=UTC)
174
176 """Convert a non-naive datetime object to a UNIX epoch timestamp"""
177 if dt is not None:
178 return calendar.timegm(dt.utctimetuple())
179
180 __all__ = [
181 'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json',
182 'safeTranslate', 'LRUCache', 'none_or_str',
183 'NotABranch', 'deferredLocked', 'SerializedInvocation', 'UTC',
184 'diffLists' ]
185