Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-django-push-notifications for 
openSUSE:Factory checked in at 2022-05-12 22:59:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-push-notifications (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-push-notifications.new.1538 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-push-notifications"

Thu May 12 22:59:44 2022 rev:3 rq:976289 version:3.0.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-push-notifications/python-django-push-notifications.changes
        2021-12-26 15:53:41.204102998 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-django-push-notifications.new.1538/python-django-push-notifications.changes
      2022-05-12 23:00:09.340780314 +0200
@@ -1,0 +2,32 @@
+Wed May 11 10:11:10 UTC 2022 - pgaj...@suse.com
+
+- version update to 3.0.0
+  * #567 Fixes crash on bulk_send test message operation from admin by 
@DataGreed in #568
+  * Updated README: added info about APNS_AUTH_KEY_PATH, APNS_AUTH_KEY_ID, 
APNS_TEAM_ID by @DataGreed in #566
+  * Add some details to APNS settings description by @scherbakovx in #575
+  * Django 4.0 warnings by @jheld in #585
+  * Run tests on python3.9 by @bertonha in #589
+  * add mutable_content to fcm by @paradizer in #582
+  * Improve efficiency of ORM lookups by @code-review-doctor in #598
+  * Drop python 2.x and django before 2.2 by @sevdog in #599
+  * Migrate to GitHub Actions. by @jezdez in #607
+  * Mention WebPushDevice in README by @Tyilo in #608
+  * Make push optional dependecies by @sevdog in #600
+  * fix: Remove python3.5 deps by @bertonha in #621
+  * Spelling error & convert string to be translatable by @Andrew-Chen-Wang in 
#614
+  * ++Enable sending image in GCM notifications by @ashishnitinpatil in #624
+  * [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in #625
+  * Change feature detection logic for database field by @sevdog in #612
+  * Add Edge support to webpush by @simonkern in #631
+  * chore: test on Django 4.0 by @bertonha in #638
+  * chore: test only active Django versions by @bertonha in #639
+  * chore: dry tests, use newer DRF on tests by @bertonha in #641
+  * [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in #635
+  * More robust handling of userAgentData, fix WebPushDeviceAdmin by 
@simonkern in #643
+  * [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in #644
+  * Add missing migration for #614 by @simonkern in #645
+  * Jazzband: Synced file(s) with jazzband/.github by @jazzband-bot in #626
+  * Show coverage badge in README. by @shimakaze-git in #651
+- python-mock is not required for build
+
+-------------------------------------------------------------------

Old:
----
  django-push-notifications-2.0.0.tar.gz

New:
----
  django-push-notifications-3.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-django-push-notifications.spec ++++++
--- /var/tmp/diff_new_pack.bilt6Q/_old  2022-05-12 23:00:09.872781028 +0200
+++ /var/tmp/diff_new_pack.bilt6Q/_new  2022-05-12 23:00:09.876781033 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-django-push-notifications
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-django-push-notifications
-Version:        2.0.0
+Version:        3.0.0
 Release:        0
 Summary:        Django package to send push notifications to mobile devices
 License:        MIT
@@ -34,12 +34,14 @@
 # SECTION test requirements
 BuildRequires:  %{python_module Django >= 1.11}
 BuildRequires:  %{python_module apns2}
-BuildRequires:  %{python_module djangorestframework >= 3.7}
 BuildRequires:  %{python_module django-codemod}
-BuildRequires:  %{python_module mock}
+BuildRequires:  %{python_module djangorestframework >= 3.7}
+BuildRequires:  %{python_module pip}
+BuildRequires:  %{python_module pytest-cov}
 BuildRequires:  %{python_module pytest-django}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module pywebpush >= 1.3.0}
+BuildRequires:  %{python_module wheel}
 # /SECTION
 %python_subpackages
 
@@ -52,10 +54,10 @@
 djcodemod run --removed-in 4.0 push_notifications/{admin,fields,models}.py
 
 %build
-%python_build
+%pyproject_wheel
 
 %install
-%python_install
+%pyproject_install
 %python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check

++++++ django-push-notifications-2.0.0.tar.gz -> 
django-push-notifications-3.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/.github/workflows/release.yml 
new/django-push-notifications-3.0.0/.github/workflows/release.yml
--- old/django-push-notifications-2.0.0/.github/workflows/release.yml   
1970-01-01 01:00:00.000000000 +0100
+++ new/django-push-notifications-3.0.0/.github/workflows/release.yml   
2022-02-14 03:43:49.000000000 +0100
@@ -0,0 +1,40 @@
+name: Release
+
+on:
+  push:
+    tags:
+    - '*'
+
+jobs:
+  build:
+    if: github.repository == 'jazzband/django-push-notifications'
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.8
+
+      - name: Install dependencies
+        run: |
+          python -m pip install -U pip
+          python -m pip install -U setuptools twine wheel
+
+      - name: Build package
+        run: |
+          python setup.py --version
+          python setup.py sdist --format=gztar bdist_wheel
+          twine check dist/*
+
+      - name: Upload packages to Jazzband
+        if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
+        uses: pypa/gh-action-pypi-publish@master
+        with:
+          user: jazzband
+          password: ${{ secrets.JAZZBAND_RELEASE_KEY }}
+          repository_url: 
https://jazzband.co/projects/django-push-notifications/upload
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/.github/workflows/test.yml 
new/django-push-notifications-3.0.0/.github/workflows/test.yml
--- old/django-push-notifications-2.0.0/.github/workflows/test.yml      
1970-01-01 01:00:00.000000000 +0100
+++ new/django-push-notifications-3.0.0/.github/workflows/test.yml      
2022-02-14 03:43:49.000000000 +0100
@@ -0,0 +1,48 @@
+name: Test
+
+on: [push, pull_request]
+
+jobs:
+  build:
+    name: build (Python ${{ matrix.python-version }}, Django ${{ 
matrix.django-version }})
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: ['3.6', '3.7', '3.8', '3.9']
+
+    steps:
+    - uses: actions/checkout@v2
+
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v2
+      with:
+        python-version: ${{ matrix.python-version }}
+
+    - name: Get pip cache dir
+      id: pip-cache
+      run: |
+        echo "::set-output name=dir::$(pip cache dir)"
+
+    - name: Cache
+      uses: actions/cache@v2
+      with:
+        path: ${{ steps.pip-cache.outputs.dir }}
+        key:
+          ${{ matrix.python-version }}-v1-${{ hashFiles('**/setup.cfg') }}-${{ 
hashFiles('**/tox.ini') }}
+        restore-keys: |
+          ${{ matrix.python-version }}-v1-
+
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip
+        python -m pip install --upgrade tox tox-gh-actions
+
+    - name: Tox tests
+      run: |
+        tox -v
+
+    - name: Upload coverage
+      uses: codecov/codecov-action@v1
+      with:
+        name: Python ${{ matrix.python-version }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/.gitignore 
new/django-push-notifications-3.0.0/.gitignore
--- old/django-push-notifications-2.0.0/.gitignore      2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/.gitignore      2022-02-14 
03:43:49.000000000 +0100
@@ -16,3 +16,11 @@
 # tox
 .tox
 *.egg-info/
+.eggs
+
+# coverage
+.coverage
+coverage.xml
+
+# vscode files
+.vscode/*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/.pre-commit-config.yaml 
new/django-push-notifications-3.0.0/.pre-commit-config.yaml
--- old/django-push-notifications-2.0.0/.pre-commit-config.yaml 2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/.pre-commit-config.yaml 2022-02-14 
03:43:49.000000000 +0100
@@ -2,13 +2,13 @@
 # See https://pre-commit.com/hooks.html for more hooks
 repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v2.4.0
+    rev: v4.1.0
     hooks:
     -   id: trailing-whitespace
     -   id: end-of-file-fixer
     -   id: check-yaml
     -   id: check-added-large-files
 -   repo: https://github.com/asottile/pyupgrade
-    rev: v1.25.2
+    rev: v2.31.0
     hooks:
     -   id: pyupgrade
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/.travis.yml 
new/django-push-notifications-3.0.0/.travis.yml
--- old/django-push-notifications-2.0.0/.travis.yml     2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/.travis.yml     1970-01-01 
01:00:00.000000000 +0100
@@ -1,38 +0,0 @@
-# https://travis-ci.org/jazzband/django-push-notifications
-sudo: false
-language: python
-python:
-- 3.5
-- 3.6
-- 3.7
-- 3.8
-cache: pip
-dist: xenial
-install: travis_retry pip install tox-travis
-script: tox
-stages:
-- test
-- name: deploy
-  if: repo = jazzband/django-push-notifications AND tag IS present
-jobs:
-  include:
-  - stage: test
-  - stage: deploy
-    install: skip
-    script: skip
-    python: 3.7
-    env: skip
-    deploy:
-      provider: pypi
-      user: jazzband
-      server: https://jazzband.co/projects/django-push-notifications/upload
-      distributions: sdist bdist_wheel
-      password:
-        secure: 
ICRZGeqLWsqEtg9Iz62SHGOktUQEN+8h4wp0RKJJhcPIj59aKJNV+ET1wM+Xsh6OgpX2Ddy2AF7vD7pDP8kbWyCVyQNeK2/Ejo9SC7tVaVUIf5VAFXmkMymlAwUc6lKYrLW2Ls4PEqvSKikHcHp20pna6jJvg0Msa11j/KYP9eM=
-      on:
-        tags: true
-        repo: jazzband/django-push-notifications
-notifications:
-  email:
-    on_failure: always
-    on_success: change
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/CODE_OF_CONDUCT.md 
new/django-push-notifications-3.0.0/CODE_OF_CONDUCT.md
--- old/django-push-notifications-2.0.0/CODE_OF_CONDUCT.md      1970-01-01 
01:00:00.000000000 +0100
+++ new/django-push-notifications-3.0.0/CODE_OF_CONDUCT.md      2022-02-14 
03:43:49.000000000 +0100
@@ -0,0 +1,46 @@
+# Code of Conduct
+
+As contributors and maintainers of the Jazzband projects, and in the interest 
of
+fostering an open and welcoming community, we pledge to respect all people who
+contribute through reporting issues, posting feature requests, updating 
documentation,
+submitting pull requests or patches, and other activities.
+
+We are committed to making participation in the Jazzband a harassment-free 
experience
+for everyone, regardless of the level of experience, gender, gender identity 
and
+expression, sexual orientation, disability, personal appearance, body size, 
race,
+ethnicity, age, religion, or nationality.
+
+Examples of unacceptable behavior by participants include:
+
+- The use of sexualized language or imagery
+- Personal attacks
+- Trolling or insulting/derogatory comments
+- Public or private harassment
+- Publishing other's private information, such as physical or electronic 
addresses,
+  without explicit permission
+- Other unethical or unprofessional conduct
+
+The Jazzband roadies have the right and responsibility to remove, edit, or 
reject
+comments, commits, code, wiki edits, issues, and other contributions that are 
not
+aligned to this Code of Conduct, or to ban temporarily or permanently any 
contributor
+for other behaviors that they deem inappropriate, threatening, offensive, or 
harmful.
+
+By adopting this Code of Conduct, the roadies commit themselves to fairly and
+consistently applying these principles to every aspect of managing the jazzband
+projects. Roadies who do not follow or enforce the Code of Conduct may be 
permanently
+removed from the Jazzband roadies.
+
+This code of conduct applies both within project spaces and in public spaces 
when an
+individual is representing the project or its community.
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be 
reported by
+contacting the roadies at `road...@jazzband.co`. All complaints will be 
reviewed and
+investigated and will result in a response that is deemed necessary and 
appropriate to
+the circumstances. Roadies are obligated to maintain confidentiality with 
regard to the
+reporter of an incident.
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], 
version
+1.3.0, available at [https://contributor-covenant.org/version/1/3/0/][version]
+
+[homepage]: https://contributor-covenant.org
+[version]: https://contributor-covenant.org/version/1/3/0/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/README.rst 
new/django-push-notifications-3.0.0/README.rst
--- old/django-push-notifications-2.0.0/README.rst      2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/README.rst      2022-02-14 
03:43:49.000000000 +0100
@@ -1,15 +1,21 @@
 django-push-notifications
 =========================
-.. image:: 
https://travis-ci.org/jazzband/django-push-notifications.svg?branch=master
-       :target: https://travis-ci.org/jazzband/django-push-notifications
 
 .. image:: https://jazzband.co/static/img/badge.svg
-       :target: https://jazzband.co/
-       :alt: Jazzband
+   :target: https://jazzband.co/
+   :alt: Jazzband
 
-A minimal Django app that implements Device models that can send messages 
through APNS, FCM/GCM and WNS.
+.. image:: 
https://github.com/jazzband/django-push-notifications/workflows/Test/badge.svg
+   :target: https://github.com/jazzband/django-push-notifications/actions
+   :alt: GitHub Actions
 
-The app implements three models: ``GCMDevice``, ``APNSDevice`` and 
``WNSDevice``. Those models share the same attributes:
+.. image:: 
https://codecov.io/gh/jazzband/django-push-notifications/branch/master/graph/badge.svg?token=PcC594rhI4
+   :target: https://codecov.io/gh/jazzband/django-push-notifications
+   :alt: Code coverage
+
+A minimal Django app that implements Device models that can send messages 
through APNS, FCM/GCM, WNS and WebPush.
+
+The app implements four models: ``GCMDevice``, ``APNSDevice``, ``WNSDevice`` 
and ``WebPushDevice``. Those models share the same attributes:
  - ``name`` (optional): A name for the device.
  - ``active`` (default True): A boolean that determines whether the device 
will be sent notifications.
  - ``user`` (optional): A foreign key to auth.User, if you wish to link the 
device to a specific user.
@@ -18,18 +24,19 @@
 
 
 The app also implements an admin panel, through which you can test single and 
bulk notifications. Select one or more
-FCM/GCM, APNS or WNS devices and in the action dropdown, select "Send test 
message" or "Send test message in bulk", accordingly.
+FCM/GCM, APNS, WNS or WebPush devices and in the action dropdown, select "Send 
test message" or "Send test message in bulk", accordingly.
 Note that sending a non-bulk test message to more than one device will just 
iterate over the devices and send multiple
 single messages.
 UPDATE_ON_DUPLICATE_REG_ID: Transform create of an existing Device (based on 
registration id) into a update. See below Update of device with duplicate 
registration ID for more details.
 
 Dependencies
 ------------
-- Python 3.5+
-- Django 1.11+
+- Python 3.6+
+- Django 2.2+
 - For the API module, Django REST Framework 3.7+ is required.
-- For WebPush (WP), pywebpush 1.3.0+ is required. py-vapid 1.3.0+ is required 
for generating the WebPush private key; however this
+- For WebPush (WP), pywebpush 1.3.0+ is required (optional). py-vapid 1.3.0+ 
is required for generating the WebPush private key; however this
   step does not need to occur on the application server.
+- For Apple Push (APNS), apns2 0.3+ is required (optional).
 
 Setup
 -----
@@ -37,7 +44,7 @@
 
 .. code-block:: shell
 
-       $ pip install django-push-notifications
+       $ pip install django-push-notifications[WP,APNS]
 
 
 Edit your settings.py file:
@@ -67,6 +74,7 @@
        If you are planning on running your project with 
``APNS_USE_SANDBOX=True``, then make sure you have set the
        *development* certificate as your ``APNS_CERTIFICATE``. Otherwise the 
app will not be able to connect to the correct host. See settings_ for details.
 
+
 For more information about how to generate certificates, see `docs/APNS 
<https://github.com/jazzband/django-push-notifications/blob/master/docs/APNS.rst>`_.
 
 You can learn more about APNS certificates `here 
<https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html>`_.
@@ -91,10 +99,13 @@
 
 **APNS settings**
 
-- ``APNS_CERTIFICATE``: Absolute path to your APNS certificate file. 
Certificates with passphrases are not supported. Read more about `Generation of 
an APNS PEM file 
<https://github.com/jazzband/django-push-notifications/blob/master/docs/APNS.rst>`_.
+- ``APNS_CERTIFICATE``: Absolute path to your APNS certificate file. 
Certificates with passphrases are not supported. If iOS application was build 
with "Release" flag, you need to use production certificate, otherwise debug. 
Read more about `Generation of an APNS PEM file 
<https://github.com/jazzband/django-push-notifications/blob/master/docs/APNS.rst>`_.
+- ``APNS_AUTH_KEY_PATH``: Absolute path to your APNS signing key file for 
`Token-Based Authentication 
<https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns>`_
 . Use this instead of ``APNS_CERTIFICATE`` if you are using ``.p8`` signing 
key certificate.
+- ``APNS_AUTH_KEY_ID``: The 10-character Key ID you obtained from your Apple 
developer account
+- ``APNS_TEAM_ID``: 10-character Team ID you use for developing your 
company???s apps for iOS.
 - ``APNS_TOPIC``: The topic of the remote notification, which is typically the 
bundle ID for your app. If you omit this header and your APNs certificate does 
not specify multiple topics, the APNs server uses the certificate???s Subject 
as the default topic.
 - ``APNS_USE_ALTERNATIVE_PORT``: Use port 2197 for APNS, instead of default 
port 443.
-- ``APNS_USE_SANDBOX``: Use 'api.development.push.apple.com', instead of 
default host 'api.push.apple.com'.
+- ``APNS_USE_SANDBOX``: Use 'api.development.push.apple.com', instead of 
default host 'api.push.apple.com'. Default value depends on ``DEBUG`` setting 
of your environment: if ``DEBUG`` is True and you use production certificate, 
you should explicitly set ``APNS_USE_SANDBOX`` to False.
 
 **FCM/GCM settings**
 
@@ -183,7 +194,49 @@
                }
                return outputArray;
        }
-       function loadVersionBrowser (userAgent) {
+
+       function loadVersionBrowser () {
+               if ("userAgentData" in navigator) {
+                       // navigator.userAgentData is not available in
+                       // Firefox and Safari
+                       const uaData = navigator.userAgentData;
+                       // Outputs of navigator.userAgentData.brands[n].brand 
are e.g.
+                       // Chrome: 'Google Chrome'
+                       // Edge: 'Microsoft Edge'
+                       // Opera: 'Opera'
+                       let browsername;
+                       let browserversion;
+                       let chromeVersion = null;
+                       for (var i = 0; i < uaData.brands.length; i++) {
+                               let brand = uaData.brands[i].brand;
+                               browserversion = uaData.brands[i].version;
+                               if 
(brand.match(/opera|chrome|edge|safari|firefox|msie|trident/i) !== null) {
+                                       // If we have a chrome match, save the 
match, but try to find another match
+                                       // E.g. Edge can also produce a false 
Chrome match.
+                                       if (brand.match(/chrome/i) !== null) {
+                                               chromeVersion = browserversion;
+                                       }
+                                       // If this is not a chrome match return 
immediately
+                                       else {
+                                               browsername = 
brand.substr(brand.indexOf(' ')+1);
+                                               return {
+                                                       name: browsername,
+                                                       version: browserversion
+                                               }
+                                       }
+                               }
+                       }
+                       // No non-Chrome match was found. If we have a chrome 
match, return it.
+                       if (chromeVersion !== null) {
+                               return {
+                                       name: "chrome",
+                                       version: chromeVersion
+                               }
+                       }
+               }
+               // If no userAgentData is not present, or if no match via 
userAgentData was found,
+               // try to extract the browser name and version from userAgent
+               const userAgent = navigator.userAgent;
                var ua = userAgent, tem, M = 
ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
                if (/trident/i.test(M[1])) {
                        tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/__init__.py 
new/django-push-notifications-3.0.0/push_notifications/__init__.py
--- old/django-push-notifications-2.0.0/push_notifications/__init__.py  
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/__init__.py  
2022-02-14 03:43:49.000000000 +0100
@@ -1,4 +1,8 @@
-import pkg_resources
+try:
+    # Python 3.8+
+    import importlib.metadata as importlib_metadata
+except ImportError:
+    # <Python 3.7 and lower
+    import importlib_metadata
 
-
-__version__ = pkg_resources.require("django-push-notifications")[0].version
+__version__ = importlib_metadata.version("django-push-notifications")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/admin.py 
new/django-push-notifications-3.0.0/push_notifications/admin.py
--- old/django-push-notifications-2.0.0/push_notifications/admin.py     
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/admin.py     
2022-02-14 03:43:49.000000000 +0100
@@ -1,13 +1,11 @@
 from django.apps import apps
 from django.contrib import admin, messages
-from django.utils.encoding import force_text
-from django.utils.translation import ugettext_lazy as _
+from django.utils.encoding import force_str
+from django.utils.translation import gettext_lazy as _
 
-from .apns import APNSServerError
-from .gcm import GCMError
+from .exceptions import APNSServerError, GCMError, WebPushError
 from .models import APNSDevice, GCMDevice, WebPushDevice, WNSDevice
 from .settings import PUSH_NOTIFICATIONS_SETTINGS as SETTINGS
-from .webpush import WebPushError
 
 
 User = apps.get_model(*SETTINGS["USER_MODEL"].split("."))
@@ -45,7 +43,7 @@
                        except APNSServerError as e:
                                errors.append(e.status)
                        except WebPushError as e:
-                               errors.append(force_text(e))
+                               errors.append(force_str(e))
 
                        if bulk:
                                break
@@ -57,13 +55,21 @@
                                if "error" in r["results"][0]:
                                        errors.append(r["results"][0]["error"])
                else:
-                       try:
-                               errors = [r["error"] for r in 
ret[0][0]["results"] if "error" in r]
-                       except TypeError:
-                               for entry in ret[0][0]:
-                                       errors = errors + [r["error"] for r in 
entry["results"] if "error" in r]
-                       except IndexError:
-                               pass
+                       if "results" in ret[0][0]:
+                               try:
+                                       errors = [r["error"] for r in 
ret[0][0]["results"] if "error" in r]
+                               except TypeError:
+                                       for entry in ret[0][0]:
+                                               errors = errors + [r["error"] 
for r in entry["results"] if "error" in r]
+                               except IndexError:
+                                       pass
+                       else:
+                               # different format, e.g.:
+                               # [{'some_token1': 'Success',
+                               #  'some_token2': 'BadDeviceToken'}]
+                               for key, value in ret[0][0].items():
+                                       if value.lower() != "success":
+                                               errors.append(value)
                if errors:
                        self.message_user(
                                request, _("Some messages could not be 
processed: %r" % (", ".join(errors))),
@@ -73,14 +79,24 @@
                        if bulk:
                                # When the queryset exceeds the max_recipients 
value, the
                                # send_message method returns a list of dicts, 
one per chunk
-                               try:
-                                       success = ret[0][0]["success"]
-                               except TypeError:
-                                       success = 0
-                                       for entry in ret[0][0]:
-                                               success = success + 
entry["success"]
-                               if success == 0:
-                                       return
+                               if "results" in ret[0][0]:
+                                       try:
+                                               success = ret[0][0]["success"]
+                                       except TypeError:
+                                               success = 0
+                                               for entry in ret[0][0]:
+                                                       success = success + 
entry["success"]
+                                       if success == 0:
+                                               return
+                               else:
+                                       # different format, e.g.:
+                                       # [{'some_token1': 'Success',
+                                       #  'some_token2': 'BadDeviceToken'}]
+                                       success = []
+                                       for key, value in ret[0][0].items():
+                                               if value.lower() == "success":
+                                                       success.append(key)
+
                        elif len(errors) == len(ret):
                                return
                        if errors:
@@ -117,7 +133,17 @@
        list_filter = ("active", "cloud_message_type")
 
 
+class WebPushDeviceAdmin(DeviceAdmin):
+       list_display = ("__str__", "browser", "user", "active", "date_created")
+       list_filter = ("active", "browser")
+
+       if hasattr(User, "USERNAME_FIELD"):
+               search_fields = ("name", "registration_id", "user__%s" % 
(User.USERNAME_FIELD))
+       else:
+               search_fields = ("name", "registration_id")
+
+
 admin.site.register(APNSDevice, DeviceAdmin)
 admin.site.register(GCMDevice, GCMDeviceAdmin)
 admin.site.register(WNSDevice, DeviceAdmin)
-admin.site.register(WebPushDevice, DeviceAdmin)
+admin.site.register(WebPushDevice, WebPushDeviceAdmin)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/api/rest_framework.py 
new/django-push-notifications-3.0.0/push_notifications/api/rest_framework.py
--- 
old/django-push-notifications-2.0.0/push_notifications/api/rest_framework.py    
    2020-03-10 12:03:47.000000000 +0100
+++ 
new/django-push-notifications-3.0.0/push_notifications/api/rest_framework.py    
    2022-02-14 03:43:49.000000000 +0100
@@ -132,7 +132,7 @@
 
 
 # Mixins
-class DeviceViewSetMixin(object):
+class DeviceViewSetMixin:
        lookup_field = "registration_id"
 
        def create(self, request, *args, **kwargs):
@@ -168,7 +168,7 @@
                return super(DeviceViewSetMixin, 
self).perform_update(serializer)
 
 
-class AuthorizedMixin(object):
+class AuthorizedMixin:
        permission_classes = (permissions.IsAuthenticated, IsOwner)
 
        def get_queryset(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/apns.py 
new/django-push-notifications-3.0.0/push_notifications/apns.py
--- old/django-push-notifications-2.0.0/push_notifications/apns.py      
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/apns.py      
2022-02-14 03:43:49.000000000 +0100
@@ -13,21 +13,7 @@
 
 from . import models
 from .conf import get_manager
-from .exceptions import NotificationError
-
-
-class APNSError(NotificationError):
-       pass
-
-
-class APNSUnsupportedPriority(APNSError):
-       pass
-
-
-class APNSServerError(APNSError):
-       def __init__(self, status):
-               super(APNSServerError, self).__init__(status)
-               self.status = status
+from .exceptions import APNSError, APNSUnsupportedPriority, APNSServerError
 
 
 def _apns_create_socket(creds=None, application_id=None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/compat.py 
new/django-push-notifications-3.0.0/push_notifications/compat.py
--- old/django-push-notifications-2.0.0/push_notifications/compat.py    
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/compat.py    
2022-02-14 03:43:49.000000000 +0100
@@ -1,10 +1,4 @@
 # flake8:noqa
-
-try:
-       from urllib.error import HTTPError
-       from urllib.parse import urlencode
-       from urllib.request import Request, urlopen
-except ImportError:
-       # Python 2 support
-       from urllib2 import HTTPError, Request, urlopen
-       from urllib import urlencode
+from urllib.error import HTTPError
+from urllib.parse import urlencode
+from urllib.request import Request, urlopen
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/conf/app.py 
new/django-push-notifications-3.0.0/push_notifications/conf/app.py
--- old/django-push-notifications-2.0.0/push_notifications/conf/app.py  
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/conf/app.py  
2022-02-14 03:43:49.000000000 +0100
@@ -231,6 +231,7 @@
                application_config.setdefault("POST_URL", {
                        "CHROME": "https://fcm.googleapis.com/fcm/send";,
                        "OPERA": "https://fcm.googleapis.com/fcm/send";,
+                       "EDGE": "https://wns2-par02p.notify.windows.com/w";,
                        "FIREFOX": 
"https://updates.push.services.mozilla.com/wpush/v2";,
                })
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/conf/base.py 
new/django-push-notifications-3.0.0/push_notifications/conf/base.py
--- old/django-push-notifications-2.0.0/push_notifications/conf/base.py 
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/conf/base.py 
2022-02-14 03:43:49.000000000 +0100
@@ -1,7 +1,7 @@
 from django.core.exceptions import ImproperlyConfigured
 
 
-class BaseConfig(object):
+class BaseConfig:
        def has_auth_token_creds(self, application_id=None):
                raise NotImplementedError
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/conf/legacy.py 
new/django-push-notifications-3.0.0/push_notifications/conf/legacy.py
--- old/django-push-notifications-2.0.0/push_notifications/conf/legacy.py       
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/conf/legacy.py       
2022-02-14 03:43:49.000000000 +0100
@@ -9,7 +9,7 @@
 ]
 
 
-class empty(object):
+class empty:
        pass
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/exceptions.py 
new/django-push-notifications-3.0.0/push_notifications/exceptions.py
--- old/django-push-notifications-2.0.0/push_notifications/exceptions.py        
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/exceptions.py        
2022-02-14 03:43:49.000000000 +0100
@@ -1,2 +1,27 @@
 class NotificationError(Exception):
        pass
+
+
+# APNS
+class APNSError(NotificationError):
+       pass
+
+
+class APNSUnsupportedPriority(APNSError):
+       pass
+
+
+class APNSServerError(APNSError):
+       def __init__(self, status):
+               super().__init__(status)
+               self.status = status
+
+
+# GCM
+class GCMError(NotificationError):
+       pass
+
+
+# Web Push
+class WebPushError(NotificationError):
+       pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/fields.py 
new/django-push-notifications-3.0.0/push_notifications/fields.py
--- old/django-push-notifications-2.0.0/push_notifications/fields.py    
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/fields.py    
2022-02-14 03:43:49.000000000 +0100
@@ -4,7 +4,7 @@
 from django import forms
 from django.core.validators import MaxValueValidator, MinValueValidator, 
RegexValidator
 from django.db import connection, models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 
 __all__ = ["HexadecimalField", "HexIntegerField"]
@@ -14,16 +14,14 @@
 
 
 hex_re = re.compile(r"^(([0-9A-f])|(0x[0-9A-f]))+$")
-signed_integer_engines = [
-       "django.db.backends.postgresql",
-       "django.db.backends.postgresql_psycopg2",
-       "django.contrib.gis.db.backends.postgis",
-       "django.db.backends.sqlite3"
+signed_integer_vendors = [
+       "postgresql",
+       "sqlite",
 ]
 
 
 def _using_signed_storage():
-       return connection.settings_dict["ENGINE"] in signed_integer_engines
+       return connection.vendor in signed_integer_vendors
 
 
 def _signed_to_unsigned_integer(value):
@@ -79,10 +77,9 @@
        ]
 
        def db_type(self, connection):
-               engine = connection.settings_dict["ENGINE"]
-               if "mysql" in engine:
+               if "mysql" == connection.vendor:
                        return "bigint unsigned"
-               elif "sqlite" in engine:
+               elif "sqlite" == connection.vendor:
                        return "UNSIGNED BIG INT"
                else:
                        return super(HexIntegerField, 
self).db_type(connection=connection)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/gcm.py 
new/django-push-notifications-3.0.0/push_notifications/gcm.py
--- old/django-push-notifications-2.0.0/push_notifications/gcm.py       
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/gcm.py       
2022-02-14 03:43:49.000000000 +0100
@@ -11,7 +11,7 @@
 
 from .compat import Request, urlopen
 from .conf import get_manager
-from .exceptions import NotificationError
+from .exceptions import GCMError
 from .models import GCMDevice
 
 
@@ -22,18 +22,13 @@
 ]
 FCM_OPTIONS_KEYS = [
        "collapse_key", "priority", "content_available", "delay_while_idle", 
"time_to_live",
-       "restricted_package_name", "dry_run"
+       "restricted_package_name", "dry_run", "mutable_content"
 ]
 FCM_NOTIFICATIONS_PAYLOAD_KEYS = [
-       "title", "body", "icon", "sound", "badge", "color", "tag", 
"click_action",
+       "title", "body", "icon", "image", "sound", "badge", "color", "tag", 
"click_action",
        "body_loc_key", "body_loc_args", "title_loc_key", "title_loc_args", 
"android_channel_id"
 ]
 
-
-class GCMError(NotificationError):
-       pass
-
-
 def _chunks(l, n):
        """
        Yield successive chunks from list \a l with a minimum size \a n
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/migrations/0008_webpush_add_edge.py
 
new/django-push-notifications-3.0.0/push_notifications/migrations/0008_webpush_add_edge.py
--- 
old/django-push-notifications-2.0.0/push_notifications/migrations/0008_webpush_add_edge.py
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/django-push-notifications-3.0.0/push_notifications/migrations/0008_webpush_add_edge.py
  2022-02-14 03:43:49.000000000 +0100
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.8 on 2021-11-12 09:49
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('push_notifications', '0007_uniquesetting'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='webpushdevice',
+            name='browser',
+            field=models.CharField(choices=[('CHROME', 'Chrome'), ('FIREFOX', 
'Firefox'), ('OPERA', 'Opera'), ('EDGE', 'Edge')], default='CHROME', 
help_text='Currently only support to Chrome, Firefox, Edge and Opera browsers', 
max_length=10, verbose_name='Browser'),
+        ),
+    ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/migrations/0009_alter_apnsdevice_device_id.py
 
new/django-push-notifications-3.0.0/push_notifications/migrations/0009_alter_apnsdevice_device_id.py
--- 
old/django-push-notifications-2.0.0/push_notifications/migrations/0009_alter_apnsdevice_device_id.py
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/django-push-notifications-3.0.0/push_notifications/migrations/0009_alter_apnsdevice_device_id.py
        2022-02-14 03:43:49.000000000 +0100
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.9 on 2022-01-10 09:03
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('push_notifications', '0008_webpush_add_edge'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='apnsdevice',
+            name='device_id',
+            field=models.UUIDField(blank=True, db_index=True, help_text='UUID 
/ UIDevice.identifierForVendor()', null=True, verbose_name='Device ID'),
+        ),
+    ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/models.py 
new/django-push-notifications-3.0.0/push_notifications/models.py
--- old/django-push-notifications-2.0.0/push_notifications/models.py    
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/models.py    
2022-02-14 03:43:49.000000000 +0100
@@ -1,5 +1,5 @@
 from django.db import models
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
 
 from .fields import HexIntegerField
 from .settings import PUSH_NOTIFICATIONS_SETTINGS as SETTINGS
@@ -14,6 +14,7 @@
        ("CHROME", "Chrome"),
        ("FIREFOX", "Firefox"),
        ("OPERA", "Opera"),
+       ("EDGE", "Edge")
 )
 
 
@@ -56,7 +57,7 @@
 
 class GCMDeviceQuerySet(models.query.QuerySet):
        def send_message(self, message, **kwargs):
-               if self:
+               if self.exists():
                        from .gcm import send_message as gcm_send_message
 
                        data = kwargs.pop("extra", {})
@@ -121,7 +122,7 @@
 
 class APNSDeviceQuerySet(models.query.QuerySet):
        def send_message(self, message, creds=None, **kwargs):
-               if self:
+               if self.exists():
                        from .apns import apns_send_bulk_message
 
                        app_ids = 
self.filter(active=True).order_by("application_id")\
@@ -145,7 +146,7 @@
 class APNSDevice(Device):
        device_id = models.UUIDField(
                verbose_name=_("Device ID"), blank=True, null=True, 
db_index=True,
-               help_text="UDID / UIDevice.identifierForVendor()"
+               help_text=_("UUID / UIDevice.identifierForVendor()")
        )
        registration_id = models.CharField(
                verbose_name=_("Registration ID"), max_length=200, 
unique=SETTINGS["UNIQUE_REG_ID"]
@@ -240,7 +241,7 @@
        browser = models.CharField(
                verbose_name=_("Browser"), max_length=10,
                choices=BROWSER_TYPES, default=BROWSER_TYPES[0][0],
-               help_text=_("Currently only support to Chrome, Firefox and 
Opera browsers")
+               help_text=_("Currently only support to Chrome, Firefox, Edge 
and Opera browsers")
        )
        objects = WebPushDeviceManager()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/settings.py 
new/django-push-notifications-3.0.0/push_notifications/settings.py
--- old/django-push-notifications-2.0.0/push_notifications/settings.py  
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/settings.py  
2022-02-14 03:43:49.000000000 +0100
@@ -41,6 +41,7 @@
        "CHROME": PUSH_NOTIFICATIONS_SETTINGS["FCM_POST_URL"],
        "OPERA": PUSH_NOTIFICATIONS_SETTINGS["FCM_POST_URL"],
        "FIREFOX": "https://updates.push.services.mozilla.com/wpush/v2";,
+       "EDGE": "https://wns2-par02p.notify.windows.com/w";,
 })
 PUSH_NOTIFICATIONS_SETTINGS.setdefault("WP_PRIVATE_KEY", None)
 PUSH_NOTIFICATIONS_SETTINGS.setdefault("WP_CLAIMS", None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/push_notifications/webpush.py 
new/django-push-notifications-3.0.0/push_notifications/webpush.py
--- old/django-push-notifications-2.0.0/push_notifications/webpush.py   
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/push_notifications/webpush.py   
2022-02-14 03:43:49.000000000 +0100
@@ -1,11 +1,7 @@
 from pywebpush import WebPushException, webpush
 
 from .conf import get_manager
-from .exceptions import NotificationError
-
-
-class WebPushError(NotificationError):
-       pass
+from .exceptions import WebPushError
 
 
 def get_subscription_info(application_id, uri, browser, auth, p256dh):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/pyproject.toml 
new/django-push-notifications-3.0.0/pyproject.toml
--- old/django-push-notifications-2.0.0/pyproject.toml  1970-01-01 
01:00:00.000000000 +0100
+++ new/django-push-notifications-3.0.0/pyproject.toml  2022-02-14 
03:43:49.000000000 +0100
@@ -0,0 +1,6 @@
+[build-system]
+requires = ["setuptools>=30.3.0", "wheel", "setuptools_scm"]
+
+[tool.pytest.ini_options]
+minversion = "6.0"
+addopts = "--cov push_notifications --cov-append --cov-branch --cov-report 
term-missing --cov-report=xml"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/setup.cfg 
new/django-push-notifications-3.0.0/setup.cfg
--- old/django-push-notifications-2.0.0/setup.cfg       2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/setup.cfg       2022-02-14 
03:43:49.000000000 +0100
@@ -1,6 +1,5 @@
 [metadata]
 name = django-push-notifications
-version = 2.0.0
 description = Send push notifications to mobile devices through GCM, APNS or 
WNS and to WebPush (Chrome, Firefox and Opera) in Django
 author = Jerome Leclanche
 author_email = jer...@leclan.ch
@@ -10,32 +9,40 @@
        Development Status :: 5 - Production/Stable
        Environment :: Web Environment
        Framework :: Django
-       Framework :: Django :: 1.11
-       Framework :: Django :: 2.0
-       Framework :: Django :: 2.1
        Framework :: Django :: 2.2
        Framework :: Django :: 3.0
+       Framework :: Django :: 3.1
+       Framework :: Django :: 3.2
+       Framework :: Django :: 4.0
        Intended Audience :: Developers
        License :: OSI Approved :: MIT License
        Programming Language :: Python
        Programming Language :: Python :: 3
-       Programming Language :: Python :: 3.5
        Programming Language :: Python :: 3.6
        Programming Language :: Python :: 3.7
        Programming Language :: Python :: 3.8
+       Programming Language :: Python :: 3.9
        Topic :: Internet :: WWW/HTTP
        Topic :: System :: Networking
 
 [options]
+python_requires = >= 3.6
 packages = find:
 install_requires =
-       apns2>=0.3.0,<0.6.0;python_version<"3.5"
-       apns2>=0.3.0;python_version>="3.5"
+       Django>=2.2
+
+setup_requires =
+       setuptools_scm
+
+[options.extras_require]
+APNS =
+       apns2>=0.3.0
+       importlib-metadata;python_version < "3.8"
        pywebpush>=1.3.0
-       Django>=1.11
+       Django>=2.2
+
+WP = pywebpush>=1.3.0
+
 
 [options.packages.find]
 exclude = tests
-
-[bdist_wheel]
-universal = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/setup.py 
new/django-push-notifications-3.0.0/setup.py
--- old/django-push-notifications-2.0.0/setup.py        2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/setup.py        2022-02-14 
03:43:49.000000000 +0100
@@ -1,6 +1,4 @@
 #!/usr/bin/env python
-
 from setuptools import setup
 
-
-setup()
+setup(use_scm_version={"version_scheme": "post-release"})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/tests/_mock.py 
new/django-push-notifications-3.0.0/tests/_mock.py
--- old/django-push-notifications-2.0.0/tests/_mock.py  2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/tests/_mock.py  1970-01-01 
01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-try:
-       from unittest import mock  # noqa
-except ImportError:
-       from mock import mock  # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/tests/test_apns_models.py 
new/django-push-notifications-3.0.0/tests/test_apns_models.py
--- old/django-push-notifications-2.0.0/tests/test_apns_models.py       
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/tests/test_apns_models.py       
2022-02-14 03:43:49.000000000 +0100
@@ -1,13 +1,13 @@
+from unittest import mock
+
 from apns2.client import NotificationPriority
 from apns2.errors import BadTopic, PayloadTooLarge, Unregistered
 from django.conf import settings
 from django.test import TestCase, override_settings
 
-from push_notifications.apns import APNSError
+from push_notifications.exceptions import APNSError
 from push_notifications.models import APNSDevice
 
-from ._mock import mock
-
 
 class APNSModelTestCase(TestCase):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/tests/test_apns_push_payload.py 
new/django-push-notifications-3.0.0/tests/test_apns_push_payload.py
--- old/django-push-notifications-2.0.0/tests/test_apns_push_payload.py 
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/tests/test_apns_push_payload.py 
2022-02-14 03:43:49.000000000 +0100
@@ -1,9 +1,10 @@
+from unittest import mock
+
 from apns2.client import NotificationPriority
 from django.test import TestCase
 
-from push_notifications.apns import APNSUnsupportedPriority, _apns_send
-
-from ._mock import mock
+from push_notifications.apns import _apns_send
+from push_notifications.exceptions import APNSUnsupportedPriority
 
 
 class APNSPushPayloadTest(TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/tests/test_gcm_push_payload.py 
new/django-push-notifications-3.0.0/tests/test_gcm_push_payload.py
--- old/django-push-notifications-2.0.0/tests/test_gcm_push_payload.py  
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/tests/test_gcm_push_payload.py  
2022-02-14 03:43:49.000000000 +0100
@@ -1,8 +1,9 @@
+from unittest import mock
+
 from django.test import TestCase
 
 from push_notifications.gcm import send_bulk_message, send_message
 
-from ._mock import mock
 from .responses import GCM_JSON, GCM_JSON_MULTIPLE
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-push-notifications-2.0.0/tests/test_legacy_config.py 
new/django-push-notifications-3.0.0/tests/test_legacy_config.py
--- old/django-push-notifications-2.0.0/tests/test_legacy_config.py     
2020-03-10 12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/tests/test_legacy_config.py     
2022-02-14 03:43:49.000000000 +0100
@@ -2,7 +2,8 @@
 from django.test import TestCase
 
 from push_notifications.conf import LegacyConfig, get_manager
-from push_notifications.webpush import WebPushError, webpush_send_message
+from push_notifications.exceptions import WebPushError
+from push_notifications.webpush import webpush_send_message
 
 
 class LegacyConfigTestCase(TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/tests/test_models.py 
new/django-push-notifications-3.0.0/tests/test_models.py
--- old/django-push-notifications-2.0.0/tests/test_models.py    2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/tests/test_models.py    2022-02-14 
03:43:49.000000000 +0100
@@ -1,4 +1,5 @@
 import json
+from unittest import mock
 
 from django.test import TestCase
 from django.utils import timezone
@@ -8,7 +9,6 @@
 from push_notifications.models import APNSDevice, GCMDevice
 
 from . import responses
-from ._mock import mock
 
 
 class GCMModelTestCase(TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/tests/test_wns.py 
new/django-push-notifications-3.0.0/tests/test_wns.py
--- old/django-push-notifications-2.0.0/tests/test_wns.py       2020-03-10 
12:03:47.000000000 +0100
+++ new/django-push-notifications-3.0.0/tests/test_wns.py       2022-02-14 
03:43:49.000000000 +0100
@@ -1,3 +1,4 @@
+from unittest import mock
 import xml.etree.ElementTree as ET
 
 from django.test import TestCase
@@ -6,8 +7,6 @@
        dict_to_xml_schema, wns_send_bulk_message, wns_send_message
 )
 
-from ._mock import mock
-
 
 class WNSSendMessageTestCase(TestCase):
        def setUp(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-push-notifications-2.0.0/tox.ini 
new/django-push-notifications-3.0.0/tox.ini
--- old/django-push-notifications-2.0.0/tox.ini 2020-03-10 12:03:47.000000000 
+0100
+++ new/django-push-notifications-3.0.0/tox.ini 2022-02-14 03:43:49.000000000 
+0100
@@ -1,37 +1,52 @@
 [tox]
+skipsdist = True
+usedevelop = true
 envlist =
-       py{35,36,37,38}-django{111,20,21,22}-apns{030,060}
-       py{36,37,38}-django30-apns{030,060}
-       py37-flake8
+    py{36,37,38,39}-dj{22,32}
+    py{38,39}-dj{40,main}
+    flake8
+
+[gh-actions]
+python =
+    3.6: py36
+    3.7: py37
+    3.8: py38
+    3.9: py39, flake8
+
+[gh-actions:env]
+DJANGO =
+    2.2: dj22
+    3.2: dj32
+    4.0: dj40
+    main: djmain
 
 [testenv]
+usedevelop = true
 setenv =
-       PYTHONWARNINGS = all
-       DJANGO_SETTINGS_MODULE = tests.settings
-       PYTHONPATH = {toxinidir}
+    PYTHONWARNINGS = all
+    DJANGO_SETTINGS_MODULE = tests.settings
+    PYTHONPATH = {toxinidir}
 commands =
-       pytest
-       pytest --ds=tests.settings_unique tests/tst_unique.py
+    pytest
+    pytest --ds=tests.settings_unique tests/tst_unique.py
 deps =
-       pytest
-       pytest-django
-       mock
-       pywebpush
-       djangorestframework>=3.7
-       django111: Django>=1.11,<2.0
-       django20: Django>=2.0,<2.1
-       django21: Django>=2.1,<2.2
-       django22: Django>=2.2,<3.0
-       django30: Django>=3.0,<3.1
-       apns030: apns2>=0.3.0,<0.6.0
-       apns060: apns2>=0.6.0
+    apns2
+    pytest
+    pytest-cov
+    pytest-django
+    pywebpush
+    djangorestframework
+    dj22: Django>=2.2,<3.0
+    dj32: Django>=3.2,<3.3
+    dj40: Django>=4.0,<4.1
+    djmain: https://github.com/django/django/archive/main.tar.gz
 
-[testenv:py37-flake8]
+[testenv:flake8]
 commands = flake8 --exit-zero
 deps =
-       flake8==3.5.0
-       flake8-isort
-       flake8-quotes
+    flake8
+    flake8-isort
+    flake8-quotes
 
 [flake8]
 ignore = W191,E503

Reply via email to