Skip to content

Commit b1b3b51

Browse files
committed
Basic native push
1 parent 46fc879 commit b1b3b51

File tree

4 files changed

+120
-61
lines changed

4 files changed

+120
-61
lines changed

pusher/config.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from .util import ensure_text, app_id_re
4+
5+
import six
6+
7+
class Config(object):
8+
9+
def __init__(self, app_id, key, secret, ssl=True, host=None, port=None, timeout=5, cluster=None,
10+
json_encoder=None, json_decoder=None, backend=None, **backend_options):
11+
if backend is None:
12+
from .requests import RequestsBackend
13+
backend = RequestsBackend
14+
15+
self._app_id = ensure_text(app_id, "app_id")
16+
if not app_id_re.match(self._app_id):
17+
raise ValueError("Invalid app id")
18+
19+
self._key = ensure_text(key, "key")
20+
self._secret = ensure_text(secret, "secret")
21+
22+
if not isinstance(ssl, bool):
23+
raise TypeError("SSL should be a boolean")
24+
self._ssl = ssl
25+
26+
if port and not isinstance(port, six.integer_types):
27+
raise TypeError("port should be an integer")
28+
self._port = port or (443 if ssl else 80)
29+
30+
if not isinstance(timeout, six.integer_types):
31+
raise TypeError("timeout should be an integer")
32+
self._timeout = timeout
33+
self._json_encoder = json_encoder
34+
self._json_decoder = json_decoder
35+
36+
self.http = backend(self, **backend_options)
37+
38+
@property
39+
def app_id(self):
40+
return self._app_id
41+
42+
@property
43+
def key(self):
44+
return self._key
45+
46+
@property
47+
def secret(self):
48+
return self._secret
49+
50+
@property
51+
def host(self):
52+
return self._host
53+
54+
@property
55+
def port(self):
56+
return self._port
57+
58+
@property
59+
def timeout(self):
60+
return self._timeout
61+
62+
@property
63+
def ssl(self):
64+
return self._ssl
65+
66+
@property
67+
def scheme(self):
68+
return 'https' if self.ssl else 'http'

pusher/http.py

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ def make_query_string(params):
4343
def process_response(status, body):
4444
if status == 200:
4545
return json.loads(body)
46+
if status == 202:
47+
return True
4648
elif status == 400:
4749
raise PusherBadRequest(body)
4850
elif status == 401:

pusher/notification_client.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from .config import Config
2+
from .http import POST, Request, request_method
3+
4+
class NotificationClient(Config):
5+
6+
def __init__(self, app_id, key, secret, ssl=True, host=None, port=None, timeout=5, cluster=None,
7+
json_encoder=None, json_decoder=None, backend=None, **backend_options):
8+
9+
super(NotificationClient, self).__init__(
10+
app_id, key, secret, ssl,
11+
host, port, timeout, cluster,
12+
json_encoder, json_decoder, backend,
13+
**backend_options)
14+
15+
if host:
16+
self._host = ensure_text(host, "host")
17+
else:
18+
self._host = "yolo.ngrok.io"
19+
20+
21+
@request_method
22+
def notify(self, interests, notification):
23+
params = {
24+
'interests': interests,
25+
}
26+
params.update(notification)
27+
return Request(self, POST, "/customer_api/v1/apps/%s/notifications" % self.app_id, params)

pusher/pusher.py

+23-61
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
division)
55
from pusher.http import GET, POST, Request, request_method
66
from pusher.signature import sign, verify
7-
from pusher.util import ensure_text, validate_channel, validate_socket_id, app_id_re, pusher_url_re, channel_name_re
7+
from pusher.util import ensure_text, validate_channel, validate_socket_id, pusher_url_re, channel_name_re
8+
from pusher.config import Config
9+
from pusher.notification_client import NotificationClient
810

911
import collections
1012
import hashlib
@@ -13,11 +15,12 @@
1315
import re
1416
import six
1517
import time
18+
import copy
1619

1720
def join_attributes(attributes):
1821
return six.text_type(',').join(attributes)
1922

20-
class Pusher(object):
23+
class Pusher(Config):
2124
"""Client for the Pusher HTTP API.
2225
2326
This client supports various backend adapters to support various http
@@ -36,41 +39,25 @@ class Pusher(object):
3639
:param backend_options: additional backend
3740
"""
3841
def __init__(self, app_id, key, secret, ssl=True, host=None, port=None, timeout=5, cluster=None,
39-
json_encoder=None, json_decoder=None, backend=None, **backend_options):
40-
41-
if backend is None:
42-
from pusher.requests import RequestsBackend
43-
backend = RequestsBackend
44-
45-
self._app_id = ensure_text(app_id, "app_id")
46-
if not app_id_re.match(self._app_id):
47-
raise ValueError("Invalid app id")
48-
49-
self._key = ensure_text(key, "key")
50-
self._secret = ensure_text(secret, "secret")
51-
52-
if not isinstance(ssl, bool):
53-
raise TypeError("SSL should be a boolean")
54-
self._ssl = ssl
55-
42+
json_encoder=None, json_decoder=None, backend=None, notification_host=None,
43+
notification_ssl=True, **backend_options):
44+
super(Pusher, self).__init__(
45+
app_id, key, secret, ssl,
46+
host, port, timeout, cluster,
47+
json_encoder, json_decoder, backend,
48+
**backend_options)
5649
if host:
5750
self._host = ensure_text(host, "host")
5851
elif cluster:
5952
self._host = six.text_type("api-%s.pusher.com") % ensure_text(cluster, "cluster")
6053
else:
6154
self._host = six.text_type("api.pusherapp.com")
6255

63-
if port and not isinstance(port, six.integer_types):
64-
raise TypeError("port should be an integer")
65-
self._port = port or (443 if ssl else 80)
66-
67-
if not isinstance(timeout, six.integer_types):
68-
raise TypeError("timeout should be an integer")
69-
self._timeout = timeout
70-
self._json_encoder = json_encoder
71-
self._json_decoder = json_decoder
72-
73-
self.http = backend(self, **backend_options)
56+
self._notification_client = NotificationClient(
57+
app_id, key, secret, notification_ssl,
58+
notification_host, port, timeout, cluster,
59+
json_encoder, json_decoder, backend,
60+
**backend_options)
7461

7562
@classmethod
7663
def from_url(cls, url, **options):
@@ -116,7 +103,7 @@ def from_env(cls, env='PUSHER_URL', **options):
116103
val = os.environ.get(env)
117104
if not val:
118105
raise Exception("Environment variable %s not found" % env)
119-
106+
120107
return cls.from_url(val, **options)
121108

122109
@request_method
@@ -126,7 +113,7 @@ def trigger(self, channels, event_name, data, socket_id=None):
126113
127114
http://pusher.com/docs/rest_api#method-post-event
128115
'''
129-
116+
130117
if isinstance(channels, six.string_types):
131118
channels = [channels]
132119

@@ -280,36 +267,11 @@ def validate_webhook(self, key, signature, body):
280267
return body_data
281268

282269
@property
283-
def app_id(self):
284-
return self._app_id
285-
286-
@property
287-
def key(self):
288-
return self._key
289-
290-
@property
291-
def secret(self):
292-
return self._secret
293-
294-
@property
295-
def host(self):
296-
return self._host
297-
298-
@property
299-
def port(self):
300-
return self._port
301-
302-
@property
303-
def timeout(self):
304-
return self._timeout
270+
def notification_client(self):
271+
return self._notification_client
305272

306-
@property
307-
def ssl(self):
308-
return self._ssl
309-
310-
@property
311-
def scheme(self):
312-
return 'https' if self.ssl else 'http'
273+
def notify(self, interests, notification):
274+
self._notification_client.notify(interests, notification)
313275

314276
def _data_to_string(self, data):
315277
if isinstance(data, six.string_types):

0 commit comments

Comments
 (0)