Skip to content

Commit 536d270

Browse files
committed
started refactor to new class structure
1 parent f68d15f commit 536d270

File tree

15 files changed

+406
-263
lines changed

15 files changed

+406
-263
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var/
1515
*.egg-info/
1616
.installed.cfg
1717
*.egg
18+
.eggs/
1819

1920
pip-log.txt
2021
pip-delete-this-directory.txt

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

22
publish:
3-
python setup.py sdist bdist_wheel upload
3+
python setup.py sdist bdist_wheel upload
44

55
.PHONY: publish

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ Get the list of channels in an application | *✔*
388388
Get the state of a single channel | *✔*
389389
Get a list of users in a presence channel | *✔*
390390
WebHook validation | *✔*
391-
Heroku add-on support | *✔*
391+
Heroku add-on support | *✔*
392392
Debugging & Logging | *✔*
393393
Cluster configuration | *✔*
394394
Timeouts | *✔*
@@ -402,7 +402,7 @@ These are helpers that have been implemented to to ensure interactions with the
402402

403403
Helper Functionality | Supported
404404
-----------------------------------------| :-------:
405-
Channel name validation | ✔
405+
Channel name validation | ✔
406406
Limit to 10 channels per trigger | ✔
407407
Limit event name length to 200 chars | ✔
408408

pusher/aiohttp.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
from pusher.http import process_response
77

88
class AsyncIOBackend:
9-
def __init__(self, config):
9+
def __init__(self, client):
1010
"""Adapter for the requests module.
1111
12-
:param config: pusher.Pusher object
12+
:param client: pusher.Client object
1313
"""
14-
self.config = config
14+
self.client = client
1515
self.conn = aiohttp.TCPConnector()
1616

1717
def send_request(self, request):
@@ -23,7 +23,7 @@ def send_request(self, request):
2323

2424
response = yield from asyncio.wait_for(
2525
aiohttp.request(method, url, params=params, data=data, headers=headers, connector=self.conn),
26-
timeout=self.config.timeout
26+
timeout=self.client.timeout
2727
)
2828
body = yield from response.read_and_close()
2929
return process_response(response.status, body.decode('utf8'))

pusher/client.py

Lines changed: 68 additions & 0 deletions
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 Client(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/config.py

Lines changed: 0 additions & 68 deletions
This file was deleted.

pusher/gae.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ class GAEBackend(object):
1010
"""Adapter for the URLFetch Module. Necessary for using this library with Google
1111
App Engine"""
1212

13-
def __init__(self, config, **options):
14-
self.config = config
13+
def __init__(self, client, **options):
14+
self.client = client
1515
self.options = options
1616

1717
def send_request(self, request):
@@ -20,7 +20,7 @@ def send_request(self, request):
2020
headers=request.headers,
2121
method=request.method,
2222
payload=request.body,
23-
deadline=self.config.timeout,
23+
deadline=self.client.timeout,
2424
**self.options
2525
)
2626
return process_response(resp.status_code, resp.content)

pusher/http.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
GET, POST, PUT, DELETE = "GET", "POST", "PUT", "DELETE"
1616

1717
class RequestMethod(object):
18-
def __init__(self, pusher, f):
19-
self.pusher = pusher
18+
def __init__(self, client, f):
19+
self.client = client
2020
self.f = f
2121

2222
def __call__(self, *args, **kwargs):
23-
return self.pusher.http.send_request(self.make_request(*args, **kwargs))
23+
return self.client.http.send_request(self.make_request(*args, **kwargs))
2424

2525
def make_request(self, *args, **kwargs):
26-
return self.f(self.pusher, *args, **kwargs)
26+
return self.f(self.client, *args, **kwargs)
2727

2828
def doc_string(doc):
2929
def decorator(f):
@@ -59,15 +59,15 @@ class Request(object):
5959
An instance of that object is passed to the backend's send_request method
6060
for each request.
6161
62-
:param config: an instance of pusher.Pusher
62+
:param client: an instance of pusher.Client
6363
:param method: HTTP method as a string
6464
:param path: The target path on the destination host
6565
:param params: Query params or body depending on the method
6666
"""
67-
def __init__(self, config, method, path, params=None):
67+
def __init__(self, client, method, path, params=None):
6868
if params is None:
6969
params = {}
70-
self.config = config
70+
self.client = client
7171
self.method = method
7272
self.path = path
7373
self.params = copy.copy(params)
@@ -84,7 +84,7 @@ def __init__(self, config, method, path, params=None):
8484
def _generate_auth(self):
8585
self.body_md5 = hashlib.md5(self.body).hexdigest()
8686
self.query_params.update({
87-
'auth_key': self.config.key,
87+
'auth_key': self.client.key,
8888
'body_md5': six.text_type(self.body_md5),
8989
'auth_version': '1.0',
9090
'auth_timestamp': '%.0f' % time.time()
@@ -96,7 +96,7 @@ def _generate_auth(self):
9696
make_query_string(self.query_params)
9797
])
9898

99-
self.query_params['auth_signature'] = sign(self.config.secret, auth_string)
99+
self.query_params['auth_signature'] = sign(self.client.secret, auth_string)
100100

101101
@property
102102
def query_string(self):
@@ -112,7 +112,7 @@ def url(self):
112112

113113
@property
114114
def base_url(self):
115-
return "%s://%s:%s" % (self.config.scheme, self.config.host, self.config.port)
115+
return "%s://%s:%s" % (self.client.scheme, self.client.host, self.client.port)
116116

117117
@property
118118
def headers(self):

pusher/notification_client.py

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .config import Config
1+
from .client import Client
22
from .http import POST, Request, request_method
33
from .util import ensure_text
44

@@ -9,37 +9,35 @@
99
GCM_TTL = 241920
1010
WEBHOOK_LEVELS = ['INFO', 'DEBUG', '']
1111

12-
class NotificationClient(Config):
13-
14-
def __init__(self, app_id, key, secret, ssl=True, host=None, port=None, timeout=5, cluster=None,
15-
json_encoder=None, json_decoder=None, backend=None, **backend_options):
16-
17-
super(NotificationClient, self).__init__(
18-
app_id, key, secret, ssl,
19-
host, port, timeout, cluster,
20-
json_encoder, json_decoder, backend,
21-
**backend_options)
22-
23-
if host:
24-
self._host = ensure_text(host, "host")
25-
else:
26-
self._host = DEFAULT_HOST
27-
28-
29-
@request_method
30-
def notify(self, interests, notification):
31-
if not isinstance(interests, list) and not isinstance(interests, set):
32-
raise TypeError("Interests must be a list or a set")
33-
34-
if len(interests) is 0:
35-
raise ValueError("Interests must not be empty")
36-
37-
if not isinstance(notification, dict):
38-
raise TypeError("Notification must be a dictionary")
39-
40-
params = {
41-
'interests': interests,
42-
}
43-
params.update(notification)
44-
path = "/%s/%s/apps/%s/notifications" % (API_PREFIX, API_VERSION, self.app_id)
45-
return Request(self, POST, path, params)
12+
class NotificationClient(Client):
13+
def __init__(self, app_id, key, secret, ssl=True, host=None, port=None, timeout=5, cluster=None,
14+
json_encoder=None, json_decoder=None, backend=None, **backend_options):
15+
super(NotificationClient, self).__init__(
16+
app_id, key, secret, ssl,
17+
host, port, timeout, cluster,
18+
json_encoder, json_decoder, backend,
19+
**backend_options)
20+
21+
if host:
22+
self._host = ensure_text(host, "host")
23+
else:
24+
self._host = DEFAULT_HOST
25+
26+
27+
@request_method
28+
def notify(self, interests, notification):
29+
if not isinstance(interests, list) and not isinstance(interests, set):
30+
raise TypeError("Interests must be a list or a set")
31+
32+
if len(interests) is 0:
33+
raise ValueError("Interests must not be empty")
34+
35+
if not isinstance(notification, dict):
36+
raise TypeError("Notification must be a dictionary")
37+
38+
params = {
39+
'interests': interests,
40+
}
41+
params.update(notification)
42+
path = "/%s/%s/apps/%s/notifications" % (API_PREFIX, API_VERSION, self.app_id)
43+
return Request(self, POST, path, params)

0 commit comments

Comments
 (0)