1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os
17 import re
18 import time
19 from datetime import tzinfo, timedelta
20 try:
21
22 import urlparse
23 except ImportError:
24
25 import urllib.parse as urlparse
26
27 from spacewalk.common import usix
28
29
31 """
32 Function that correctly sets headers in an Apache-like table
33 The values may be a string (which are set as for a dictionary),
34 or an array.
35 """
36
37
38 if isinstance(values, (usix.ListType, usix.TupleType)):
39 for v in values:
40 mp_table.add(name, str(v))
41 else:
42 mp_table[name] = str(values)
43
44
45 rfc822_days = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')
46 rfc822_mons = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
47 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
48
49
51 """
52 Return time as a string formatted such as: 'Wed, 23 Jun 2001 23:08:35 GMT'.
53 We must not use locale-specific functions such as strftime here because
54 the RFC explicitly requires C-locale only formatting. To satisfy this
55 requirement, we declare our own days and months here and do the formatting
56 manually.
57
58 This function accepts a single argument. If it is a List or Tuple type,
59 it is assumed to be of the form struct_time, as specified in the Python
60 time module reference. If the argument is a float, it is expected to be
61 the number of seconds from the epoch.
62
63 NOTE: In all cases, the argument is assumed to be in local time. It will
64 be translated to GMT in the return value.
65 """
66
67 if isinstance(arg, (usix.ListType, usix.TupleType)):
68
69 arg = time.mktime(arg)
70
71
72
73 (tm_year, tm_mon, tm_mday, tm_hour, tm_min,
74 tm_sec, tm_wday, _tm_yday_, _tm_isdst_) = time.gmtime(arg)
75
76 return \
77 "%s, %02d %s %04d %02d:%02d:%02d %s" % \
78 (rfc822_days[tm_wday], tm_mday, rfc822_mons[tm_mon - 1], tm_year,
79 tm_hour, tm_min, tm_sec, "GMT")
80
81
83 """
84 Converts the string in format YYYYMMDDHHMISS to seconds from the epoch
85 """
86 if isinstance(s, (usix.IntType, usix.FloatType)):
87
88 return s
89 if len(s) == 14:
90 format_string = "%Y%m%d%H%M%S"
91 elif len(s) == 19:
92 format_string = "%Y-%m-%d %H:%M:%S"
93 else:
94 raise TypeError("String '%s' is not a YYYYMMDDHHMISS" % s)
95
96 timeval = list(time.strptime(s, format_string))
97
98 timeval[8] = -1
99 return time.mktime(timeval)
100
101
103 """ A type/value checker
104 Check value against the list of acceptable values / types
105 """
106
107 for a in args:
108 if isinstance(a, usix.TypeType):
109
110 if isinstance(val, a):
111 return 1
112 else:
113
114 if val == a:
115 return 1
116 return 0
117
118
120 """ urlparse is more complicated than what we need.
121
122 We make the assumption that the URL has real URL information.
123 NOTE: http/https ONLY for right now.
124
125 The normal behavior of urlparse:
126 - if no {http[s],file}:// then the string is considered everything
127 that normally follows the URL, e.g. /XMLRPC
128 - if {http[s],file}:// exists, anything between that and the next /
129 is the URL.
130
131 The behavior of *this* function:
132 - if no {http[s],file}:// then the string is simply assumed to be a
133 URL without the {http[s],file}:// attached. The parsed info is
134 reparsed as one would think it would be:
135
136 - returns: (addressing scheme, network location, path,
137 parameters, query, fragment identifier).
138
139 NOTE: netloc (or network location) can be HOSTNAME:PORT
140 """
141 schemes = ('http', 'https')
142 if url is None:
143 return None
144 parsed = list(urlparse.urlparse(url))
145 if not parsed[0] or parsed[0] not in schemes:
146 url = 'https://' + url
147 parsed = list(urlparse.urlparse(url))
148 parsed[0] = ''
149 return tuple(parsed)
150
151
153 """Given an object id (assumed to be <label>-<number>), returns the
154 last few digits for the number. For instance, (812345, 3) should
155 return 345"""
156
157 num_id = object_id.split('-')[-1]
158
159 num_id = num_id[-factor:]
160 return num_id.rjust(factor, '0')
161
162
163
164 re_rpmName = re.compile("^(.*)-([^-]*)-([^-]*)$")
165
166
168 """ IN: Package string in, n-n-n-v.v.v-r.r_r, format.
169 OUT: Four strings (in a tuple): name, epoch, version, release.
170 """
171 reg = re_rpmName.match(pkgName)
172 if reg is None:
173 return None, None, None, None
174 n, v, r = reg.group(1, 2, 3)
175 e = None
176 ind = r.find(':')
177 if ind >= 0:
178 e = r[ind + 1:]
179 r = r[0:ind]
180 return str(n), e, str(v), str(r)
181
182
184 """ IN: Package string in, n-n_v.v-v.v-r.r, format.
185 OUT: Four strings (in a tuple): name, epoch, version, release.
186 """
187 if pkgName.find('_') == -1:
188 return None, None, None, None
189 e = None
190 n, version = pkgName.split('_')
191 if version.find(':') != -1:
192 e, version = version.split(':')
193 version_tmpArr = version.split('-')
194 v = '-'.join(version_tmpArr[:-1])
195 r = version_tmpArr[-1]
196 return str(n), e, str(v), str(r)
197
198
200 """Return true if this is a SUSE system, otherwise false"""
201
202 if not os.path.exists('/etc/os-release'):
203 return False
204
205 cpe_name = ''
206 try:
207 lines = open('/etc/os-release', 'rb').readlines()
208 for line in lines:
209
210 if re.match(r'[ \t]*(#|$)', line):
211 continue
212
213
214
215 (key, val) = [c.strip() for c in line.split('=', 1)]
216 if key == 'CPE_NAME':
217 cpe_name = val
218 break
219 except (IOError, OSError):
220 pass
221
222 if 'cpe:/o:opensuse:' in cpe_name or 'cpe:/o:suse:' in cpe_name:
223 return True
224 return False
225
226
228 """Used for creating offset-aware datetime objects in Python 2."""
229
230
233
236
239
240 utc = UTC()
241