Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Cython debug symbols
cython_debug/

# Distribution / packaging
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Sentry
.sentryclirc

# Staticfiles
staticfiles/
static/
media/

# Jupyter Notebook
.ipynb_checkpoints

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# PyCharm
.idea/

# VSCode
.vscode/
63 changes: 48 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ Currently, it Supports Sending Push Notification to **Firefox 46+, Chrome 52+ an

----------


Installation and Setup
----------------------

Expand All @@ -27,25 +26,36 @@ INSTALLED_APPS = (
```

If you would like to send notification to Google Chrome Users, you need to add a ``WEBPUSH_SETTINGS`` entry with the **Vapid Credentials** Like following:

```python
WEBPUSH_SETTINGS = {
"VAPID_PUBLIC_KEY": "Vapid Public Key",
"VAPID_PRIVATE_KEY":"Vapid Private Key",
"VAPID_PRIVATE_KEY": "Vapid Private Key",
"VAPID_ADMIN_EMAIL": "admin@example.com"
}
```

**Replace ``"Vapid Public Key"`` and ``"Vapid Private Key"`` with your Vapid Keys. Also replace ``admin@example.com`` with your email so that the push server of browser can reach to you if anything goes wrong.**

> **To know how to obtain Vapid Keys please see this [`py_vapid`](https://github.com/web-push-libs/vapid/tree/master/python) and [Google Developer Documentation](https://developers.google.com/web/fundamentals/push-notifications/subscribing-a-user#how_to_create_application_server_keys). You can obtain one easily from [web-push-codelab.glitch.me](https://web-push-codelab.glitch.me/). ``Application Server Keys`` and ``Vapid Keys`` both are same.**

Then include `webpush` in the `urls.py`

```python
# Django >= 2.0
from django.urls import path, include

urlpatterns = [
url(r'^webpush/', include('webpush.urls'))
path('webpush/', include('webpush.urls'))
]
```

# Django < 2.0
from django.conf.urls import url, include

urlpatterns = [
url(r'^webpush/', include('webpush.urls'))
]
```

`django-webpush` is shipped with built in **`jinja`** support.
If you would like to use with jinja backend,
Expand All @@ -67,15 +77,13 @@ TEMPLATES = [
]
```


**Then run Migration by ***`python manage.py migrate`*****



Adding Web Push Information in Template
---------------------------------------

So in template, you need to load `webpush_notifications` custom template tag by following:

- If you are using built in templating engine, add `{% load webpush_notifications %}` in the template
- If you are using **jinja** templating engine, you do not need to load anything.

Expand All @@ -85,17 +93,21 @@ Next, inside the `<head></head>` tag add `webpush_header` according to your temp
<head>
# For django templating engine
{% webpush_header %}

# For jinja templating engine
{{ webpush_header() }}
</head>
```

Next, inside the `<body></body>` tag, insert `webush_button` where you would like to see the **Subscribe to Push Messaging** Button. Like following

```html
<body>
<p> Hello World! </p>

# For django templating engine
{% webpush_button %}

# For jinja templating engine
{{ webpush_button() }}
</body>
Expand All @@ -106,8 +118,10 @@ Or if you want to add custom classes (e.g. bootstrap)
```html
<body>
<p> Hello World! </p>

# For django templating engine
{% webpush_button with_class="btn btn-outline-info" %}

# For jinja templating engine
{{ webpush_button(with_class="btn btn-outline-info") }}
</body>
Expand All @@ -122,6 +136,7 @@ Or if you want to add custom classes (e.g. bootstrap)

return render(request, 'template.html', {"webpush":webpush})
```

> **Note:** If you dont pass `group` through the `webpush` context, only logged in users can see the button for subscription and able to get notification.

----------
Expand All @@ -134,7 +149,6 @@ So in order to send notification, see below.

- If you would like to send notification to a specific group, do like following:


```python
from webpush import send_group_notification

Expand All @@ -148,6 +162,7 @@ So in order to send notification, see below.
```

- If you would like to send Notification to a specific user, do like following

```python
from webpush import send_user_notification

Expand All @@ -174,14 +189,14 @@ So in order to send notification, see below.

send_group_notification(group_name="my_group", payload=payload, ttl=1000)
```

**And the subscribers will get a notification like:**

![Web Push Notification icon](http://i.imgur.com/Vr1RMvF.png)

**That will open https://www.example.com if clicked.**

- If you want fine grained control over sending a single push message, do like following

- If you want fine grained control over sending a single push message, do like following

```python
from webpush.utils import send_to_subscription
Expand All @@ -194,18 +209,36 @@ So in order to send notification, see below.
send_to_subscription(push_info.subscription, payload)

```





**And the subscribers will get a notification like**
![Web Push Notification](http://i.imgur.com/VA6cxRc.png)

Contributing
------------

If you would like to contribute, fork the repository and send a pull request. You can also open an issue if you find any bug or want to suggest a feature.

Internationalization
---------------------

The package is shipped with built in internationalization support.

If you would like to add more language or update translation, you can run the following command:

```bash

# Add js translation
django-admin makemessages -d djangojs -l <language_code>

# Add python translation
django-admin makemessages -l <language_code>
```

After that, you can run `django-admin compilemessages` to compile the messages.

License
=======
----

Copyright © 2018 Safwan Rahman

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
Expand Down
2 changes: 2 additions & 0 deletions webpush/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

from .utils import send_notification_to_group, send_notification_to_user


def send_group_notification(group_name, payload, ttl=0, exclude_user_id=None):
payload = json.dumps(payload)
send_notification_to_group(group_name, payload, ttl, exclude_user_id)


def send_user_notification(user, payload, ttl=0):
payload = json.dumps(payload)
send_notification_to_user(user, payload, ttl)
9 changes: 6 additions & 3 deletions webpush/admin.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import json

from django.contrib import admin
from django.utils.translation import gettext_lazy as _

from .models import PushInformation
from .utils import _send_notification


class PushInfoAdmin(admin.ModelAdmin):
list_display = ("__str__", "user", "subscription", "group")

actions = ("send_test_message",)

def send_test_message(self, request, queryset):
payload = {"head": "Hey", "body": "Hello World"}
payload = {"head": _("Hey"), "body": _("Hello World")}
for device in queryset:
notification = _send_notification(device.subscription, json.dumps(payload), 0)
if notification:
self.message_user(request, "Test sent successfully")
self.message_user(request, _("Test sent successfully"))
else:
self.message_user(request, "Deprecated subscription deleted")
self.message_user(request, _("Deprecated subscription deleted"))
send_test_message.short_description = _("Send test message")


admin.site.register(PushInformation, PushInfoAdmin)
17 changes: 9 additions & 8 deletions webpush/forms.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from django import forms
from django.utils.translation import gettext_lazy as _

from .models import Group, PushInformation, SubscriptionInfo


class WebPushForm(forms.Form):
group = forms.CharField(max_length=255, required=False)
group = forms.CharField(max_length=255, required=False, label=_("Group"))
status_type = forms.ChoiceField(choices=[
('subscribe', 'subscribe'),
('unsubscribe', 'unsubscribe')
])
('subscribe', _('Subscribe')),
('unsubscribe', _('Unsubscribe'))
], label=_("Status Type"))

def save_or_delete(self, subscription, user, status_type, group_name):
# Ensure get_or_create matches exactly
Expand All @@ -18,15 +19,15 @@ def save_or_delete(self, subscription, user, status_type, group_name):
data["user"] = user

if group_name:
group, created = Group.objects.get_or_create(name=group_name)
group, _ = Group.objects.get_or_create(name=group_name)
data["group"] = group

data["subscription"] = subscription

push_info, created = PushInformation.objects.get_or_create(**data)
push_info, _ = PushInformation.objects.get_or_create(**data)

# If unsubscribe is called, that means need to delete the browser
# and notification info from server.
# and notification info from server.
if status_type == "unsubscribe":
push_info.delete()
subscription.delete()
Expand All @@ -39,5 +40,5 @@ class Meta:
fields = ('endpoint', 'auth', 'p256dh', 'browser', 'user_agent')

def get_or_save(self):
subscription, created = SubscriptionInfo.objects.get_or_create(**self.cleaned_data)
subscription, _ = SubscriptionInfo.objects.get_or_create(**self.cleaned_data)
return subscription
Binary file added webpush/locale/en/LC_MESSAGES/django.mo
Binary file not shown.
Loading