5
5
File: client.py
6
6
Author: goodspeed
7
7
8
- Github: https://github.com/zongxiao
8
+ Github: https://github.com/gusibi
9
9
Date: 2015-02-11
10
10
Description: Weixin helpers
11
11
"""
20
20
21
21
PY2 = sys .version_info [0 ] == 2
22
22
23
- _always_safe = ('abcdefghijklmnopqrstuvwxyz'
24
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-+' )
23
+ _always_safe = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-+"
25
24
26
25
safe_char = _always_safe
27
26
28
- error_dict = {
29
- 'AppID 参数错误' : {
30
- 'errcode' : 40013 ,
31
- 'errmsg' : 'invalid appid'
32
- }
33
- }
27
+ error_dict = {"AppID 参数错误" : {"errcode" : 40013 , "errmsg" : "invalid appid" }}
34
28
35
29
36
30
if PY2 :
37
31
text_type = unicode
38
32
iteritems = lambda d , * args , ** kwargs : d .iteritems (* args , ** kwargs )
39
33
40
- def to_native (x , charset = sys .getdefaultencoding (), errors = ' strict' ):
34
+ def to_native (x , charset = sys .getdefaultencoding (), errors = " strict" ):
41
35
if x is None or isinstance (x , str ):
42
36
return x
43
37
return x .encode (charset , errors )
38
+
39
+
44
40
else :
45
41
text_type = str
46
42
iteritems = lambda d , * args , ** kwargs : iter (d .items (* args , ** kwargs ))
47
43
48
- def to_native (x , charset = sys .getdefaultencoding (), errors = ' strict' ):
44
+ def to_native (x , charset = sys .getdefaultencoding (), errors = " strict" ):
49
45
if x is None or isinstance (x , str ):
50
46
return x
51
47
return x .decode (charset , errors )
@@ -60,15 +56,18 @@ def to_native(x, charset=sys.getdefaultencoding(), errors='strict'):
60
56
61
57
try :
62
58
import hashlib
59
+
63
60
md5_constructor = hashlib .md5
64
61
md5_hmac = md5_constructor
65
62
sha_constructor = hashlib .sha1
66
63
sha_hmac = sha_constructor
67
64
except ImportError :
68
65
import md5
66
+
69
67
md5_constructor = md5 .new
70
68
md5_hmac = md5
71
69
import sha
70
+
72
71
sha_constructor = sha .new
73
72
sha_hmac = sha
74
73
@@ -79,6 +78,7 @@ class Promise(object):
79
78
the closure of the lazy function. It can be used to recognize
80
79
promises in code.
81
80
"""
81
+
82
82
pass
83
83
84
84
@@ -89,11 +89,10 @@ def __init__(self, obj, *args):
89
89
90
90
def __str__ (self ):
91
91
original = UnicodeDecodeError .__str__ (self )
92
- return '%s. You passed in %r (%s)' % (original , self .obj ,
93
- type (self .obj ))
92
+ return "%s. You passed in %r (%s)" % (original , self .obj , type (self .obj ))
94
93
95
94
96
- def smart_text (s , encoding = ' utf-8' , strings_only = False , errors = ' strict' ):
95
+ def smart_text (s , encoding = " utf-8" , strings_only = False , errors = " strict" ):
97
96
"""
98
97
Returns a text object representing 's' -- unicode on Python 2 and str on
99
98
Python 3. Treats bytestrings using the 'encoding' codec.
@@ -105,9 +104,14 @@ def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
105
104
return force_text (s , encoding , strings_only , errors )
106
105
107
106
108
- _PROTECTED_TYPES = six .integer_types + (type (None ), float , Decimal ,
109
- datetime .datetime , datetime .date ,
110
- datetime .time )
107
+ _PROTECTED_TYPES = six .integer_types + (
108
+ type (None ),
109
+ float ,
110
+ Decimal ,
111
+ datetime .datetime ,
112
+ datetime .date ,
113
+ datetime .time ,
114
+ )
111
115
112
116
113
117
def is_protected_type (obj ):
@@ -118,7 +122,7 @@ def is_protected_type(obj):
118
122
return isinstance (obj , _PROTECTED_TYPES )
119
123
120
124
121
- def force_text (s , encoding = ' utf-8' , strings_only = False , errors = ' strict' ):
125
+ def force_text (s , encoding = " utf-8" , strings_only = False , errors = " strict" ):
122
126
"""
123
127
Similar to smart_text, except that lazy instances are resolved to
124
128
strings, rather than kept as lazy objects.
@@ -136,7 +140,7 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
136
140
s = six .text_type (s , encoding , errors )
137
141
else :
138
142
s = six .text_type (s )
139
- elif hasattr (s , ' __unicode__' ):
143
+ elif hasattr (s , " __unicode__" ):
140
144
s = six .text_type (s )
141
145
else :
142
146
s = six .text_type (bytes (s ), encoding , errors )
@@ -154,12 +158,11 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
154
158
# working unicode method. Try to handle this without raising a
155
159
# further exception by individually forcing the exception args
156
160
# to unicode.
157
- s = ' ' .join (force_text (arg , encoding , strings_only , errors )
158
- for arg in s )
161
+ s = " " .join (force_text (arg , encoding , strings_only , errors ) for arg in s )
159
162
return s
160
163
161
164
162
- def smart_bytes (s , encoding = ' utf-8' , strings_only = False , errors = ' strict' ):
165
+ def smart_bytes (s , encoding = " utf-8" , strings_only = False , errors = " strict" ):
163
166
"""
164
167
Returns a bytestring version of 's', encoded as specified in 'encoding'.
165
168
If strings_only is True, don't convert (some) non-string-like objects.
@@ -170,18 +173,18 @@ def smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
170
173
return force_bytes (s , encoding , strings_only , errors )
171
174
172
175
173
- def force_bytes (s , encoding = ' utf-8' , strings_only = False , errors = ' strict' ):
176
+ def force_bytes (s , encoding = " utf-8" , strings_only = False , errors = " strict" ):
174
177
"""
175
178
Similar to smart_bytes, except that lazy instances are resolved to
176
179
strings, rather than kept as lazy objects.
177
180
If strings_only is True, don't convert (some) non-string-like objects.
178
181
"""
179
182
# Handle the common case first for performance reasons.
180
183
if isinstance (s , bytes ):
181
- if encoding == ' utf-8' :
184
+ if encoding == " utf-8" :
182
185
return s
183
186
else :
184
- return s .decode (' utf-8' , errors ).encode (encoding , errors )
187
+ return s .decode (" utf-8" , errors ).encode (encoding , errors )
185
188
if strings_only and is_protected_type (s ):
186
189
return s
187
190
if isinstance (s , Promise ):
@@ -197,13 +200,14 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
197
200
# An Exception subclass containing non-ASCII data that doesn't
198
201
# know how to print itself properly. We shouldn't raise a
199
202
# further exception.
200
- return b' ' .join (force_bytes ( arg , encoding ,
201
- strings_only , errors )
202
- for arg in s )
203
+ return b" " .join (
204
+ force_bytes ( arg , encoding , strings_only , errors ) for arg in s
205
+ )
203
206
return six .text_type (s ).encode (encoding , errors )
204
207
else :
205
208
return s .encode (encoding , errors )
206
209
210
+
207
211
if six .PY3 :
208
212
smart_str = smart_text
209
213
force_str = force_text
@@ -228,31 +232,32 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
228
232
def genarate_js_signature (params ):
229
233
keys = params .keys ()
230
234
keys .sort ()
231
- params_str = b''
235
+ params_str = b""
232
236
for key in keys :
233
- params_str += b' %s=%s&' % (smart_str (key ), smart_str (params [key ]))
237
+ params_str += b" %s=%s&" % (smart_str (key ), smart_str (params [key ]))
234
238
params_str = params_str [:- 1 ]
235
239
return sha1 (params_str ).hexdigest ()
236
240
237
241
238
242
def genarate_signature (params ):
239
243
sorted_params = sorted ([v for k , v in params .items ()])
240
- params_str = smart_str ('' .join (sorted_params ))
241
- return sha1 (str (params_str ).encode (' utf-8' )).hexdigest ()
244
+ params_str = smart_str ("" .join (sorted_params ))
245
+ return sha1 (str (params_str ).encode (" utf-8" )).hexdigest ()
242
246
243
247
244
248
def get_encoding (html = None , headers = None ):
245
249
try :
246
250
import chardet
251
+
247
252
if html :
248
- encoding = chardet .detect (html ).get (' encoding' )
253
+ encoding = chardet .detect (html ).get (" encoding" )
249
254
return encoding
250
255
except ImportError :
251
256
pass
252
257
if headers :
253
- content_type = headers .get (' content-type' )
258
+ content_type = headers .get (" content-type" )
254
259
try :
255
- encoding = content_type .split (' ' )[1 ].split ('=' )[1 ]
260
+ encoding = content_type .split (" " )[1 ].split ("=" )[1 ]
256
261
return encoding
257
262
except IndexError :
258
263
pass
@@ -275,7 +280,7 @@ def iter_multi_items(mapping):
275
280
yield item
276
281
277
282
278
- def url_quote (string , charset = ' utf-8' , errors = ' strict' , safe = '/:' , unsafe = '' ):
283
+ def url_quote (string , charset = " utf-8" , errors = " strict" , safe = "/:" , unsafe = "" ):
279
284
"""
280
285
URL encode a single string with a given encoding.
281
286
@@ -302,12 +307,12 @@ def url_quote(string, charset='utf-8', errors='strict', safe='/:', unsafe=''):
302
307
if char in safe :
303
308
rv .append (char )
304
309
else :
305
- rv .extend ((' %%%02X' % char ).encode (' ascii' ))
310
+ rv .extend ((" %%%02X" % char ).encode (" ascii" ))
306
311
return to_native (bytes (rv ))
307
312
308
313
309
- def url_quote_plus (string , charset = ' utf-8' , errors = ' strict' , safe = '' ):
310
- return url_quote (string , charset , errors , safe + ' ' , '+' ).replace (' ' , '+' )
314
+ def url_quote_plus (string , charset = " utf-8" , errors = " strict" , safe = "" ):
315
+ return url_quote (string , charset , errors , safe + " " , "+" ).replace (" " , "+" )
311
316
312
317
313
318
def _url_encode_impl (obj , charset , encode_keys , sort , key ):
@@ -321,40 +326,40 @@ def _url_encode_impl(obj, charset, encode_keys, sort, key):
321
326
key = text_type (key ).encode (charset )
322
327
if not isinstance (value , bytes ):
323
328
value = text_type (value ).encode (charset )
324
- yield url_quote_plus (key ) + '=' + url_quote_plus (value )
329
+ yield url_quote_plus (key ) + "=" + url_quote_plus (value )
325
330
326
331
327
- def url_encode (obj , charset = 'utf-8' , encode_keys = False , sort = False , key = None ,
328
- separator = b'&' ):
329
- separator = to_native (separator , 'ascii' )
332
+ def url_encode (
333
+ obj , charset = "utf-8" , encode_keys = False , sort = False , key = None , separator = b"&"
334
+ ):
335
+ separator = to_native (separator , "ascii" )
330
336
return separator .join (_url_encode_impl (obj , charset , encode_keys , sort , key ))
331
337
332
338
333
339
class WeixiErrorParser (html_parser .HTMLParser ):
334
-
335
340
def __init__ (self ):
336
341
html_parser .HTMLParser .__init__ (self )
337
342
self .recording = 0
338
343
self .data = []
339
344
340
345
def handle_starttag (self , tag , attrs ):
341
- if tag != 'h4' :
346
+ if tag != "h4" :
342
347
return
343
348
if self .recording :
344
349
self .recording += 1
345
350
self .recording = 1
346
351
347
352
def handle_endtag (self , tag ):
348
- if tag == 'h4' and self .recording :
353
+ if tag == "h4" and self .recording :
349
354
self .recording -= 1
350
355
351
356
def handle_data (self , data ):
352
357
if self .recording :
353
358
self .data .append (data )
354
359
355
360
356
- def error_parser (error_html , encoding = ' gbk' ):
357
- html = text_type (error_html , encoding or ' gbk' )
361
+ def error_parser (error_html , encoding = " gbk" ):
362
+ html = text_type (error_html , encoding or " gbk" )
358
363
error_parser = WeixiErrorParser ()
359
364
error_parser .feed (html )
360
365
if error_parser .data :
0 commit comments