68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
# combo-plugin-gnm - Combo WebPush App
|
|
# Copyright (C) 2018 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from django.conf import settings
|
|
from django.db import transaction
|
|
from django.utils.timezone import is_naive, make_aware
|
|
|
|
from pywebpush import WebPushException
|
|
from retrying import retry
|
|
from webpush.utils import _send_notification
|
|
|
|
from .models import WebPushRecord
|
|
|
|
|
|
def retry_if_webpush_exception(exception):
|
|
'''Return True if we should retry'''
|
|
return isinstance(exception, WebPushException)
|
|
|
|
|
|
@retry(wait_exponential_multiplier=1000,
|
|
wait_exponential_max=getattr(settings, 'WEBPUSH_BACKOFF_MAXMILLISECS', 10000),
|
|
retry_on_exception=retry_if_webpush_exception)
|
|
def send_web_push(notification, since=None):
|
|
'''Get all the user subscriptions (every browsers with authoorized notifications)
|
|
and send a push mesg to each one
|
|
'''
|
|
if is_naive(since):
|
|
since = make_aware(since)
|
|
user_subscription_list = notification.user.webpush_info.select_related("subscription")
|
|
responses = []
|
|
for sub_info in user_subscription_list:
|
|
with transaction.atomic():
|
|
web_push_record, created = WebPushRecord.objects.select_for_update().get_or_create(
|
|
notification=notification,
|
|
subscription=sub_info)
|
|
|
|
if web_push_record.status == WebPushRecord.DEFAULT_STATUS and \
|
|
web_push_record.creation_date >= since:
|
|
# check the user's subscription and send the request to the endpoint
|
|
req = _send_notification(sub_info, web_push_record.payload, web_push_record.ttl)
|
|
# requests.Response object
|
|
if req.status_code <= 201:
|
|
web_push_record.status = web_push_record.OK_STATUS
|
|
web_push_record.save()
|
|
responses += [req]
|
|
else:
|
|
web_push_record.status = web_push_record.ERR_STATUS
|
|
web_push_record.save()
|
|
|
|
else:
|
|
web_push_record.set_status_err()
|
|
|
|
return responses
|