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