1
1
# -*- coding: utf-8 -*-
2
2
3
- from __future__ import (print_function , unicode_literals , absolute_import ,
4
- division )
3
+ from __future__ import (
4
+ print_function ,
5
+ unicode_literals ,
6
+ absolute_import ,
7
+ division )
8
+
9
+ from pusher .util import (
10
+ ensure_text ,
11
+ validate_channel ,
12
+ validate_socket_id ,
13
+ join_attributes ,
14
+ data_to_string )
15
+
5
16
from pusher .http import GET , POST , Request , request_method
6
- from pusher .signature import sign , verify
7
- from pusher .util import ensure_text , validate_channel , validate_socket_id , pusher_url_re , channel_name_re , join_attributes
8
17
from pusher .client import Client
9
18
10
-
11
19
import collections
12
20
import hashlib
13
21
import json
18
26
19
27
20
28
class PusherClient (Client ):
21
- def __init__ (self , app_id , key , secret , ssl = True , host = None , port = None , timeout = 5 , cluster = None ,
22
- json_encoder = None , json_decoder = None , backend = None , notification_host = None ,
23
- notification_ssl = True , ** backend_options ):
29
+ def __init__ (
30
+ self , app_id , key , secret , ssl = True , host = None , port = None ,
31
+ timeout = 5 , cluster = None , json_encoder = None , json_decoder = None ,
32
+ backend = None , notification_host = None , notification_ssl = True ,
33
+ ** backend_options ):
24
34
super (PusherClient , self ).__init__ (
25
- app_id , key , secret , ssl ,
26
- host , port , timeout , cluster ,
27
- json_encoder , json_decoder , backend ,
28
- ** backend_options )
35
+ app_id , key , secret , ssl , host , port , timeout , cluster ,
36
+ json_encoder , json_decoder , backend , ** backend_options )
29
37
30
38
if host :
31
39
self ._host = ensure_text (host , "host" )
40
+
32
41
elif cluster :
33
- self ._host = six .text_type ("api-%s.pusher.com" ) % ensure_text (cluster , "cluster" )
42
+ self ._host = six .text_type ("api-%s.pusher.com" ) %
43
+ ensure_text (cluster , "cluster" )
44
+
34
45
else :
35
46
self ._host = six .text_type ("api.pusherapp.com" )
36
47
@@ -40,7 +51,8 @@ def trigger(self, channels, event_name, data, socket_id=None):
40
51
if isinstance (channels , six .string_types ):
41
52
channels = [channels ]
42
53
43
- if isinstance (channels , dict ) or not isinstance (channels , (collections .Sized , collections .Iterable )):
54
+ if isinstance (channels , dict ) or not isinstance (
55
+ channels , (collections .Sized , collections .Iterable )):
44
56
raise TypeError ("Expected a single or a list of channels" )
45
57
46
58
if len (channels ) > 10 :
@@ -53,16 +65,16 @@ def trigger(self, channels, event_name, data, socket_id=None):
53
65
if len (event_name ) > 200 :
54
66
raise ValueError ("event_name too long" )
55
67
56
- data = self . _data_to_string (data )
68
+ data = data_to_string (data , self . _json_encoder )
57
69
58
70
if len (data ) > 10240 :
59
71
raise ValueError ("Too much data" )
60
72
61
73
params = {
62
74
'name' : event_name ,
63
75
'channels' : channels ,
64
- 'data' : data
65
- }
76
+ 'data' : data }
77
+
66
78
if socket_id :
67
79
params ['socket_id' ] = validate_socket_id (socket_id )
68
80
@@ -79,13 +91,14 @@ def trigger_batch(self, batch=[], already_encoded=False):
79
91
80
92
if not already_encoded :
81
93
for event in batch :
82
- event ['data' ] = self ._data_to_string (event ['data' ])
94
+ event ['data' ] = data_to_string (event ['data' ],
95
+ self ._json_encoder )
83
96
84
97
params = {
85
- 'batch' : batch
86
- }
98
+ 'batch' : batch }
87
99
88
- return Request (self , POST , "/apps/%s/batch_events" % self .app_id , params )
100
+ return Request (
101
+ self , POST , "/apps/%s/batch_events" % self .app_id , params )
89
102
90
103
91
104
@request_method
@@ -98,9 +111,13 @@ def channels_info(self, prefix_filter=None, attributes=[]):
98
111
params = {}
99
112
if attributes :
100
113
params ['info' ] = join_attributes (attributes )
114
+
101
115
if prefix_filter :
102
- params ['filter_by_prefix' ] = ensure_text (prefix_filter , "prefix_filter" )
103
- return Request (self , GET , six .text_type ("/apps/%s/channels" ) % self .app_id , params )
116
+ params ['filter_by_prefix' ] = ensure_text (
117
+ prefix_filter , "prefix_filter" )
118
+
119
+ return Request (
120
+ self , GET , six .text_type ("/apps/%s/channels" ) % self .app_id , params )
104
121
105
122
106
123
@request_method
@@ -115,7 +132,9 @@ def channel_info(self, channel, attributes=[]):
115
132
params = {}
116
133
if attributes :
117
134
params ['info' ] = join_attributes (attributes )
118
- return Request (self , GET , "/apps/%s/channels/%s" % (self .app_id , channel ), params )
135
+
136
+ return Request (
137
+ self , GET , "/apps/%s/channels/%s" % (self .app_id , channel ), params )
119
138
120
139
121
140
@request_method
@@ -127,77 +146,5 @@ def users_info(self, channel):
127
146
'''
128
147
validate_channel (channel )
129
148
130
- return Request (self , GET , "/apps/%s/channels/%s/users" % (self .app_id , channel ))
131
-
132
-
133
- def authenticate (self , channel , socket_id , custom_data = None ):
134
- """Used to generate delegated client subscription token.
135
-
136
- :param channel: name of the channel to authorize subscription to
137
- :param socket_id: id of the socket that requires authorization
138
- :param custom_data: used on presence channels to provide user info
139
- """
140
- channel = validate_channel (channel )
141
-
142
- if not channel_name_re .match (channel ):
143
- raise ValueError ('Channel should be a valid channel, got: %s' % channel )
144
-
145
- socket_id = validate_socket_id (socket_id )
146
-
147
- if custom_data :
148
- custom_data = json .dumps (custom_data , cls = self ._json_encoder )
149
-
150
- string_to_sign = "%s:%s" % (socket_id , channel )
151
-
152
- if custom_data :
153
- string_to_sign += ":%s" % custom_data
154
-
155
- signature = sign (self .secret , string_to_sign )
156
-
157
- auth = "%s:%s" % (self .key , signature )
158
- result = {'auth' : auth }
159
-
160
- if custom_data :
161
- result ['channel_data' ] = custom_data
162
-
163
- return result
164
-
165
-
166
- def validate_webhook (self , key , signature , body ):
167
- """Used to validate incoming webhook messages. When used it guarantees
168
- that the sender is Pusher and not someone else impersonating it.
169
-
170
- :param key: key used to sign the body
171
- :param signature: signature that was given with the body
172
- :param body: content that needs to be verified
173
- """
174
- key = ensure_text (key , "key" )
175
- signature = ensure_text (signature , "signature" )
176
- body = ensure_text (body , "body" )
177
-
178
- if key != self .key :
179
- return None
180
-
181
- if not verify (self .secret , body , signature ):
182
- return None
183
-
184
- try :
185
- body_data = json .loads (body , cls = self ._json_decoder )
186
- except ValueError :
187
- return None
188
-
189
- time_ms = body_data .get ('time_ms' )
190
- if not time_ms :
191
- return None
192
-
193
- if abs (time .time ()* 1000 - time_ms ) > 300000 :
194
- return None
195
-
196
- return body_data
197
-
198
-
199
- def _data_to_string (self , data ):
200
- if isinstance (data , six .string_types ):
201
- return ensure_text (data , "data" )
202
- else :
203
- return json .dumps (data , cls = self ._json_encoder )
149
+ return Request (
150
+ self , GET , "/apps/%s/channels/%s/users" % (self .app_id , channel ))
0 commit comments