commit | author | age
|
0c1c39
|
1 |
from pyramid.compat import ( |
CM |
2 |
text_type, |
|
3 |
binary_type, |
|
4 |
is_nonstr_iter, |
|
5 |
url_quote as _url_quote, |
e967a9
|
6 |
url_quote_plus as _quote_plus, |
0c29cf
|
7 |
) |
8e606d
|
8 |
|
0c29cf
|
9 |
|
MM |
10 |
def url_quote(val, safe=''): # bw compat api |
22f0eb
|
11 |
cls = val.__class__ |
MM |
12 |
if cls is text_type: |
|
13 |
val = val.encode('utf-8') |
|
14 |
elif cls is not binary_type: |
|
15 |
val = str(val).encode('utf-8') |
|
16 |
return _url_quote(val, safe=safe) |
0c29cf
|
17 |
|
eb9fbf
|
18 |
|
804232
|
19 |
# bw compat api (dnr) |
D |
20 |
def quote_plus(val, safe=''): |
|
21 |
cls = val.__class__ |
|
22 |
if cls is text_type: |
|
23 |
val = val.encode('utf-8') |
|
24 |
elif cls is not binary_type: |
|
25 |
val = str(val).encode('utf-8') |
|
26 |
return _quote_plus(val, safe=safe) |
|
27 |
|
0c29cf
|
28 |
|
804232
|
29 |
def urlencode(query, doseq=True, quote_via=quote_plus): |
eb9fbf
|
30 |
""" |
6f43b6
|
31 |
An alternate implementation of Python's stdlib |
MM |
32 |
:func:`urllib.parse.urlencode` function which accepts unicode keys and |
|
33 |
values within the ``query`` dict/sequence; all Unicode keys and values are |
|
34 |
first converted to UTF-8 before being used to compose the query string. |
eb9fbf
|
35 |
|
CM |
36 |
The value of ``query`` must be a sequence of two-tuples |
|
37 |
representing key/value pairs *or* an object (often a dictionary) |
|
38 |
with an ``.items()`` method that returns a sequence of two-tuples |
|
39 |
representing key/value pairs. |
|
40 |
|
|
41 |
For minimal calling convention backwards compatibility, this |
|
42 |
version of urlencode accepts *but ignores* a second argument |
|
43 |
conventionally named ``doseq``. The Python stdlib version behaves |
|
44 |
differently when ``doseq`` is False and when a sequence is |
|
45 |
presented as one of the values. This version always behaves in |
|
46 |
the ``doseq=True`` mode, no matter what the value of the second |
|
47 |
argument. |
|
48 |
|
6f43b6
|
49 |
Both the key and value are encoded using the ``quote_via`` function which |
MM |
50 |
by default is using a similar algorithm to :func:`urllib.parse.quote_plus` |
|
51 |
which converts spaces into '+' characters and '/' into '%2F'. |
af5fa0
|
52 |
|
MM |
53 |
.. versionchanged:: 1.5 |
|
54 |
In a key/value pair, if the value is ``None`` then it will be |
|
55 |
dropped from the resulting output. |
6f43b6
|
56 |
|
MM |
57 |
.. versionchanged:: 1.9 |
|
58 |
Added the ``quote_via`` argument to allow alternate quoting algorithms |
|
59 |
to be used. |
|
60 |
|
eb9fbf
|
61 |
""" |
CM |
62 |
try: |
|
63 |
# presumed to be a dictionary |
|
64 |
query = query.items() |
|
65 |
except AttributeError: |
|
66 |
pass |
|
67 |
|
|
68 |
result = '' |
|
69 |
prefix = '' |
|
70 |
|
|
71 |
for (k, v) in query: |
804232
|
72 |
k = quote_via(k) |
a84e17
|
73 |
|
8e606d
|
74 |
if is_nonstr_iter(v): |
eb9fbf
|
75 |
for x in v: |
804232
|
76 |
x = quote_via(x) |
eb9fbf
|
77 |
result += '%s%s=%s' % (prefix, k, x) |
CM |
78 |
prefix = '&' |
af5fa0
|
79 |
elif v is None: |
15afe5
|
80 |
result += '%s%s=' % (prefix, k) |
eb9fbf
|
81 |
else: |
804232
|
82 |
v = quote_via(v) |
eb9fbf
|
83 |
result += '%s%s=%s' % (prefix, k, v) |
a84e17
|
84 |
|
eb9fbf
|
85 |
prefix = '&' |
CM |
86 |
|
|
87 |
return result |