1
2
3
4
5
6 import os
7 import re
8 import time
9 import urllib
10 import urlparse
11 import warnings
12
13 from restkit.errors import InvalidUrl
14
15 absolute_http_url_re = re.compile(r"^https?://", re.I)
16
17 try:
18 import subprocess
19 subprocess.Popen
20 closefds = os.name == 'posix'
21
22 - def popen3(cmd, mode='t', bufsize=0):
23 p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
24 stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
25 close_fds=closefds)
26 p.wait()
27 return (p.stdin, p.stdout, p.stderr)
28 except ImportError:
29 subprocess = None
30 popen3 = os.popen3
31
33 if os.path.isabs(program):
34 return program
35 if os.path.dirname(program):
36 program = os.path.normpath(os.path.realpath(program))
37 return program
38 paths = os.getenv('PATH')
39 if not paths:
40 return False
41 for path in paths.split(os.pathsep):
42 filename = os.path.join(path, program)
43 if os.access(filename, os.X_OK):
44 return filename
45 return False
46
47 weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
48 monthname = [None,
49 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
50 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
51
53 """Return the current date and time formatted for a message header."""
54 if timestamp is None:
55 timestamp = time.time()
56 year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
57 s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
58 weekdayname[wd],
59 day, monthname[month], year,
60 hh, mm, ss)
61 return s
62
64 host = uri.netloc
65 port = None
66 i = host.rfind(':')
67 j = host.rfind(']')
68 if i > j:
69 try:
70 port = int(host[i+1:])
71 except ValueError:
72 raise InvalidUrl("nonnumeric port: '%s'" % host[i+1:])
73 host = host[:i]
74 else:
75
76 if uri.scheme == "https":
77 port = 443
78 else:
79 port = 80
80
81 if host and host[0] == '[' and host[-1] == ']':
82 host = host[1:-1]
83 return (host, port)
84
86 if not isinstance(s, basestring):
87 raise TypeError("value should be a str or unicode")
88
89 if isinstance(s, unicode):
90 return s.encode('utf-8')
91 return s
92
94 """URL encode a single string with a given encoding."""
95 if isinstance(s, unicode):
96 s = s.encode(charset)
97 elif not isinstance(s, str):
98 s = str(s)
99 return urllib.quote(s, safe=safe)
100
101
102 -def url_encode(obj, charset="utf8", encode_keys=False):
103 items = []
104 if isinstance(obj, dict):
105 for k, v in list(obj.items()):
106 items.append((k, v))
107 else:
108 items = list(items)
109
110 tmp = []
111 for k, v in items:
112 if encode_keys:
113 k = encode(k, charset)
114
115 if not isinstance(v, (tuple, list)):
116 v = [v]
117
118 for v1 in v:
119 if v1 is None:
120 v1 = ''
121 elif callable(v1):
122 v1 = encode(v1(), charset)
123 else:
124 v1 = encode(v1, charset)
125 tmp.append('%s=%s' % (urllib.quote(k), urllib.quote_plus(v1)))
126 return '&'.join(tmp)
127
128 -def encode(v, charset="utf8"):
129 if isinstance(v, unicode):
130 v = v.encode(charset)
131 else:
132 v = str(v)
133 return v
134
135
137 """Assemble a uri based on a base, any number of path segments,
138 and query string parameters.
139
140 """
141
142
143 charset = kwargs.pop("charset", "utf-8")
144 safe = kwargs.pop("safe", "/:")
145 encode_keys = kwargs.pop("encode_keys", True)
146
147 base_trailing_slash = False
148 if base and base.endswith("/"):
149 base_trailing_slash = True
150 base = base[:-1]
151 retval = [base]
152
153
154 _path = []
155 trailing_slash = False
156 for s in args:
157 if s is not None and isinstance(s, basestring):
158 if len(s) > 1 and s.endswith('/'):
159 trailing_slash = True
160 else:
161 trailing_slash = False
162 _path.append(url_quote(s.strip('/'), charset, safe))
163
164 path_str =""
165 if _path:
166 path_str = "/".join([''] + _path)
167 if trailing_slash:
168 path_str = path_str + "/"
169 elif base_trailing_slash:
170 path_str = path_str + "/"
171
172 if path_str:
173 retval.append(path_str)
174
175 params_str = url_encode(kwargs, charset, encode_keys)
176 if params_str:
177 retval.extend(['?', params_str])
178
179 return ''.join(retval)
180
181
183 prefix_path = prefix_path or ''
184 url = urlparse.urlparse(location)
185 host_url = urlparse.urlparse(host_uri)
186
187 if not absolute_http_url_re.match(location):
188
189 proxy_uri = '%s%s' % (host_uri, prefix_path)
190 return urlparse.urljoin(proxy_uri, location)
191 elif url.scheme == host_url.scheme and url.netloc == host_url.netloc:
192 return urlparse.urlunparse((host_url.scheme, host_url.netloc,
193 prefix_path + url.path, url.params, url.query, url.fragment))
194
195 return location
196
198 idx = -1
199 for i, (k, v) in enumerate(headers):
200 if k.upper() == name.upper():
201 idx = i
202 break
203 if idx >= 0:
204 headers[i] = (name.title(), value)
205 else:
206 headers.append((name.title(), value))
207 return headers
208
210 hdrs = {}
211 for (k, v) in new_headers:
212 hdrs[k.upper()] = v
213
214 found = []
215 for i, (k, v) in enumerate(headers):
216 ku = k.upper()
217 if ku in hdrs:
218 headers[i] = (k.title(), hdrs[ku])
219 found.append(ku)
220 if len(found) == len(new_headers):
221 return
222
223 for k, v in new_headers.items():
224 if k not in found:
225 headers.append((k.title(), v))
226 return headers
227
228
229
231 """
232 Wraps a decorator, with a deprecation warning or error
233 """
234 - def __init__(self, decorator, attr, message, warning=True):
235 self.decorator = decorator
236 self.attr = attr
237 self.message = message
238 self.warning = warning
239
240 - def __get__(self, obj, type=None):
241 if obj is None:
242 return self
243 self.warn()
244 return self.decorator.__get__(obj, type)
245
249
253
255 return '<Deprecated attribute %s: %r>' % (
256 self.attr,
257 self.decorator)
258
260 if not self.warning:
261 raise DeprecationWarning(
262 'The attribute %s is deprecated: %s' % (self.attr, self.message))
263 else:
264 warnings.warn(
265 'The attribute %s is deprecated: %s' % (self.attr, self.message),
266 DeprecationWarning,
267 stacklevel=3)
268