Skip to content

Commit

Permalink
Merge pull request #88 from stefan-qsd/develop
Browse files Browse the repository at this point in the history
APNS2 push support
  • Loading branch information
qsoftdevelopment authored Feb 21, 2020
2 parents 99055dd + edf9639 commit d88b9a7
Show file tree
Hide file tree
Showing 14 changed files with 250 additions and 23 deletions.
14 changes: 13 additions & 1 deletion .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
name: python
version: 4.3.0
version: 4.4.0
schema: 1
scm: github.com/pubnub/python
changelog:
- version: v4.4.0
date: Feb 20, 2020
changes:
- type: feature
text: Add support for APNS2 Push API
- version: v4.3.0
date: Jan 28, 2020
changes:
Expand Down Expand Up @@ -178,11 +183,18 @@ features:
- CHANNEL-GROUPS-REMOVE-CHANNELS
- CHANNEL-GROUPS-REMOVE-GROUPS
- CHANNEL-GROUPS-LIST-CHANNELS-IN-GROUP
others:
- TELEMETRY
- CREATE-PUSH-PAYLOAD
push:
- PUSH-ADD-DEVICE-TO-CHANNELS
- PUSH-REMOVE-DEVICE-FROM-CHANNELS
- PUSH-LIST-CHANNELS-FROM-DEVICE
- PUSH-REMOVE-DEVICE
- PUSH-TYPE-APNS
- PUSH-TYPE-APNS2
- PUSH-TYPE-FCM
- PUSH-TYPE-MPNS
presence:
- PRESENCE-HERE-NOW
- PRESENCE-WHERE-NOW
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## [4.4.0](https://github.com/pubnub/python/tree/v4.4.0)

[Full Changelog](https://github.com/pubnub/python/compare/v4.3.0...v4.4.0)

- 🌟 Add support for APNS2 Push API

## [4.3.0](https://github.com/pubnub/python/tree/v4.3.0)

[Full Changelog](https://github.com/pubnub/python/compare/v4.2.1...v4.3.0)
Expand Down
39 changes: 34 additions & 5 deletions pubnub/endpoints/push/add_channels_to_push.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import six

from pubnub.endpoints.endpoint import Endpoint
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, \
PNERR_PUSH_TOPIC_MISSING
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
from pubnub.models.consumer.push import PNPushAddChannelResult
from pubnub import utils


class AddChannelsToPush(Endpoint):
# v1/push/sub-key/{subKey}/devices/{pushToken}
ADD_PATH = "/v1/push/sub-key/%s/devices/%s"
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}
ADD_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s"

def __init__(self, pubnub):
Endpoint.__init__(self, pubnub)
self._channels = None
self._device_id = None
self._push_type = None
self._topic = None
self._environment = None

def channels(self, channels):
self._channels = channels
Expand All @@ -30,17 +35,37 @@ def push_type(self, push_type):
self._push_type = push_type
return self

def topic(self, topic):
self._topic = topic
return self

def environment(self, environment):
self._environment = environment
return self

def custom_params(self):
params = {}

params['add'] = utils.join_items(self._channels)
params['type'] = utils.push_type_to_string(self._push_type)

if self._push_type != PNPushType.APNS2:
params['type'] = utils.push_type_to_string(self._push_type)
else:
if self._environment is None:
self._environment = PNPushEnvironment.DEVELOPMENT

params['environment'] = self._environment
params['topic'] = self._topic

return params

def build_path(self):
return AddChannelsToPush.ADD_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
if self._push_type != PNPushType.APNS2:
return AddChannelsToPush.ADD_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
else:
return AddChannelsToPush.ADD_PATH_APNS2 % (
self.pubnub.config.subscribe_key, self._device_id)

def http_method(self):
return HttpMethod.GET
Expand All @@ -57,6 +82,10 @@ def validate_params(self):
if self._push_type is None:
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)

if self._push_type == PNPushType.APNS2:
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)

def create_response(self, envelope):
return PNPushAddChannelResult()

Expand Down
37 changes: 32 additions & 5 deletions pubnub/endpoints/push/list_push_provisions.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import six

from pubnub.endpoints.endpoint import Endpoint
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, PNERR_PUSH_TOPIC_MISSING
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
from pubnub.models.consumer.push import PNPushListProvisionsResult
from pubnub import utils


class ListPushProvisions(Endpoint):
# v1/push/sub-key/{subKey}/devices/{pushToken}
LIST_PATH = "/v1/push/sub-key/%s/devices/%s"
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}
LIST_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s"

def __init__(self, pubnub):
Endpoint.__init__(self, pubnub)
self._device_id = None
self._push_type = None
self._topic = None
self._environment = None

def device_id(self, device_id):
self._device_id = device_id
Expand All @@ -25,16 +29,35 @@ def push_type(self, push_type):
self._push_type = push_type
return self

def topic(self, topic):
self._topic = topic
return self

def environment(self, environment):
self._environment = environment
return self

def custom_params(self):
params = {}

params['type'] = utils.push_type_to_string(self._push_type)
if self._push_type != PNPushType.APNS2:
params['type'] = utils.push_type_to_string(self._push_type)
else:
if self._environment is None:
self._environment = PNPushEnvironment.DEVELOPMENT

params['environment'] = self._environment
params['topic'] = self._topic

return params

def build_path(self):
return ListPushProvisions.LIST_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
if self._push_type != PNPushType.APNS2:
return ListPushProvisions.LIST_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
else:
return ListPushProvisions.LIST_PATH_APNS2 % (
self.pubnub.config.subscribe_key, self._device_id)

def http_method(self):
return HttpMethod.GET
Expand All @@ -48,6 +71,10 @@ def validate_params(self):
if self._push_type is None:
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)

if self._push_type == PNPushType.APNS2:
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)

def create_response(self, channels):
if channels is not None and len(channels) > 0 and isinstance(channels, list):
return PNPushListProvisionsResult(channels)
Expand Down
40 changes: 35 additions & 5 deletions pubnub/endpoints/push/remove_channels_from_push.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
import six

from pubnub.endpoints.endpoint import Endpoint
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, \
PNERR_PUSH_TOPIC_MISSING
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
from pubnub.models.consumer.push import PNPushRemoveChannelResult
from pubnub import utils


class RemoveChannelsFromPush(Endpoint):
# v1/push/sub-key/{subKey}/devices/{pushToken}
REMOVE_PATH = "/v1/push/sub-key/%s/devices/%s"
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}
REMOVE_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s"

def __init__(self, pubnub):
Endpoint.__init__(self, pubnub)
self._channels = None
self._device_id = None
self._push_type = None
self._topic = None
self._environment = None

def channels(self, channels):
self._channels = channels
Expand All @@ -30,14 +35,35 @@ def push_type(self, push_type):
self._push_type = push_type
return self

def topic(self, topic):
self._topic = topic
return self

def environment(self, environment):
self._environment = environment
return self

def custom_params(self):
params = {'remove': utils.join_items(self._channels), 'type': utils.push_type_to_string(self._push_type)}
params = {'remove': utils.join_items(self._channels)}

if self._push_type != PNPushType.APNS2:
params['type'] = utils.push_type_to_string(self._push_type)
else:
if self._environment is None:
self._environment = PNPushEnvironment.DEVELOPMENT

params['environment'] = self._environment
params['topic'] = self._topic

return params

def build_path(self):
return RemoveChannelsFromPush.REMOVE_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
if self._push_type != PNPushType.APNS2:
return RemoveChannelsFromPush.REMOVE_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
else:
return RemoveChannelsFromPush.REMOVE_PATH_APNS2 % (
self.pubnub.config.subscribe_key, self._device_id)

def http_method(self):
return HttpMethod.GET
Expand All @@ -54,6 +80,10 @@ def validate_params(self):
if self._push_type is None:
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)

if self._push_type == PNPushType.APNS2:
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)

def create_response(self, envelope):
return PNPushRemoveChannelResult()

Expand Down
37 changes: 32 additions & 5 deletions pubnub/endpoints/push/remove_device.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import six

from pubnub.endpoints.endpoint import Endpoint
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, PNERR_PUSH_TOPIC_MISSING
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
from pubnub.models.consumer.push import PNPushRemoveAllChannelsResult
from pubnub import utils


class RemoveDeviceFromPush(Endpoint):
# v1/push/sub-key/{subKey}/devices/{pushToken}/remove
REMOVE_PATH = "/v1/push/sub-key/%s/devices/%s/remove"
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}/remove
REMOVE_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s/remove"

def __init__(self, pubnub):
Endpoint.__init__(self, pubnub)
self._device_id = None
self._push_type = None
self._topic = None
self._environment = None

def device_id(self, device_id):
self._device_id = device_id
Expand All @@ -25,16 +29,35 @@ def push_type(self, push_type):
self._push_type = push_type
return self

def topic(self, topic):
self._topic = topic
return self

def environment(self, environment):
self._environment = environment
return self

def custom_params(self):
params = {}

params['type'] = utils.push_type_to_string(self._push_type)
if self._push_type != PNPushType.APNS2:
params['type'] = utils.push_type_to_string(self._push_type)
else:
if self._environment is None:
self._environment = PNPushEnvironment.DEVELOPMENT

params['environment'] = self._environment
params['topic'] = self._topic

return params

def build_path(self):
return RemoveDeviceFromPush.REMOVE_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
if self._push_type != PNPushType.APNS2:
return RemoveDeviceFromPush.REMOVE_PATH % (
self.pubnub.config.subscribe_key, self._device_id)
else:
return RemoveDeviceFromPush.REMOVE_PATH_APNS2 % (
self.pubnub.config.subscribe_key, self._device_id)

def http_method(self):
return HttpMethod.GET
Expand All @@ -48,6 +71,10 @@ def validate_params(self):
if self._push_type is None:
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)

if self._push_type == PNPushType.APNS2:
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)

def create_response(self, envelope):
return PNPushRemoveAllChannelsResult()

Expand Down
6 changes: 6 additions & 0 deletions pubnub/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class PNPushType(object):
APNS = 1
MPNS = 2
GCM = 3
APNS2 = 4


class PNResourceType(object):
Expand All @@ -115,3 +116,8 @@ class PNResourceType(object):
class PNMatchType(object):
RESOURCE = "resource"
PATTERN = "pattern"


class PNPushEnvironment(object):
DEVELOPMENT = "development"
PRODUCTION = "production"
2 changes: 2 additions & 0 deletions pubnub/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@
PNERR_HISTORY_MESSAGE_ACTIONS_MULTIPLE_CHANNELS = "History can return message action data for a single channel only. " \
"Either pass a single channel or disable the include_message_action" \
"s flag. "

PNERR_PUSH_TOPIC_MISSING = "Push notification topic is missing. Required only if push type is APNS2."
2 changes: 1 addition & 1 deletion pubnub/pubnub_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

class PubNubCore:
"""A base class for PubNub Python API implementations"""
SDK_VERSION = "4.3.0"
SDK_VERSION = "4.4.0"
SDK_NAME = "PubNub-Python"

TIMESTAMP_DIVIDER = 1000
Expand Down
Loading

0 comments on commit d88b9a7

Please sign in to comment.