openSUSE Commits
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
November 2023
- 1 participants
- 1691 discussions
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-cachy for openSUSE:Factory checked in at 2023-11-30 22:00:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cachy (Old)
and /work/SRC/openSUSE:Factory/.python-cachy.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-cachy"
Thu Nov 30 22:00:47 2023 rev:6 rq:1129799 version:0.3.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cachy/python-cachy.changes 2023-05-08 17:24:41.656840776 +0200
+++ /work/SRC/openSUSE:Factory/.python-cachy.new.25432/python-cachy.changes 2023-11-30 22:01:35.693664620 +0100
@@ -1,0 +2,6 @@
+Wed Nov 29 12:32:31 UTC 2023 - Daniel Garcia <daniel.garcia(a)suse.com>
+
+- Add upstream patch flexmock-0.11.patch to make tests work with
+ latest version of python-flexmock gh#sdispater/cachy#19
+
+-------------------------------------------------------------------
New:
----
flexmock-0.11.patch
BETA DEBUG BEGIN:
New:
- Add upstream patch flexmock-0.11.patch to make tests work with
latest version of python-flexmock gh#sdispater/cachy#19
BETA DEBUG END:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-cachy.spec ++++++
--- /var/tmp/diff_new_pack.021LHb/_old 2023-11-30 22:01:36.333688198 +0100
+++ /var/tmp/diff_new_pack.021LHb/_new 2023-11-30 22:01:36.337688345 +0100
@@ -25,6 +25,8 @@
URL: https://github.com/sdispater/cachy
Source: https://files.pythonhosted.org/packages/source/c/cachy/cachy-%{version}.tar…
Patch0: support-pymemcache.patch
+# PATCH-FIX-UPSTREAM flexmock-0.11.patch, gh#sdispater/cachy#19
+Patch1: flexmock-0.11.patch
BuildRequires: %{python_module fakeredis >= 0.10.2}
BuildRequires: %{python_module flexmock >= 0.10.2}
BuildRequires: %{python_module msgpack-python >= 0.5}
@@ -63,5 +65,6 @@
%files %{python_files}
%license LICENSE
%doc README.rst
-%{python_sitelib}/*
+%{python_sitelib}/cachy
+%{python_sitelib}/cachy-%{version}*-info
++++++ flexmock-0.11.patch ++++++
From d6fd558be00e3818d01bd1f6a5290bd094a87e52 Mon Sep 17 00:00:00 2001
From: Stefano Rivera <stefano(a)rivera.za.net>
Date: Tue, 9 Nov 2021 23:09:46 -0800
Subject: [PATCH] No need to teardown flexmock
flexmock patches unittest to hook tearing down, itself.
The flexmock_teardown() function is a private API that was moved in
0.11.0.
---
tests/stores/test_dict_store.py | 5 +----
tests/stores/test_file_store.py | 4 +---
tests/stores/test_redis_store.py | 2 --
tests/test_cache_manager.py | 5 +----
tests/test_repository.py | 5 +----
tests/test_tagged_cache.py | 5 +----
6 files changed, 5 insertions(+), 21 deletions(-)
diff --git a/tests/stores/test_dict_store.py b/tests/stores/test_dict_store.py
index b2574a3..8d4171f 100644
--- a/tests/stores/test_dict_store.py
+++ b/tests/stores/test_dict_store.py
@@ -1,16 +1,13 @@
# -*- coding: utf-8 -*-
from unittest import TestCase
-from flexmock import flexmock, flexmock_teardown
+from flexmock import flexmock
from cachy.stores import DictStore
class DictStoreTestCase(TestCase):
- def tearDown(self):
- flexmock_teardown()
-
def test_items_can_be_set_and_retrieved(self):
store = DictStore()
store.put('foo', 'bar', 10)
diff --git a/tests/stores/test_file_store.py b/tests/stores/test_file_store.py
index 10ab336..704612d 100644
--- a/tests/stores/test_file_store.py
+++ b/tests/stores/test_file_store.py
@@ -7,7 +7,7 @@
import shutil
from unittest import TestCase
-from flexmock import flexmock, flexmock_teardown
+from flexmock import flexmock
from cachy.serializers import JsonSerializer
from cachy.stores import FileStore
@@ -29,8 +29,6 @@ def tearDown(self):
if os.path.isdir(e):
shutil.rmtree(e)
- flexmock_teardown()
-
def test_none_is_returned_if_file_doesnt_exist(self):
mock = flexmock(os.path)
mock.should_receive('exists').once().and_return(False)
diff --git a/tests/stores/test_redis_store.py b/tests/stores/test_redis_store.py
index a5009f4..82e1fb4 100644
--- a/tests/stores/test_redis_store.py
+++ b/tests/stores/test_redis_store.py
@@ -4,7 +4,6 @@
import redis
from unittest import TestCase
-from flexmock import flexmock, flexmock_teardown
from fakeredis import FakeServer
from fakeredis import FakeStrictRedis
from cachy.stores import RedisStore
@@ -23,7 +22,6 @@ def setUp(self):
super(RedisStoreTestCase, self).setUp()
def tearDown(self):
- flexmock_teardown()
self.redis.flushdb()
def test_get_returns_null_when_not_found(self):
diff --git a/tests/test_cache_manager.py b/tests/test_cache_manager.py
index ae9dda4..b5da411 100644
--- a/tests/test_cache_manager.py
+++ b/tests/test_cache_manager.py
@@ -3,7 +3,7 @@
import os
import tempfile
from unittest import TestCase
-from flexmock import flexmock, flexmock_teardown
+from flexmock import flexmock
from cachy import CacheManager, Repository
from cachy.stores import DictStore, FileStore
@@ -12,9 +12,6 @@
class RepositoryTestCase(TestCase):
- def tearDown(self):
- flexmock_teardown()
-
def test_store_get_the_correct_store(self):
cache = CacheManager({
'default': 'dict',
diff --git a/tests/test_repository.py b/tests/test_repository.py
index aeb53b7..f7b3bf5 100644
--- a/tests/test_repository.py
+++ b/tests/test_repository.py
@@ -2,7 +2,7 @@
import datetime
from unittest import TestCase
-from flexmock import flexmock, flexmock_teardown
+from flexmock import flexmock
from cachy import Repository
from cachy.contracts.store import Store
@@ -10,9 +10,6 @@
class RepositoryTestCase(TestCase):
- def tearDown(self):
- flexmock_teardown()
-
def test_get_returns_value_from_cache(self):
repo = self._get_repository()
repo.get_store().should_receive('get').once().with_args('foo').and_return('bar')
diff --git a/tests/test_tagged_cache.py b/tests/test_tagged_cache.py
index cefdc69..79e986c 100644
--- a/tests/test_tagged_cache.py
+++ b/tests/test_tagged_cache.py
@@ -7,14 +7,11 @@
from cachy.tag_set import TagSet
from cachy.redis_tagged_cache import RedisTaggedCache
from datetime import datetime, timedelta
-from flexmock import flexmock, flexmock_teardown
+from flexmock import flexmock
class TaggedCacheTestCase(TestCase):
- def tearDown(self):
- flexmock_teardown()
-
def test_tags_can_be_flushed(self):
store = DictStore()
1
0
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 2023-11-30 22:00:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-push-notifications (Old)
and /work/SRC/openSUSE:Factory/.python-django-push-notifications.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-push-notifications"
Thu Nov 30 22:00:42 2023 rev:5 rq:1129794 version:3.0.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-django-push-notifications/python-django-push-notifications.changes 2023-01-06 17:06:38.652548151 +0100
+++ /work/SRC/openSUSE:Factory/.python-django-push-notifications.new.25432/python-django-push-notifications.changes 2023-11-30 22:01:31.313503262 +0100
@@ -1,0 +2,12 @@
+Wed Nov 29 12:14:57 UTC 2023 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 3.0.2:
+ * LegacyConfig.get_apns_use_alternative_port always return None
+ * Add django 4.1, remove master branch
+ * Update topic send_message docs in README
+ * Fix: HexadecimalField accepts non-hex values
+ * Expanded documentation for Web Push
+ * Allow APNS tokens of variable length.
+ * Add WebPush support for Safari
+
+-------------------------------------------------------------------
Old:
----
django-push-notifications-3.0.0.tar.gz
New:
----
django-push-notifications-3.0.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-django-push-notifications.spec ++++++
--- /var/tmp/diff_new_pack.V1bYh5/_old 2023-11-30 22:01:31.933526103 +0100
+++ /var/tmp/diff_new_pack.V1bYh5/_new 2023-11-30 22:01:31.933526103 +0100
@@ -16,9 +16,9 @@
#
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%{?sle15_python_module_pythons}
Name: python-django-push-notifications
-Version: 3.0.0
+Version: 3.0.2
Release: 0
Summary: Django package to send push notifications to mobile devices
License: MIT
++++++ django-push-notifications-3.0.0.tar.gz -> django-push-notifications-3.0.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/.github/workflows/release.yml new/django-push-notifications-3.0.2/.github/workflows/release.yml
--- old/django-push-notifications-3.0.0/.github/workflows/release.yml 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/.github/workflows/release.yml 2023-10-29 17:59:32.000000000 +0100
@@ -8,7 +8,7 @@
jobs:
build:
if: github.repository == 'jazzband/django-push-notifications'
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/.github/workflows/test.yml new/django-push-notifications-3.0.2/.github/workflows/test.yml
--- old/django-push-notifications-3.0.0/.github/workflows/test.yml 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/.github/workflows/test.yml 2023-10-29 17:59:32.000000000 +0100
@@ -5,7 +5,7 @@
jobs:
build:
name: build (Python ${{ matrix.python-version }}, Django ${{ matrix.django-version }})
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
@@ -37,6 +37,7 @@
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade tox tox-gh-actions
+ python -m pip install setuptools-scm==6.4.2
- name: Tox tests
run: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/.pre-commit-config.yaml new/django-push-notifications-3.0.2/.pre-commit-config.yaml
--- old/django-push-notifications-3.0.0/.pre-commit-config.yaml 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/.pre-commit-config.yaml 2023-10-29 17:59:32.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: v4.1.0
+ rev: v4.5.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: v2.31.0
+ rev: v3.15.0
hooks:
- id: pyupgrade
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/README.rst new/django-push-notifications-3.0.2/README.rst
--- old/django-push-notifications-3.0.0/README.rst 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/README.rst 2023-10-29 17:59:32.000000000 +0100
@@ -64,7 +64,7 @@
"WNS_PACKAGE_SECURITY_ID": "[your package security id, e.g: 'ms-app://e-3-4-6234...']",
"WNS_SECRET_KEY": "[your app secret key, e.g.: 'KDiejnLKDUWodsjmewuSZkk']",
"WP_PRIVATE_KEY": "/path/to/your/private.pem",
- "WP_CLAIMS": {'sub': "mailto: development(a)example.com"}
+ "WP_CLAIMS": {'sub': "mailto:development@example.com"}
}
.. note::
@@ -122,238 +122,11 @@
**WP settings**
-- Install:
-
-.. code-block:: python
-
- pip install pywebpush
- pip install py-vapid (Only for generating key)
-
-- Getting keys:
-
- - Create file (claim.json) like this:
-
-.. code-block:: bash
-
- {
- "sub": "mailto: development(a)example.com",
- "aud": "https://android.googleapis.com"
- }
-
- - Generate public and private keys:
-
-.. code-block:: bash
-
- vapid --sign claim.json
-
- No private_key.pem file found.
- Do you want me to create one for you? (Y/n)Y
- Do you want me to create one for you? (Y/n)Y
- Generating private_key.pem
- Generating public_key.pem
- Include the following headers in your request:
-
- Crypto-Key: p256ecdsa=BEFuGfKKEFp-kEBMxAIw7ng8HeH_QwnH5_h55ijKD4FRvgdJU1GVlDo8K5U5ak4cMZdQTUJlkA34llWF0xHya70
-
- Authorization: WebPush eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL2FuZHJvaWQuZ29vZ2xlYXBpcy5jb20iLCJleHAiOiIxNTA4NDkwODM2Iiwic3ViIjoibWFpbHRvOiBkZXZlbG9wbWVudEBleGFtcGxlLmNvbSJ9.r5CYMs86X3JZ4AEs76pXY5PxsnEhIFJ-0ckbibmFHZuyzfIpf1ZGIJbSI7knA4ufu7Hm8RFfEg5wWN1Yf-dR2A
-
- - Generate client public key (applicationServerKey)
-
-.. code-block:: bash
-
- vapid --applicationServerKey
-
- Application Server Key = BEFuGfKKEFp-kEBMxAIw7ng8HeH_QwnH5_h55ijKD4FRvgdJU1GVlDo8K5U5ak4cMZdQTUJlkA34llWF0xHya70
-
-
-- Configure settings:
-
- ``WP_PRIVATE_KEY``: Absolute path to your private certificate file: os.path.join(BASE_DIR, "private_key.pem")
-- ``WP_CLAIMS``: Dictionary with the same sub info like claims file: {'sub': "mailto: development(a)example.com"}
+- ``WP_CLAIMS``: Dictionary with default value for the sub, (subject), sent to the webpush service, This would be used by the service if they needed to reach out to you (the sender). Could be a url or mailto e.g. {'sub': "mailto:development@example.com"}.
- ``WP_ERROR_TIMEOUT``: The timeout on WebPush POSTs. (Optional)
-- ``WP_POST_URL``: A dictionary (key per browser supported) with the full url that webpush notifications will be POSTed to. (Optional)
-
-
-- Configure client (javascript):
-
-.. code-block:: javascript
-
- // Utils functions:
-
- function urlBase64ToUint8Array (base64String) {
- var padding = '='.repeat((4 - base64String.length % 4) % 4)
- var base64 = (base64String + padding)
- .replace(/\-/g, '+')
- .replace(/_/g, '/')
-
- var rawData = window.atob(base64)
- var outputArray = new Uint8Array(rawData.length)
-
- for (var i = 0; i < rawData.length; ++i) {
- outputArray[i] = rawData.charCodeAt(i)
- }
- return outputArray;
- }
-
- 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) || [];
- return {name: 'IE', version: (tem[1] || '')};
- }
- if (M[1] === 'Chrome') {
- tem = ua.match(/\bOPR\/(\d+)/);
- if (tem != null) {
- return {name: 'Opera', version: tem[1]};
- }
- }
- M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
- if ((tem = ua.match(/version\/(\d+)/i)) != null) {
- M.splice(1, 1, tem[1]);
- }
- return {
- name: M[0],
- version: M[1]
- };
- };
- var applicationServerKey = "BEFuGfKKEFp-kEBMxAIw7ng8HeH_QwnH5_h55ijKD4FRvgdJU1GVlDo8K5U5ak4cMZdQTUJlkA34llWF0xHya70";
- ....
-
- // In your ready listener
- if ('serviceWorker' in navigator) {
- // The service worker has to store in the root of the app
- // http://stackoverflow.com/questions/29874068/navigator-serviceworker-is-neve…
- var browser = loadVersionBrowser();
- navigator.serviceWorker.register('navigatorPush.service.js?version=1.0.0').then(function (reg) {
- reg.pushManager.subscribe({
- userVisibleOnly: true,
- applicationServerKey: urlBase64ToUint8Array(applicationServerKey)
- }).then(function (sub) {
- var endpointParts = sub.endpoint.split('/');
- var registration_id = endpointParts[endpointParts.length - 1];
- var data = {
- 'browser': browser.name.toUpperCase(),
- 'p256dh': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('p256dh')))),
- 'auth': btoa(String.fromCharCode.apply(null, new Uint8Array(sub.getKey('auth')))),
- 'name': 'XXXXX',
- 'registration_id': registration_id
- };
- requestPOSTToServer(data);
- })
- }).catch(function (err) {
- console.log(':^(', err);
- });
-
-
-
-
- // Example navigatorPush.service.js file
-
- var getTitle = function (title) {
- if (title === "") {
- title = "TITLE DEFAULT";
- }
- return title;
- };
- var getNotificationOptions = function (message, message_tag) {
- var options = {
- body: message,
- icon: '/img/icon_120.png',
- tag: message_tag,
- vibrate: [200, 100, 200, 100, 200, 100, 200]
- };
- return options;
- };
-
- self.addEventListener('install', function (event) {
- self.skipWaiting();
- });
-
- self.addEventListener('push', function(event) {
- try {
- // Push is a JSON
- var response_json = event.data.json();
- var title = response_json.title;
- var message = response_json.message;
- var message_tag = response_json.tag;
- } catch (err) {
- // Push is a simple text
- var title = "";
- var message = event.data.text();
- var message_tag = "";
- }
- self.registration.showNotification(getTitle(title), getNotificationOptions(message, message_tag));
- // Optional: Comunicating with our js application. Send a signal
- self.clients.matchAll({includeUncontrolled: true, type: 'window'}).then(function (clients) {
- clients.forEach(function (client) {
- client.postMessage({
- "data": message_tag,
- "data_title": title,
- "data_body": message});
- });
- });
- });
-
- // Optional: Added to that the browser opens when you click on the notification push web.
- self.addEventListener('notificationclick', function(event) {
- // Android doesn't close the notification when you click it
- // See http://crbug.com/463146
- event.notification.close();
- // Check if there's already a tab open with this URL.
- // If yes: focus on the tab.
- // If no: open a tab with the URL.
- event.waitUntil(clients.matchAll({type: 'window', includeUncontrolled: true}).then(function(windowClients) {
- for (var i = 0; i < windowClients.length; i++) {
- var client = windowClients[i];
- if ('focus' in client) {
- return client.focus();
- }
- }
- })
- );
- });
+For more information about how to configure WebPush, see `docs/WebPush <https://github.com/jazzband/django-push-notifications/blob/master/docs/WebP…>`_.
Sending messages
@@ -389,6 +162,37 @@
once constructed the payload exceeds the maximum size, an ``APNSDataOverflow`` exception will be raised before anything is sent.
Reference: `Apple Payload Documentation <https://developer.apple.com/library/content/documentation/NetworkingInterne…>`_
+Web Push accepts only one variable (``message``), which is passed directly to pywebpush. This message can be a simple string, which will be used as your notification's body, or it can be contain `any data supported by pywebpush<https://github.com/web-push-libs/pywebpush>`.
+
+Simple example:
+
+.. code-block:: python
+
+ from push_notifications.models import WebPushDevice
+
+ device = WebPushDevice.objects.get(registration_id=wp_reg_id)
+
+ device.send_message("You've got mail")
+
+.. note::
+ To customize the notification title using this method, edit the ``"TITLE DEFAULT"`` string in your ``navigatorPush.service.js`` file.
+
+JSON example:
+
+.. code-block:: python
+
+ import json
+ from push_notifications.models import WebPushDevice
+
+ device = WebPushDevice.objects.get(registration_id=wp_reg_id)
+
+ title = "Message Received"
+ message = "You've got mail"
+ data = json.dumps({"title": title, "message": message})
+
+ device.send_message(data)
+
+
Sending messages in bulk
------------------------
.. code-block:: python
@@ -463,7 +267,7 @@
from push_notifications.gcm import send_message
# First param is "None" because no Registration_id is needed, the message will be sent to all devices subscribed to the topic.
- send_message(None, {"body": "Hello members of my_topic!"}, to="/topics/my_topic")
+ send_message(None, {"body": "Hello members of my_topic!"}, cloud_type="FCM", to="/topics/my_topic")
Reference: `FCM Documentation <https://firebase.google.com/docs/cloud-messaging/android/topic-messaging>`_
@@ -495,6 +299,7 @@
Routes can be added one of two ways:
- Routers_ (include all views)
+
.. _Routers: http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers#using-…
::
@@ -513,6 +318,7 @@
)
- Using as_view_ (specify which views to include)
+
.. _as_view: http://www.django-rest-framework.org/tutorial/6-viewsets-and-routers#bindin…
::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/docs/WebPush.rst new/django-push-notifications-3.0.2/docs/WebPush.rst
--- old/django-push-notifications-3.0.0/docs/WebPush.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/django-push-notifications-3.0.2/docs/WebPush.rst 2023-10-29 17:59:32.000000000 +0100
@@ -0,0 +1,225 @@
+At a high-level, the key steps for implementing web push notifications after installing django-push-notifications[WP] are:
+ - Configure the VAPID keys, a private and public key for signing your push requests.
+ - Add client side logic to ask the user for permission to send push notifications and then sending returned client identifier information to a django view to create a WebPushDevice.
+ - Use a service worker to receive messages that have been pushed to the device and displaying them as notifications.
+
+These are in addition to the instalation steps for django-push-notifications[WP]
+
+Configure the VAPID keys
+------------------------------
+- Install:
+
+.. code-block:: python
+
+ pip install py-vapid (Only for generating key)
+
+- Generate public and private keys:
+
+.. code-block:: bash
+
+ vapid --gen
+
+ Generating private_key.pem
+ Generating public_key.pem
+
+
+The private key generated is the file to use with the setting ``WP_PRIVATE_KEY``
+The public key will be used in your client side javascript, but first it must be formated as an Application Server Key
+
+- Generate client public key (applicationServerKey)
+
+.. code-block:: bash
+
+ vapid --applicationServerKey
+
+ Application Server Key = <Your Public Key>
+
+
+
+Client Side logic to ask user for permission and subscribe to WebPush
+------------------------------
+The example subscribeUser function is best called in response to a user action, such as a button click. Some browsers will deny the request otherwise.
+
+.. code-block:: javascript
+
+ // Utils functions:
+
+ function urlBase64ToUint8Array (base64String) {
+ var padding = '='.repeat((4 - base64String.length % 4) % 4)
+ var base64 = (base64String + padding)
+ .replace(/\-/g, '+')
+ .replace(/_/g, '/')
+
+ var rawData = window.atob(base64)
+ var outputArray = new Uint8Array(rawData.length)
+
+ for (var i = 0; i < rawData.length; ++i) {
+ outputArray[i] = rawData.charCodeAt(i)
+ }
+ return outputArray;
+ }
+
+ var applicationServerKey = '<Your Public Key>';
+
+ function subscribeUser() {
+ if ('Notification' in window && 'serviceWorker' in navigator) {
+ navigator.serviceWorker.ready.then(function (reg) {
+ reg.pushManager
+ .subscribe({
+ userVisibleOnly: true,
+ applicationServerKey: urlBase64ToUint8Array(
+ applicationServerKey
+ ),
+ })
+ .then(function (sub) {
+ var registration_id = sub.endpoint;
+ var data = {
+ p256dh: btoa(
+ String.fromCharCode.apply(
+ null,
+ new Uint8Array(sub.getKey('p256dh'))
+ )
+ ),
+ auth: btoa(
+ String.fromCharCode.apply(
+ null,
+ new Uint8Array(sub.getKey('auth'))
+ )
+ ),
+ registration_id: registration_id,
+ }
+ requestPOSTToServer(data)
+ })
+ .catch(function (e) {
+ if (Notification.permission === 'denied') {
+ console.warn('Permission for notifications was denied')
+ } else {
+ console.error('Unable to subscribe to push', e)
+ }
+ })
+ })
+ }
+ }
+
+ // Send the subscription data to your server
+ function requestPOSTToServer (data) {
+ const headers = new Headers();
+ headers.set('Content-Type', 'application/json');
+ const requestOptions = {
+ method: 'POST',
+ headers,
+ body: JSON.stringify(data),
+ };
+
+ return (
+ fetch(
+ '<your endpoint url>',
+ requestOptions
+ )
+ ).then((response) => response.json())
+ }
+
+Server Side logic to create webpush
+------------------------------
+Is is up to you how to add a view in your django application that can handle a POST of p256dh, auth, registration_id and create a WebPushDevice with those values assoicated with the appropriate user.
+For example you could use rest_framework
+
+.. code-block:: python
+
+ from rest_framework.routers import SimpleRouter
+ from push_notifications.api.rest_framework import WebPushDeviceViewSet
+ ....
+ api_router = SimpleRouter()
+ api_router.register(r'push/web', WebPushDeviceViewSet, basename='web_push')
+ ...
+ urlpatterns += [
+ # Api
+ re_path('api/v1/', include(api_router.urls)),
+ ...
+ ]
+
+Or a generic function view (add your own boilerplate for errors and protections)
+
+.. code-block:: python
+
+ import json
+ from push_notifications.models import WebPushDevice
+ def register_webpush(request):
+ data = json.loads(request.body)
+ WebPushDevice.objects.create(
+ user=request.user,
+ **data
+ )
+
+
+Service Worker to show messages
+------------------------------
+You will need a service worker registered with your web app that can handle the notfications, for example
+
+.. code-block:: javascript
+
+ // Example navigatorPush.service.js file
+
+ var getTitle = function (title) {
+ if (title === "") {
+ title = "TITLE DEFAULT";
+ }
+ return title;
+ };
+ var getNotificationOptions = function (message, message_tag) {
+ var options = {
+ body: message,
+ icon: '/img/icon_120.png',
+ tag: message_tag,
+ vibrate: [200, 100, 200, 100, 200, 100, 200]
+ };
+ return options;
+ };
+
+ self.addEventListener('install', function (event) {
+ self.skipWaiting();
+ });
+
+ self.addEventListener('push', function(event) {
+ try {
+ // Push is a JSON
+ var response_json = event.data.json();
+ var title = response_json.title;
+ var message = response_json.message;
+ var message_tag = response_json.tag;
+ } catch (err) {
+ // Push is a simple text
+ var title = "";
+ var message = event.data.text();
+ var message_tag = "";
+ }
+ self.registration.showNotification(getTitle(title), getNotificationOptions(message, message_tag));
+ // Optional: Comunicating with our js application. Send a signal
+ self.clients.matchAll({includeUncontrolled: true, type: 'window'}).then(function (clients) {
+ clients.forEach(function (client) {
+ client.postMessage({
+ "data": message_tag,
+ "data_title": title,
+ "data_body": message});
+ });
+ });
+ });
+
+ // Optional: Added to that the browser opens when you click on the notification push web.
+ self.addEventListener('notificationclick', function(event) {
+ // Android doesn't close the notification when you click it
+ // See http://crbug.com/463146
+ event.notification.close();
+ // Check if there's already a tab open with this URL.
+ // If yes: focus on the tab.
+ // If no: open a tab with the URL.
+ event.waitUntil(clients.matchAll({type: 'window', includeUncontrolled: true}).then(function(windowClients) {
+ for (var i = 0; i < windowClients.length; i++) {
+ var client = windowClients[i];
+ if ('focus' in client) {
+ return client.focus();
+ }
+ }
+ })
+ );
+ });
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/api/rest_framework.py new/django-push-notifications-3.0.2/push_notifications/api/rest_framework.py
--- old/django-push-notifications-3.0.0/push_notifications/api/rest_framework.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/api/rest_framework.py 2023-10-29 17:59:32.000000000 +0100
@@ -22,7 +22,7 @@
data = int(data, 16) if type(data) != int else data
except ValueError:
raise ValidationError("Device ID is not a valid hex number")
- return super(HexIntegerField, self).to_internal_value(data)
+ return super().to_internal_value(data)
def to_representation(self, value):
return value
@@ -46,10 +46,10 @@
model = APNSDevice
def validate_registration_id(self, value):
- # iOS device tokens are 256-bit hexadecimal (64 characters). In 2016 Apple is increasing
- # iOS device tokens to 100 bytes hexadecimal (200 characters).
- if hex_re.match(value) is None or len(value) not in (64, 200):
+ # https://developer.apple.com/documentation/uikit/uiapplicationdelegate/16229…
+ # As of 02/2023 APNS tokens (registration_id) "are of variable length. Do not hard-code their size."
+ if hex_re.match(value) is None:
raise ValidationError("Registration ID (device token) is invalid")
return value
@@ -160,12 +160,12 @@
def perform_create(self, serializer):
if self.request.user.is_authenticated:
serializer.save(user=self.request.user)
- return super(DeviceViewSetMixin, self).perform_create(serializer)
+ return super().perform_create(serializer)
def perform_update(self, serializer):
if self.request.user.is_authenticated:
serializer.save(user=self.request.user)
- return super(DeviceViewSetMixin, self).perform_update(serializer)
+ return super().perform_update(serializer)
class AuthorizedMixin:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/conf/app.py new/django-push-notifications-3.0.2/push_notifications/conf/app.py
--- old/django-push-notifications-3.0.0/push_notifications/conf/app.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/conf/app.py 2023-10-29 17:59:32.000000000 +0100
@@ -171,7 +171,7 @@
"""Validate the APNS certificate at startup."""
try:
- with open(certfile, "r") as f:
+ with open(certfile) as f:
content = f.read()
check_apns_certificate(content)
except Exception as e:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/conf/legacy.py new/django-push-notifications-3.0.2/push_notifications/conf/legacy.py
--- old/django-push-notifications-3.0.0/push_notifications/conf/legacy.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/conf/legacy.py 2023-10-29 17:59:32.000000000 +0100
@@ -119,8 +119,7 @@
return self._get_application_settings(application_id, "APNS_USE_SANDBOX", self.msg)
def get_apns_use_alternative_port(self, application_id=None):
- return
- self._get_application_settings(application_id, "APNS_USE_ALTERNATIVE_PORT", self.msg)
+ return self._get_application_settings(application_id, "APNS_USE_ALTERNATIVE_PORT", self.msg)
def get_apns_topic(self, application_id=None):
return self._get_application_settings(application_id, "APNS_TOPIC", self.msg)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/fields.py new/django-push-notifications-3.0.2/push_notifications/fields.py
--- old/django-push-notifications-3.0.0/push_notifications/fields.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/fields.py 2023-10-29 17:59:32.000000000 +0100
@@ -13,7 +13,7 @@
UNSIGNED_64BIT_INT_MAX_VALUE = 2 ** 64 - 1
-hex_re = re.compile(r"^(([0-9A-f])|(0x[0-9A-f]))+$")
+hex_re = re.compile(r"^(0x)?([0-9a-f])+$", re.I)
signed_integer_vendors = [
"postgresql",
"sqlite",
@@ -48,7 +48,7 @@
self.default_validators = [
RegexValidator(hex_re, _("Enter a valid hexadecimal number"), "invalid")
]
- super(HexadecimalField, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def prepare_value(self, value):
# converts bigint from db to hex before it is displayed in admin
@@ -82,7 +82,7 @@
elif "sqlite" == connection.vendor:
return "UNSIGNED BIG INT"
else:
- return super(HexIntegerField, self).db_type(connection=connection)
+ return super().db_type(connection=connection)
def get_prep_value(self, value):
""" Return the integer value to be stored from the hex string """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/migrations/0001_initial.py new/django-push-notifications-3.0.2/push_notifications/migrations/0001_initial.py
--- old/django-push-notifications-3.0.0/push_notifications/migrations/0001_initial.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/migrations/0001_initial.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
from django.conf import settings
from django.db import migrations, models
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/migrations/0002_auto_20160106_0850.py new/django-push-notifications-3.0.2/push_notifications/migrations/0002_auto_20160106_0850.py
--- old/django-push-notifications-3.0.0/push_notifications/migrations/0002_auto_20160106_0850.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/migrations/0002_auto_20160106_0850.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.9.1 on 2016-01-06 08:50
from django.db import migrations, models
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/migrations/0003_wnsdevice.py new/django-push-notifications-3.0.2/push_notifications/migrations/0003_wnsdevice.py
--- old/django-push-notifications-3.0.0/push_notifications/migrations/0003_wnsdevice.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/migrations/0003_wnsdevice.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-13 20:46
import django.db.models.deletion
from django.conf import settings
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/migrations/0004_fcm.py new/django-push-notifications-3.0.2/push_notifications/migrations/0004_fcm.py
--- old/django-push-notifications-3.0.0/push_notifications/migrations/0004_fcm.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/migrations/0004_fcm.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-13 20:46
from django.conf import settings
from django.db import migrations, models
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/migrations/0005_applicationid.py new/django-push-notifications-3.0.2/push_notifications/migrations/0005_applicationid.py
--- old/django-push-notifications-3.0.0/push_notifications/migrations/0005_applicationid.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/migrations/0005_applicationid.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
from django.conf import settings
from django.db import migrations, models
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/migrations/0006_webpushdevice.py new/django-push-notifications-3.0.2/push_notifications/migrations/0006_webpushdevice.py
--- old/django-push-notifications-3.0.0/push_notifications/migrations/0006_webpushdevice.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/migrations/0006_webpushdevice.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
from django.conf import settings
from django.db import migrations, models
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/models.py new/django-push-notifications-3.0.2/push_notifications/models.py
--- old/django-push-notifications-3.0.0/push_notifications/models.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/models.py 2023-10-29 17:59:32.000000000 +0100
@@ -255,6 +255,4 @@
def send_message(self, message, **kwargs):
from .webpush import webpush_send_message
- return webpush_send_message(
- uri=self.registration_id, message=message, browser=self.browser,
- auth=self.auth, p256dh=self.p256dh, application_id=self.application_id, **kwargs)
+ return webpush_send_message(self, message, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/push_notifications/webpush.py new/django-push-notifications-3.0.2/push_notifications/webpush.py
--- old/django-push-notifications-3.0.0/push_notifications/webpush.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/push_notifications/webpush.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,3 +1,5 @@
+import warnings
+
from pywebpush import WebPushException, webpush
from .conf import get_manager
@@ -5,9 +7,18 @@
def get_subscription_info(application_id, uri, browser, auth, p256dh):
- url = get_manager().get_wp_post_url(application_id, browser)
+ if uri.startswith("https://"):
+ endpoint = uri
+ else:
+ url = get_manager().get_wp_post_url(application_id, browser)
+ endpoint = "{}/{}".format(url, uri)
+ warnings.warn(
+ "registration_id should be the full endpoint returned from pushManager.subscribe",
+ DeprecationWarning,
+ stacklevel=2,
+ )
return {
- "endpoint": "{}/{}".format(url, uri),
+ "endpoint": endpoint,
"keys": {
"auth": auth,
"p256dh": p256dh,
@@ -15,25 +26,30 @@
}
-def webpush_send_message(
- uri, message, browser, auth, p256dh, application_id=None, **kwargs
-):
- subscription_info = get_subscription_info(application_id, uri, browser, auth, p256dh)
-
+def webpush_send_message(device, message, **kwargs):
+ subscription_info = get_subscription_info(
+ device.application_id, device.registration_id,
+ device.browser, device.auth, device.p256dh)
try:
+ results = {"results": [{"original_registration_id": device.registration_id}]}
response = webpush(
subscription_info=subscription_info,
data=message,
- vapid_private_key=get_manager().get_wp_private_key(application_id),
- vapid_claims=get_manager().get_wp_claims(application_id).copy(),
+ vapid_private_key=get_manager().get_wp_private_key(device.application_id),
+ vapid_claims=get_manager().get_wp_claims(device.application_id).copy(),
**kwargs
)
- results = {"results": [{}]}
- if not response.ok:
- results["results"][0]["error"] = response.content
- results["results"][0]["original_registration_id"] = response.content
- else:
+ if response.ok:
results["success"] = 1
+ else:
+ results["failure"] = 1
+ results["results"][0]["error"] = response.content
return results
except WebPushException as e:
+ if e.response is not None and e.response.status_code in [404, 410]:
+ results["failure"] = 1
+ results["results"][0]["error"] = e.message
+ device.active = False
+ device.save()
+ return results
raise WebPushError(e.message)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/setup.cfg new/django-push-notifications-3.0.2/setup.cfg
--- old/django-push-notifications-3.0.0/setup.cfg 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/setup.cfg 2023-10-29 17:59:32.000000000 +0100
@@ -38,7 +38,6 @@
APNS =
apns2>=0.3.0
importlib-metadata;python_version < "3.8"
- pywebpush>=1.3.0
Django>=2.2
WP = pywebpush>=1.3.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/setup.py new/django-push-notifications-3.0.2/setup.py
--- old/django-push-notifications-3.0.0/setup.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/setup.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,4 +1,11 @@
#!/usr/bin/env python
from setuptools import setup
+from pathlib import Path
-setup(use_scm_version={"version_scheme": "post-release"})
+this_directory = Path(__file__).parent
+long_description = (this_directory / "README.rst").read_text()
+setup(
+ long_description=long_description,
+ long_description_content_type='text/x-rst',
+ use_scm_version={"version_scheme": "post-release"}
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tests/settings.py new/django-push-notifications-3.0.2/tests/settings.py
--- old/django-push-notifications-3.0.0/tests/settings.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/tests/settings.py 2023-10-29 17:59:32.000000000 +0100
@@ -26,5 +26,5 @@
SECRET_KEY = "foobar"
PUSH_NOTIFICATIONS_SETTINGS = {
- "WP_CLAIMS": {"sub": "mailto: jazzband(a)example.com"}
+ "WP_CLAIMS": {"sub": "mailto:jazzband@example.com"}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tests/settings_unique.py new/django-push-notifications-3.0.2/tests/settings_unique.py
--- old/django-push-notifications-3.0.0/tests/settings_unique.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/tests/settings_unique.py 2023-10-29 17:59:32.000000000 +0100
@@ -26,6 +26,6 @@
SECRET_KEY = "foobar"
PUSH_NOTIFICATIONS_SETTINGS = {
- "WP_CLAIMS": {"sub": "mailto: jazzband(a)example.com"},
+ "WP_CLAIMS": {"sub": "mailto:jazzband@example.com"},
"UNIQUE_REG_ID": True
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tests/test_fields.py new/django-push-notifications-3.0.2/tests/test_fields.py
--- old/django-push-notifications-3.0.0/tests/test_fields.py 1970-01-01 01:00:00.000000000 +0100
+++ new/django-push-notifications-3.0.2/tests/test_fields.py 2023-10-29 17:59:32.000000000 +0100
@@ -0,0 +1,40 @@
+from django.core.exceptions import ValidationError
+from django.test import SimpleTestCase
+
+from push_notifications.fields import HexadecimalField
+
+
+class HexadecimalFieldTestCase(SimpleTestCase):
+ _INVALID_HEX_VALUES = [
+ "foobar",
+ "GLUTEN",
+ "HeLLo WoRLd",
+ "international",
+ "°!#€%&/()[]{}=?",
+ "0x",
+ ]
+
+ _VALID_HEX_VALUES = {
+ "babe": "babe",
+ "BEEF": "BEEF",
+ " \nfeed \t": "feed",
+ "0x012345789abcdef": "0x012345789abcdef",
+ "012345789aBcDeF": "012345789aBcDeF",
+ }
+
+ def test_clean_invalid_values(self):
+ """Passing invalid values raises ValidationError."""
+ f = HexadecimalField()
+ for invalid in self._INVALID_HEX_VALUES:
+ self.assertRaisesMessage(
+ ValidationError,
+ "'Enter a valid hexadecimal number'",
+ f.clean,
+ invalid,
+ )
+
+ def test_clean_valid_values(self):
+ """Passing valid values returns the expected output."""
+ f = HexadecimalField()
+ for valid, expected in self._VALID_HEX_VALUES.items():
+ self.assertEqual(expected, f.clean(valid))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tests/test_legacy_config.py new/django-push-notifications-3.0.2/tests/test_legacy_config.py
--- old/django-push-notifications-3.0.0/tests/test_legacy_config.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/tests/test_legacy_config.py 2023-10-29 17:59:32.000000000 +0100
@@ -1,3 +1,5 @@
+from unittest import mock
+
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase
@@ -38,9 +40,17 @@
)
def test_immutable_wp_claims(self):
+ self.endpoint = "https://updates.push.services.mozilla.com/wpush/v2/token"
+ self.mock_device = mock.Mock()
+ self.mock_device.application_id = None
+ self.mock_device.registration_id = self.endpoint
+ self.mock_device.auth = "authtest"
+ self.mock_device.p256dh = "p256dhtest"
+ self.mock_device.active = True
+ self.mock_device.save.return_value = True
vapid_claims_pre = get_manager().get_wp_claims(None).copy()
try:
- webpush_send_message("", {}, "CHROME", "", "")
+ webpush_send_message(self.mock_device, "message")
except WebPushError:
pass
vapid_claims_after = get_manager().get_wp_claims(None)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tests/test_models.py new/django-push-notifications-3.0.2/tests/test_models.py
--- old/django-push-notifications-3.0.0/tests/test_models.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/tests/test_models.py 2023-10-29 17:59:32.000000000 +0100
@@ -276,7 +276,7 @@
reg_ids = [obj.registration_id for obj in GCMDevice.objects.all()]
send_bulk_message(reg_ids, {"message": "Hello World"}, "GCM")
p.assert_called_once_with(
- [u"abc", u"abc1"], {"message": "Hello World"}, cloud_type="GCM", application_id=None
+ ["abc", "abc1"], {"message": "Hello World"}, cloud_type="GCM", application_id=None
)
def test_fcm_send_message(self):
@@ -506,7 +506,7 @@
reg_ids = [obj.registration_id for obj in GCMDevice.objects.all()]
send_bulk_message(reg_ids, {"message": "Hello World"}, "FCM")
p.assert_called_once_with(
- [u"abc", u"abc1"], {"message": "Hello World"}, cloud_type="FCM",
+ ["abc", "abc1"], {"message": "Hello World"}, cloud_type="FCM",
application_id=None
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tests/test_rest_framework.py new/django-push-notifications-3.0.2/tests/test_rest_framework.py
--- old/django-push-notifications-3.0.0/tests/test_rest_framework.py 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/tests/test_rest_framework.py 2023-10-29 17:59:32.000000000 +0100
@@ -5,13 +5,13 @@
)
-GCM_DRF_INVALID_HEX_ERROR = {"device_id": [u"Device ID is not a valid hex number"]}
-GCM_DRF_OUT_OF_RANGE_ERROR = {"device_id": [u"Device ID is out of range"]}
+GCM_DRF_INVALID_HEX_ERROR = {"device_id": ["Device ID is not a valid hex number"]}
+GCM_DRF_OUT_OF_RANGE_ERROR = {"device_id": ["Device ID is out of range"]}
class APNSDeviceSerializerTestCase(TestCase):
def test_validation(self):
- # valid data - 32 bytes upper case
+ # valid data - 64 bytes upper case
serializer = APNSDeviceSerializer(data={
"registration_id": "AEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE",
"name": "Apple iPhone 6+",
@@ -20,7 +20,7 @@
})
self.assertTrue(serializer.is_valid())
- # valid data - 32 bytes lower case
+ # valid data - 64 bytes lower case
serializer = APNSDeviceSerializer(data={
"registration_id": "aeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeaeae",
"name": "Apple iPhone 6+",
@@ -31,7 +31,7 @@
# valid data - 100 bytes upper case
serializer = APNSDeviceSerializer(data={
- "registration_id": "AE" * 100,
+ "registration_id": "AE" * 50,
"name": "Apple iPhone 6+",
"device_id": "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
})
@@ -39,7 +39,15 @@
# valid data - 100 bytes lower case
serializer = APNSDeviceSerializer(data={
- "registration_id": "ae" * 100,
+ "registration_id": "ae" * 50,
+ "name": "Apple iPhone 6+",
+ "device_id": "ffffffffffffffffffffffffffffffff",
+ })
+ self.assertTrue(serializer.is_valid())
+
+ # valid data - 200 bytes mixed case
+ serializer = APNSDeviceSerializer(data={
+ "registration_id": "aE" * 100,
"name": "Apple iPhone 6+",
"device_id": "ffffffffffffffffffffffffffffffff",
})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tests/test_webpush.py new/django-push-notifications-3.0.2/tests/test_webpush.py
--- old/django-push-notifications-3.0.0/tests/test_webpush.py 1970-01-01 01:00:00.000000000 +0100
+++ new/django-push-notifications-3.0.2/tests/test_webpush.py 2023-10-29 17:59:32.000000000 +0100
@@ -0,0 +1,93 @@
+from unittest import mock
+
+from django.test import TestCase
+from pywebpush import WebPushException
+
+from push_notifications.exceptions import WebPushError
+from push_notifications.webpush import (
+ get_subscription_info, webpush_send_message
+)
+
+# Mock Responses
+mock_success_response = mock.MagicMock(status_code=200, ok=True)
+mock_fail_resposne = mock.MagicMock(status_code=400, ok=False, content="Test Error")
+mock_unsubscribe_response = mock.MagicMock(
+ status_code=410, ok=False, content="Unsubscribe")
+mock_unsubscribe_response_404 = mock.MagicMock(
+ status_code=404, ok=False, content="Unsubscribe")
+
+
+class WebPushSendMessageTestCase(TestCase):
+ def setUp(self):
+ self.endpoint = "https://updates.push.services.mozilla.com/wpush/v2/token"
+ self.mock_device = mock.Mock()
+ self.mock_device.application_id = None
+ self.mock_device.registration_id = self.endpoint
+ self.mock_device.auth = "authtest"
+ self.mock_device.p256dh = "p256dhtest"
+ self.mock_device.active = True
+ self.mock_device.save.return_value = True
+
+ def test_get_subscription_info(self):
+ keys = {"auth": "authtest", "p256dh": "p256dhtest"}
+ endpoint = self.endpoint
+ original = get_subscription_info(
+ None, "token", "FIREFOX", keys["auth"], keys["p256dh"]
+ )
+
+ self.assertEqual(
+ original,
+ {
+ "endpoint": endpoint,
+ "keys": keys,
+ },
+ )
+
+ patched = get_subscription_info(
+ None,
+ endpoint,
+ "",
+ keys["auth"],
+ keys["p256dh"],
+ )
+
+ self.assertEqual(
+ patched,
+ {
+ "endpoint": endpoint,
+ "keys": keys,
+ },
+ )
+
+ @mock.patch("push_notifications.webpush.webpush", return_value=mock_success_response)
+ def test_webpush_send_message(self, webpush_mock):
+ results = webpush_send_message(self.mock_device, "message")
+ self.assertEqual(results["success"], 1)
+
+ @mock.patch("push_notifications.webpush.webpush", return_value=mock_fail_resposne)
+ def test_webpush_send_message_failure(self, webpush_mock):
+ results = webpush_send_message(self.mock_device, "message")
+ self.assertEqual(results["failure"], 1)
+
+ @mock.patch(
+ "push_notifications.webpush.webpush",
+ side_effect=WebPushException("Unsubscribe",
+ response=mock_unsubscribe_response))
+ def test_webpush_send_message_unsubscribe(self, webpush_mock):
+ results = webpush_send_message(self.mock_device, "message")
+ self.assertEqual(results["failure"], 1)
+
+ @mock.patch(
+ "push_notifications.webpush.webpush",
+ side_effect=WebPushException("Unsubscribe",
+ response=mock_unsubscribe_response_404))
+ def test_webpush_send_message_404(self, webpush_mock):
+ results = webpush_send_message(self.mock_device, "message")
+ self.assertEqual(results["failure"], 1)
+
+ @mock.patch(
+ "push_notifications.webpush.webpush",
+ side_effect=WebPushException("Error"))
+ def test_webpush_send_message_exception(self, webpush_mock):
+ with self.assertRaises(WebPushError):
+ webpush_send_message(self.mock_device, "message")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-push-notifications-3.0.0/tox.ini new/django-push-notifications-3.0.2/tox.ini
--- old/django-push-notifications-3.0.0/tox.ini 2022-02-14 03:43:49.000000000 +0100
+++ new/django-push-notifications-3.0.2/tox.ini 2023-10-29 17:59:32.000000000 +0100
@@ -1,9 +1,9 @@
[tox]
-skipsdist = True
+skipsdist = False
usedevelop = true
envlist =
py{36,37,38,39}-dj{22,32}
- py{38,39}-dj{40,main}
+ py{38,39}-dj{40,405}
flake8
[gh-actions]
@@ -18,7 +18,7 @@
2.2: dj22
3.2: dj32
4.0: dj40
- main: djmain
+ 4.0.5: dj405
[testenv]
usedevelop = true
@@ -38,8 +38,8 @@
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
+ dj40: Django>=4.0,<4.0.5
+ dj405: Django>=4.0.5,<4.1
[testenv:flake8]
commands = flake8 --exit-zero
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-django-countries for openSUSE:Factory checked in at 2023-11-30 22:00:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-countries (Old)
and /work/SRC/openSUSE:Factory/.python-django-countries.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-countries"
Thu Nov 30 22:00:40 2023 rev:3 rq:1129786 version:7.5.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-django-countries/python-django-countries.changes 2021-05-12 19:32:20.727010461 +0200
+++ /work/SRC/openSUSE:Factory/.python-django-countries.new.25432/python-django-countries.changes 2023-11-30 22:01:29.837448886 +0100
@@ -1,0 +2,35 @@
+Wed Nov 29 12:05:05 UTC 2023 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 7.5.1:
+ * Make ``CountryField`` queryset filters also work with country
+ codes in addition to names.
+ * Switch to ``pyproject.toml`` rather than ``setup.py`` to fix
+ installation issues with pip 23.0+.
+ * Rename Turkey to Türkiye.
+ * Improve translation fallback handling, fixing a threading
+ race condition that could cause odd translation issues.
+ * This also fixes translation issues with older Python 3.6/3.7
+ versions.
+ * Add Python 3.11, drop Python 3.6 and Django 2.2 support.
+ * Fix error when using ``USE_I18N = False``.
+ * Fix broken translations due to last common country names fix.
+ * Fixed Traditional Chinese translation (needed to be
+ ``locale/zh_Hant``).
+ * Update flag of Honduras.
+ * Add Django 4.0 and 4.1 to the test matrix, dropping 3.0 and
+ 3.1
+ * Add Django Rest Framework 3.13 and 3.14, dropping 3.11.
+ * Multi-choice countries are now stored sorted and with
+ duplicates stripped.
+ * Fix common country names not being honoured in non-English
+ translations (only fixed for Python 3.8+).
+ * Fix slowdown introduced in v7.3 caused by always using
+ country name lookups for field comparisons.
+ ``filter(country="New Zealand")`` will no longer match now,
+ but instead new ``__name`` and ``__iname`` filters have
+ been added to achieve this.
+ * Typing compatibility fixes for Python <3.9.
+ * Make full English country names work in database lookups, for
+ example, ``Person.objects.filter(country__icontains="zealand")``.
+
+-------------------------------------------------------------------
Old:
----
django-countries-7.2.1.tar.gz
New:
----
django-countries-7.5.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-django-countries.spec ++++++
--- /var/tmp/diff_new_pack.9vLLRk/_old 2023-11-30 22:01:30.361468190 +0100
+++ /var/tmp/diff_new_pack.9vLLRk/_new 2023-11-30 22:01:30.361468190 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-django-countries
#
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,20 +16,21 @@
#
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%define skip_python2 1
+%{?sle15_python_module_pythons}
Name: python-django-countries
-Version: 7.2.1
+Version: 7.5.1
Release: 0
Summary: Provides a country field for Django models
License: MIT
Group: Development/Languages/Python
URL: https://github.com/SmileyChris/django-countries/
Source: https://files.pythonhosted.org/packages/source/d/django-countries/django-co…
-BuildRequires: %{python_module setuptools}
+BuildRequires: %{python_module pip}
+BuildRequires: %{python_module wheel}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-Django
+Requires: python-typing-extensions
Recommends: python-djangorestframework
Recommends: python-graphene-django
Recommends: python-pyuca
@@ -41,6 +42,7 @@
BuildRequires: %{python_module pytest-django}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module pyuca}
+BuildRequires: %{python_module typing-extensions}
# /SECTION
%python_subpackages
@@ -53,10 +55,10 @@
sed -i '1{/^#!/d}' django_countries/*.py
%build
-%python_build
+%pyproject_wheel
%install
-%python_install
+%pyproject_install
%{python_expand rm -r %{buildroot}%{$python_sitelib}/django_countries/tests/
%fdupes %{buildroot}%{$python_sitelib}
}
@@ -69,5 +71,6 @@
%files %{python_files}
%doc CHANGES.rst README.rst
%license LICENSE
-%{python_sitelib}/*
+%{python_sitelib}/django_countries
+%{python_sitelib}/django_countries-%{version}.dist-info
++++++ django-countries-7.2.1.tar.gz -> django-countries-7.5.1.tar.gz ++++++
++++ 7740 lines of diff (skipped)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-django-classy-tags for openSUSE:Factory checked in at 2023-11-30 22:00:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-classy-tags (Old)
and /work/SRC/openSUSE:Factory/.python-django-classy-tags.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-django-classy-tags"
Thu Nov 30 22:00:39 2023 rev:8 rq:1129784 version:4.1.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-django-classy-tags/python-django-classy-tags.changes 2023-06-22 23:26:28.369967571 +0200
+++ /work/SRC/openSUSE:Factory/.python-django-classy-tags.new.25432/python-django-classy-tags.changes 2023-11-30 22:01:28.997417941 +0100
@@ -1,0 +2,12 @@
+Wed Nov 29 11:59:04 UTC 2023 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 4.1.0:
+ * Django 4.2 support
+ * Dropped support for Python 3.7
+ * Added support for Python 3.11
+ * Dropped support for Django < 3.2
+ * Added support for Django 4.1
+ * Start testing against Django's `main` branch
+- drop django-4-1-support.patch (upstream)
+
+-------------------------------------------------------------------
Old:
----
3.0.1.tar.gz
django-4-1-support.patch
New:
----
4.1.0.tar.gz
BETA DEBUG BEGIN:
Old: * Start testing against Django's `main` branch
- drop django-4-1-support.patch (upstream)
BETA DEBUG END:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-django-classy-tags.spec ++++++
--- /var/tmp/diff_new_pack.lzoyVK/_old 2023-11-30 22:01:29.637441518 +0100
+++ /var/tmp/diff_new_pack.lzoyVK/_new 2023-11-30 22:01:29.637441518 +0100
@@ -18,14 +18,12 @@
%{?sle15_python_module_pythons}
Name: python-django-classy-tags
-Version: 3.0.1
+Version: 4.1.0
Release: 0
Summary: Class based template tags for Django
License: MIT
URL: https://github.com/ojii/django-classy-tags
Source: https://github.com/divio/django-classy-tags/archive/%{version}.tar.gz
-# PATCH-FIX-UPSTREAM Support django >= 4.1 gh#django-cms/django-classy-tags#86
-Patch0: django-4-1-support.patch
BuildRequires: %{python_module Django >= 3.2}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
++++++ 3.0.1.tar.gz -> 4.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.github/PULL_REQUEST_TEMPLATE.md new/django-classy-tags-4.1.0/.github/PULL_REQUEST_TEMPLATE.md
--- old/django-classy-tags-3.0.1/.github/PULL_REQUEST_TEMPLATE.md 1970-01-01 01:00:00.000000000 +0100
+++ new/django-classy-tags-4.1.0/.github/PULL_REQUEST_TEMPLATE.md 2023-07-29 04:21:05.000000000 +0200
@@ -0,0 +1,30 @@
+## Description
+
+<!--
+If this is a security issue stop right here and follow our documentation:
+http://docs.django-cms.org/en/latest/contributing/development-policies.html#reporting-security-issues
+-->
+
+## Related resources
+
+<!--
+Add here links to existing issues or conversation from GitHub
+or any other resource.
+-->
+
+* #...
+* #...
+
+## Checklist
+
+<!--
+Please check the following items before submitting, otherwise,
+your pull request will be closed.
+Use 'x' to check each item: [x] I have ...
+-->
+
+* [ ] I have opened this pull request against ``master``
+* [ ] I have added or modified the tests when changing logic
+* [ ] I have followed [the conventional commits guidelines](https://www.conventionalcommits.org/) to add meaningful information into the changelog
+* [ ] I have read the [contribution guidelines ](https://github.com/django-cms/django-cms/blob/develop/CONTRIBUTING.rst) and I have joined #workgroup-pr-review on
+[Slack](https://www.django-cms.org/slack) to find a “pr review buddy” who is going to review my pull request.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.github/dependabot.yml new/django-classy-tags-4.1.0/.github/dependabot.yml
--- old/django-classy-tags-3.0.1/.github/dependabot.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/django-classy-tags-4.1.0/.github/dependabot.yml 2023-07-29 04:21:05.000000000 +0200
@@ -0,0 +1,11 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://docs.github.com/github/administering-a-repository/configuration-opt…
+
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "weekly"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.github/workflows/codeql-analysis.yml new/django-classy-tags-4.1.0/.github/workflows/codeql-analysis.yml
--- old/django-classy-tags-3.0.1/.github/workflows/codeql-analysis.yml 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/.github/workflows/codeql-analysis.yml 2023-07-29 04:21:05.000000000 +0200
@@ -36,11 +36,11 @@
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v1
+ uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -51,7 +51,7 @@
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
- uses: github/codeql-action/autobuild@v1
+ uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -65,4 +65,4 @@
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
+ uses: github/codeql-action/analyze@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.github/workflows/lint.yml new/django-classy-tags-4.1.0/.github/workflows/lint.yml
--- old/django-classy-tags-3.0.1/.github/workflows/lint.yml 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/.github/workflows/lint.yml 2023-07-29 04:21:05.000000000 +0200
@@ -8,15 +8,15 @@
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install flake8
run: pip install --upgrade flake8
- name: Run flake8
- uses: liskin/gh-problem-matcher-wrap@v1
+ uses: liskin/gh-problem-matcher-wrap@v2
with:
linters: flake8
run: flake8
@@ -25,14 +25,14 @@
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: 3.9
- run: python -m pip install isort
- name: isort
- uses: liskin/gh-problem-matcher-wrap@v1
+ uses: liskin/gh-problem-matcher-wrap@v2
with:
linters: isort
run: isort -c -rc -df classytags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.github/workflows/publish-to-live-pypi.yml new/django-classy-tags-4.1.0/.github/workflows/publish-to-live-pypi.yml
--- old/django-classy-tags-3.0.1/.github/workflows/publish-to-live-pypi.yml 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/.github/workflows/publish-to-live-pypi.yml 2023-07-29 04:21:05.000000000 +0200
@@ -9,12 +9,17 @@
build-n-publish:
name: Build and publish Python 🐍 distributions 📦 to pypi
runs-on: ubuntu-latest
+ environment:
+ name: pypi
+ url: https://pypi.org/p/django-classy-tags
+ permissions:
+ id-token: write
steps:
- - uses: actions/checkout@master
- - name: Set up Python 3.9
- uses: actions/setup-python@v1
+ - uses: actions/checkout@v3
+ - name: Set up Python 3.10
+ uses: actions/setup-python@v4
with:
- python-version: 3.9
+ python-version: '3.10'
- name: Install pypa/build
run: >-
@@ -33,7 +38,4 @@
- name: Publish distribution 📦 to PyPI
if: startsWith(github.ref, 'refs/tags')
- uses: pypa/gh-action-pypi-publish@master
- with:
- user: __token__
- password: ${{ secrets.PYPI_API_TOKEN }}
+ uses: pypa/gh-action-pypi-publish@release/v1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.github/workflows/publish-to-test-pypi.yml new/django-classy-tags-4.1.0/.github/workflows/publish-to-test-pypi.yml
--- old/django-classy-tags-3.0.1/.github/workflows/publish-to-test-pypi.yml 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/.github/workflows/publish-to-test-pypi.yml 2023-07-29 04:21:05.000000000 +0200
@@ -9,12 +9,17 @@
build-n-publish:
name: Build and publish Python 🐍 distributions 📦 to TestPyPI
runs-on: ubuntu-latest
+ environment:
+ name: test
+ url: https://test.pypi.org/p/django-classy-tags
+ permissions:
+ id-token: write
steps:
- - uses: actions/checkout@master
- - name: Set up Python 3.9
- uses: actions/setup-python@v1
+ - uses: actions/checkout@v3
+ - name: Set up Python 3.10
+ uses: actions/setup-python@v4
with:
- python-version: 3.9
+ python-version: '3.10'
- name: Install pypa/build
run: >-
@@ -32,9 +37,7 @@
.
- name: Publish distribution 📦 to Test PyPI
- uses: pypa/gh-action-pypi-publish@master
+ uses: pypa/gh-action-pypi-publish@release/v1
with:
- user: __token__
- password: ${{ secrets.TEST_PYPI_API_TOKEN }}
- repository_url: https://test.pypi.org/legacy/
- skip_existing: true
+ repository-url: https://test.pypi.org/legacy/
+ skip-existing: true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.github/workflows/test.yml new/django-classy-tags-4.1.0/.github/workflows/test.yml
--- old/django-classy-tags-3.0.1/.github/workflows/test.yml 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/.github/workflows/test.yml 2023-07-29 04:21:05.000000000 +0200
@@ -4,60 +4,76 @@
jobs:
unit-tests:
+ # Runs for all supported Django/Python versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
- python-version: ['3.7', '3.8', '3.9', '3.10']
- django-version: ['2.2', '3.1', '3.2']
+ python-version: ['3.8', '3.9', '3.10', '3.11']
+ django-version: ['3.2', '4.0', '4.1', '4.2']
os: [
ubuntu-20.04,
]
+ exclude:
+ - python-version: '3.11'
+ django-version: '3.2'
+ - python-version: '3.11'
+ django-version: '4.0'
+ - python-version: '3.8'
+ django-version: '4.2'
+ - python-version: '3.9'
+ django-version: '4.2'
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- pip install django==${{ matrix.django-version }} coverage
+ pip install Django==${{ matrix.django-version }} coverage
python setup.py install
- name: Run coverage
run: coverage run setup.py test
- name: Upload Coverage to Codecov
- uses: codecov/codecov-action@v1
+ uses: codecov/codecov-action@v3
- unit-tests-dj4:
+
+ unit-tests-future-versions:
+ # Runs for all Django/Python versions which are not yet supported
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
- python-version: ['3.8', '3.9', '3.10']
+ python-version: ['3.10', '3.11']
+ django-version: [
+ 'https://github.com/django/django/archive/main.tar.gz'
+ ]
os: [
ubuntu-20.04,
]
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- pip install "django>=4.0,<4.1" coverage
+ pip install ${{ matrix.django-version }} coverage
python setup.py install
- name: Run coverage
run: coverage run setup.py test
+ continue-on-error: true
- name: Upload Coverage to Codecov
- uses: codecov/codecov-action@v1
+ uses: codecov/codecov-action@v3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/.pre-commit-config.yaml new/django-classy-tags-4.1.0/.pre-commit-config.yaml
--- old/django-classy-tags-3.0.1/.pre-commit-config.yaml 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/.pre-commit-config.yaml 2023-07-29 04:21:05.000000000 +0200
@@ -1,15 +1,15 @@
repos:
- repo: https://github.com/asottile/pyupgrade
- rev: v2.31.0
+ rev: v2.32.1
hooks:
- id: pyupgrade
args: ["--py37-plus"]
- repo: https://github.com/adamchainz/django-upgrade
- rev: '1.4.0'
+ rev: '1.6.1'
hooks:
- id: django-upgrade
- args: [--target-version, "2.2"]
+ args: [--target-version, "3.2"]
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
@@ -22,7 +22,7 @@
- id: yesqa
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.1.0
+ rev: v4.2.0
hooks:
- id: check-merge-conflict
- id: mixed-line-ending
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/CHANGELOG.rst new/django-classy-tags-4.1.0/CHANGELOG.rst
--- old/django-classy-tags-3.0.1/CHANGELOG.rst 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/CHANGELOG.rst 2023-07-29 04:21:05.000000000 +0200
@@ -5,6 +5,21 @@
unreleased
==========
+4.1.0 2023-07-29
+================
+
+* Django 4.2 support
+
+
+4.0.0 2022-12-01
+================
+
+* Dropped support for Python 3.7
+* Added support for Python 3.11
+* Dropped support for Django < 3.2
+* Added support for Django 4.1
+* Start testing against Django's `main` branch
+
3.0.1 2022-02-01
================
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/README.rst new/django-classy-tags-4.1.0/README.rst
--- old/django-classy-tags-3.0.1/README.rst 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/README.rst 2023-07-29 04:21:05.000000000 +0200
@@ -107,7 +107,7 @@
.. |coverage| image:: https://codecov.io/gh/divio/django-classy-tags/branch/master/graph/badge.svg
:target: https://codecov.io/gh/divio/django-classy-tags
-.. |python| image:: https://img.shields.io/badge/python-3.5+-blue.svg
+.. |python| image:: https://img.shields.io/badge/python-3.7+-blue.svg
:target: https://pypi.org/project/django-classy-tags/
-.. |django| image:: https://img.shields.io/badge/django-2.2,%203.0,%203.1-blue.svg
+.. |django| image:: https://img.shields.io/badge/django-3.2,%204.0,%204.0-blue.svg
:target: https://www.djangoproject.com/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/classytags/__init__.py new/django-classy-tags-4.1.0/classytags/__init__.py
--- old/django-classy-tags-3.0.1/classytags/__init__.py 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/classytags/__init__.py 2023-07-29 04:21:05.000000000 +0200
@@ -1 +1 @@
-__version__ = '3.0.1'
+__version__ = '4.1.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/classytags/core.py new/django-classy-tags-4.1.0/classytags/core.py
--- old/django-classy-tags-3.0.1/classytags/core.py 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/classytags/core.py 2023-07-29 04:21:05.000000000 +0200
@@ -108,22 +108,13 @@
class TagMeta(type):
"""
Metaclass for the Tag class that set's the name attribute onto the class
- and a _decorated_function pseudo-function which is used by Django's
- template system to get the tag name.
"""
def __new__(cls, name, bases, attrs):
- parents = [base for base in bases if isinstance(base, TagMeta)]
- if not parents:
+ if not any(base for base in bases if isinstance(base, TagMeta)):
return super().__new__(cls, name, bases, attrs)
tag_name = str(attrs.get('name', get_default_name(name)))
-
- def fake_func():
- pass # pragma: no cover
-
- fake_func.__name__ = tag_name
- attrs['_decorated_function'] = fake_func
- attrs['name'] = str(tag_name)
- return super().__new__(cls, name, bases, attrs)
+ attrs['name'] = tag_name
+ return super().__new__(cls, tag_name, bases, attrs)
class Tag(TagMeta('TagMeta', (Node,), {})):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/docs/conf.py new/django-classy-tags-4.1.0/docs/conf.py
--- old/django-classy-tags-3.0.1/docs/conf.py 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/docs/conf.py 2023-07-29 04:21:05.000000000 +0200
@@ -50,9 +50,9 @@
# built documents.
#
# The short X.Y version.
-version = '3.0.1'
+version = '4.1.0'
# The full version, including alpha/beta/rc tags.
-release = '3.0.1'
+release = '4.1.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/docs/requirements.txt new/django-classy-tags-4.1.0/docs/requirements.txt
--- old/django-classy-tags-3.0.1/docs/requirements.txt 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/docs/requirements.txt 2023-07-29 04:21:05.000000000 +0200
@@ -4,17 +4,13 @@
#
# pip-compile
#
---trusted-host pypi.python.org
---trusted-host pypi.org
---trusted-host files.pythonhosted.org
-
alabaster==0.7.12
# via sphinx
babel==2.9.1
# via sphinx
beautifulsoup4==4.10.0
# via furo
-certifi==2021.10.8
+certifi==2022.12.7
# via requests
charset-normalizer==2.0.10
# via requests
@@ -23,38 +19,36 @@
colorama==0.4.4
# via sphinx-autobuild
datetime==4.3
- # via -r requirements.in
+ # via -r docs/requirements.in
docutils==0.17.1
# via sphinx
furo==2022.1.2
- # via -r requirements.in
+ # via -r docs/requirements.in
idna==3.3
# via requests
imagesize==1.3.0
# via sphinx
-importlib-metadata==4.10.1
- # via sphinx
jinja2==3.0.3
# via sphinx
livereload==2.6.3
# via sphinx-autobuild
markupsafe==2.0.1
# via
- # -r requirements.in
+ # -r docs/requirements.in
# jinja2
packaging==21.3
# via sphinx
pep517==0.12.0
# via pip-tools
pip-tools==6.4.0
- # via -r requirements.in
+ # via -r docs/requirements.in
pyenchant==3.2.2
# via
- # -r requirements.in
+ # -r docs/requirements.in
# sphinxcontrib-spelling
pygments==2.11.2
# via
- # -r requirements.in
+ # -r docs/requirements.in
# furo
# sphinx
pyparsing==3.0.7
@@ -73,12 +67,12 @@
# via beautifulsoup4
sphinx==4.4.0
# via
- # -r requirements.in
+ # -r docs/requirements.in
# furo
# sphinx-autobuild
# sphinxcontrib-spelling
sphinx-autobuild==2021.3.14
- # via -r requirements.in
+ # via -r docs/requirements.in
sphinxcontrib-applehelp==1.0.2
# via sphinx
sphinxcontrib-devhelp==1.0.2
@@ -92,18 +86,16 @@
sphinxcontrib-serializinghtml==1.1.5
# via sphinx
sphinxcontrib-spelling==7.3.2
- # via -r requirements.in
+ # via -r docs/requirements.in
tomli==2.0.0
# via pep517
tornado==6.1
# via livereload
urllib3==1.26.8
# via requests
-wheel==0.37.1
+wheel==0.38.1
# via pip-tools
-zipp==3.7.0
- # via importlib-metadata
-zope.interface==5.4.0
+zope-interface==5.4.0
# via datetime
# The following packages are considered to be unsafe in a requirements file:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/requirements.in new/django-classy-tags-4.1.0/requirements.in
--- old/django-classy-tags-3.0.1/requirements.in 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/requirements.in 2023-07-29 04:21:05.000000000 +0200
@@ -1,5 +1,5 @@
bump2version
-Django>2.2
+Django>3.2
pip-tools
pre-commit
wheel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/requirements.txt new/django-classy-tags-4.1.0/requirements.txt
--- old/django-classy-tags-3.0.1/requirements.txt 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/requirements.txt 2023-07-29 04:21:05.000000000 +0200
@@ -4,49 +4,47 @@
#
# pip-compile
#
---trusted-host pypi.python.org
---trusted-host pypi.org
---trusted-host files.pythonhosted.org
-
-asgiref==3.4.1
+asgiref==3.5.2
# via django
+build==0.8.0
+ # via pip-tools
bump2version==1.0.1
# via -r requirements.in
cfgv==3.3.1
# via pre-commit
-click==8.0.3
+click==8.1.3
# via pip-tools
-distlib==0.3.4
+distlib==0.3.6
# via virtualenv
-django==4.0.1
+django==4.1.10
# via -r requirements.in
-filelock==3.4.2
+filelock==3.8.0
# via virtualenv
-identify==2.4.4
+identify==2.5.5
# via pre-commit
-nodeenv==1.6.0
+nodeenv==1.7.0
# via pre-commit
-pep517==0.12.0
- # via pip-tools
-pip-tools==6.4.0
+packaging==21.3
+ # via build
+pep517==0.13.0
+ # via build
+pip-tools==6.8.0
# via -r requirements.in
-platformdirs==2.4.1
+platformdirs==2.5.2
# via virtualenv
-pre-commit==2.17.0
+pre-commit==2.20.0
# via -r requirements.in
+pyparsing==3.0.9
+ # via packaging
pyyaml==6.0
# via pre-commit
-six==1.16.0
- # via virtualenv
-sqlparse==0.4.2
+sqlparse==0.4.3
# via django
toml==0.10.2
# via pre-commit
-tomli==2.0.0
- # via pep517
-virtualenv==20.13.0
+virtualenv==20.16.5
# via pre-commit
-wheel==0.37.1
+wheel==0.38.1
# via
# -r requirements.in
# pip-tools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/setup.cfg new/django-classy-tags-4.1.0/setup.cfg
--- old/django-classy-tags-3.0.1/setup.cfg 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/setup.cfg 2023-07-29 04:21:05.000000000 +0200
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 3.0.1
+current_version = 4.1.0
commit = True
tag = False
@@ -39,6 +39,7 @@
build,
data,
dist,
+ docs/env,
docs/conf.py,
*migrations*,
requirements,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/setup.py new/django-classy-tags-4.1.0/setup.py
--- old/django-classy-tags-3.0.1/setup.py 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/setup.py 2023-07-29 04:21:05.000000000 +0200
@@ -5,7 +5,7 @@
REQUIREMENTS = [
- 'django>=2.2',
+ 'django>=3.2',
]
@@ -16,15 +16,15 @@
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: 3.11',
'Framework :: Django',
- 'Framework :: Django :: 2.2',
- 'Framework :: Django :: 3.1',
'Framework :: Django :: 3.2',
'Framework :: Django :: 4.0',
+ 'Framework :: Django :: 4.1',
+ 'Framework :: Django :: 4.2',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Software Development',
@@ -36,7 +36,7 @@
setup(
name='django-classy-tags',
- version='3.0.1',
+ version='4.1.0',
author='Jonas Obrist',
author_email='ojiidotch(a)gmail.com',
maintainer='Django CMS Association and contributors',
@@ -47,7 +47,7 @@
long_description=long_description,
long_description_content_type='text/x-rst',
packages=find_packages(exclude=['tests']),
- python_requires='>=3.7',
+ python_requires='>=3.8',
include_package_data=True,
zip_safe=False,
install_requires=REQUIREMENTS,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/tests/test_core.py new/django-classy-tags-4.1.0/tests/test_core.py
--- old/django-classy-tags-3.0.1/tests/test_core.py 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/tests/test_core.py 2023-07-29 04:21:05.000000000 +0200
@@ -591,6 +591,22 @@
msg = "'my_tag2' in %s" % lib.tags.keys()
self.assertTrue('my_tag2' not in lib.tags, msg)
+ # test decorated naming
+ lib = template.Library()
+
+ @lib.tag(name="my_decorated_tag_5")
+ class MyTag5(core.Tag):
+ pass
+ msg = "'my_decorated_tag_5' not in %s" % lib.tags.keys()
+ self.assertTrue('my_decorated_tag_5' in lib.tags, msg)
+
+ # test decorated and explicit naming
+ # the tag registration takes precedence over the name attribute
+ lib = template.Library()
+ lib.tag('my_decorated_tag_6', MyTag2)
+ msg = "'my_decorated_tag_6' not in %s" % lib.tags.keys()
+ self.assertTrue('my_decorated_tag_6' in lib.tags, msg)
+
def test_hello_world(self):
class Hello(core.Tag):
options = core.Options(
@@ -971,6 +987,12 @@
tag = MyTag(dummy_parser, DummyTokens())
self.assertEqual('<Tag: mytag>', repr(tag))
+ def test_repr_without_explicit_name(self):
+ class MyTag(core.Tag):
+ pass
+ tag = MyTag(dummy_parser, DummyTokens())
+ self.assertEqual('<Tag: my_tag>', repr(tag))
+
def test_non_required_multikwarg(self):
options = core.Options(
arguments.MultiKeywordArgument('multi', required=False),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/django-classy-tags-3.0.1/tox.ini new/django-classy-tags-4.1.0/tox.ini
--- old/django-classy-tags-3.0.1/tox.ini 2022-02-01 23:26:47.000000000 +0100
+++ new/django-classy-tags-4.1.0/tox.ini 2023-07-29 04:21:05.000000000 +0200
@@ -2,23 +2,28 @@
envlist =
flake8
isort
- py{37,38,39}-dj{22,31,32}
- py{38,39,310}-dj{31,32,40}
+ py{38,39,310}-dj{32,40,41}
+ py{310,311}-dj{41,42,main}
skip_missing_interpreters=True
[testenv]
deps =
-r{toxinidir}/tests/requirements/base.txt
- dj22: Django>=2.2,<3.0
- dj31: Django>=3.1,<3.2
dj32: Django>=3.2,<3.3
dj40: Django>=4.0,<4.1
+ dj41: Django>=4.1,<4.2
+ dj42: Django>=4.2,<5.0
+ djmain: https://github.com/django/django/archive/main.tar.gz
commands =
{envpython} --version
{env:COMMAND:coverage} erase
{env:COMMAND:coverage} run setup.py test
{env:COMMAND:coverage} report
+ignore_outcome =
+ djmain: True
+ignore_errors =
+ djmain: True
[testenv:flake8]
deps = flake8
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-cloudflare for openSUSE:Factory checked in at 2023-11-30 22:00:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cloudflare (Old)
and /work/SRC/openSUSE:Factory/.python-cloudflare.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-cloudflare"
Thu Nov 30 22:00:37 2023 rev:14 rq:1129789 version:2.14.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cloudflare/python-cloudflare.changes 2023-10-05 20:06:17.097501612 +0200
+++ /work/SRC/openSUSE:Factory/.python-cloudflare.new.25432/python-cloudflare.changes 2023-11-30 22:01:27.417359734 +0100
@@ -1,0 +2,19 @@
+Wed Nov 29 12:09:24 UTC 2023 - Dirk Müller <dmueller(a)suse.com>
+
+- update to 2.14.2:
+ * added AI info
+ * account name via -a flag now. should not be needed
+ * stable diffusion example
+ * move config info into code
+ * first pass a new AI API calls
+ * cleanup of usage, added more flag descriptions
+ * cleanup of usage and getops values - now consistent
+ * timeout values now work from config or api call,
+ added support for image binary results, fixed logging if binary
+ * handle raw byte output either via --image flag or if return
+ from api is bytes
+ * more api endpoints
+ * added ips and issue114 tests
+ * add importlib_resources info for older Python versions
+
+-------------------------------------------------------------------
Old:
----
cloudflare-2.12.4.tar.gz
New:
----
cloudflare-2.14.2.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-cloudflare.spec ++++++
--- /var/tmp/diff_new_pack.il9ClS/_old 2023-11-30 22:01:27.965379922 +0100
+++ /var/tmp/diff_new_pack.il9ClS/_new 2023-11-30 22:01:27.969380070 +0100
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-cloudflare
-Version: 2.12.4
+Version: 2.14.2
Release: 0
Summary: Python wrapper for the Cloudflare v4 API
License: MIT
++++++ cloudflare-2.12.4.tar.gz -> cloudflare-2.14.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/CloudFlare/__init__.py new/cloudflare-2.14.2/CloudFlare/__init__.py
--- old/cloudflare-2.12.4/CloudFlare/__init__.py 2023-09-22 03:45:07.000000000 +0200
+++ new/cloudflare-2.14.2/CloudFlare/__init__.py 2023-11-26 05:05:05.000000000 +0100
@@ -1,6 +1,6 @@
""" Cloudflare v4 API"""
-__version__ = '2.12.4'
+__version__ = '2.14.2'
from .cloudflare import CloudFlare
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/CloudFlare/api_v4.py new/cloudflare-2.14.2/CloudFlare/api_v4.py
--- old/cloudflare-2.12.4/CloudFlare/api_v4.py 2023-09-19 21:23:01.000000000 +0200
+++ new/cloudflare-2.14.2/CloudFlare/api_v4.py 2023-11-25 19:04:44.000000000 +0100
@@ -390,12 +390,15 @@
self.add('AUTH', 'accounts', 'custom_pages')
self.add('VOID', 'accounts', 'dlp')
+ self.add('AUTH', 'accounts', 'dlp/datasets')
+ self.add('AUTH', 'accounts', 'dlp/datasets', 'upload')
self.add('VOID', 'accounts', 'dlp/patterns')
self.add('AUTH', 'accounts', 'dlp/patterns/validate')
self.add('AUTH', 'accounts', 'dlp/payload_log')
self.add('AUTH', 'accounts', 'dlp/profiles')
self.add('AUTH', 'accounts', 'dlp/profiles/custom')
self.add('AUTH', 'accounts', 'dlp/profiles/predefined')
+
self.add('AUTH', 'accounts', 'members')
self.add('VOID', 'accounts', 'mnm')
self.add('AUTH', 'accounts', 'mnm/config')
@@ -447,6 +450,9 @@
self.add('VOID', 'accounts', 'vectorize')
self.add('AUTH', 'accounts', 'vectorize/index')
self.add('AUTH', 'accounts', 'vectorize/indexes')
+ self.add('AUTH', 'accounts', 'vectorize/indexes', 'insert')
+ self.add('AUTH', 'accounts', 'vectorize/indexes', 'query')
+ self.add('AUTH', 'accounts', 'vectorize/indexes', 'upsert')
self.add('AUTH', 'accounts', 'virtual_dns')
self.add('VOID', 'accounts', 'virtual_dns', 'dns_analytics')
@@ -624,8 +630,12 @@
self.add('VOID', 'accounts', 'access/logs')
self.add('AUTH', 'accounts', 'access/logs/access_requests')
self.add('AUTH', 'accounts', 'access/seats')
+ self.add('AUTH', 'accounts', 'access/tags')
self.add('AUTH', 'accounts', 'access/users')
self.add('AUTH', 'accounts', 'access/users', 'failed_logins')
+ self.add('AUTH', 'accounts', 'access/users', 'active_sessions')
+ self.add('AUTH', 'accounts', 'access/users', 'last_seen_identity')
+
def accounts_diagnostics(self):
""" accounts diagnostics """
@@ -647,12 +657,16 @@
def accounts_extras(self):
""" extras """
+ self.add('VOID', 'accounts', 'ai')
+ self.add('AUTH', 'accounts', 'ai/run')
+
self.add('VOID', 'accounts', 'alerting')
self.add('VOID', 'accounts', 'alerting/v3')
self.add('AUTH', 'accounts', 'alerting/v3/available_alerts')
self.add('VOID', 'accounts', 'alerting/v3/destinations')
self.add('AUTH', 'accounts', 'alerting/v3/destinations/eligible')
self.add('AUTH', 'accounts', 'alerting/v3/destinations/pagerduty')
+ self.add('AUTH', 'accounts', 'alerting/v3/destinations/pagerduty/connect')
self.add('AUTH', 'accounts', 'alerting/v3/destinations/webhooks')
self.add('AUTH', 'accounts', 'alerting/v3/history')
self.add('AUTH', 'accounts', 'alerting/v3/policies')
@@ -682,13 +696,19 @@
self.add('VOID', 'accounts', 'dex')
self.add('AUTH', 'accounts', 'dex/colos')
+ self.add('VOID', 'accounts', 'dex/fleet-status')
+ self.add('AUTH', 'accounts', 'dex/fleet-status/devices')
+ self.add('AUTH', 'accounts', 'dex/fleet-status/live')
+ self.add('AUTH', 'accounts', 'dex/fleet-status/over-time')
self.add('AUTH', 'accounts', 'dex/http-tests')
+ self.add('AUTH', 'accounts', 'dex/http-tests', 'percentiles')
self.add('AUTH', 'accounts', 'dex/tests')
self.add('AUTH', 'accounts', 'dex/tests/unique-devices')
self.add('VOID', 'accounts', 'dex/traceroute-test-results')
self.add('AUTH', 'accounts', 'dex/traceroute-test-results', 'network-path')
self.add('AUTH', 'accounts', 'dex/traceroute-tests')
self.add('AUTH', 'accounts', 'dex/traceroute-tests', 'network-path')
+ self.add('AUTH', 'accounts', 'dex/traceroute-tests', 'percentiles')
self.add('AUTH', 'accounts', 'dns_firewall')
self.add('VOID', 'accounts', 'dns_firewall', 'dns_analytics')
@@ -697,6 +717,7 @@
self.add('AUTH', 'accounts', 'gateway')
self.add('AUTH', 'accounts', 'gateway/app_types')
+ self.add('AUTH', 'accounts', 'gateway/audit_ssh_settings')
self.add('AUTH', 'accounts', 'gateway/categories')
self.add('AUTH', 'accounts', 'gateway/configuration')
self.add('AUTH', 'accounts', 'gateway/lists')
@@ -773,17 +794,30 @@
self.add('VOID', 'accounts', 'hyperdrive')
self.add('AUTH', 'accounts', 'hyperdrive/configs')
+ self.add('AUTH', 'accounts', 'warp_connector')
+ self.add('AUTH', 'accounts', 'warp_connector', 'token')
+
+ self.add('VOID', 'accounts', 'zerotrust')
+ self.add('AUTH', 'accounts', 'zerotrust/connectivity_settings')
+
+ self.add('VOID', 'accounts', 'd1')
+ self.add('AUTH', 'accounts', 'd1/database')
+ self.add('AUTH', 'accounts', 'd1/database', 'query')
def zones_extras(self):
""" zones extras """
self.add('VOID', 'zones', 'acm')
self.add('AUTH', 'zones', 'acm/total_tls')
+
self.add('VOID', 'zones', 'cache')
- self.add('AUTH', 'zones', 'cache/variants')
self.add('AUTH', 'zones', 'cache/cache_reserve')
+ self.add('AUTH', 'zones', 'cache/cache_reserve_clear')
+ self.add('AUTH', 'zones', 'cache/origin_post_quantum_encryption')
self.add('AUTH', 'zones', 'cache/regional_tiered_cache')
self.add('AUTH', 'zones', 'cache/tiered_cache_smart_topology_enable')
+ self.add('AUTH', 'zones', 'cache/variants')
+
self.add('AUTH', 'zones', 'managed_headers')
self.add('AUTH', 'zones', 'page_shield')
self.add('AUTH', 'zones', 'page_shield/policies')
@@ -857,8 +891,16 @@
self.add('VOID', 'zones', 'api_gateway')
self.add('AUTH', 'zones', 'api_gateway/configuration')
self.add('AUTH', 'zones', 'api_gateway/discovery')
+ self.add('AUTH', 'zones', 'api_gateway/discovery/operations')
self.add('AUTH', 'zones', 'api_gateway/operations')
+ self.add('AUTH', 'zones', 'api_gateway/operations', 'schema_validation')
+# self.add('AUTH', 'zones', 'api_gateway/operations/schema_validation')
self.add('AUTH', 'zones', 'api_gateway/schemas')
+ self.add('VOID', 'zones', 'api_gateway/settings')
+ self.add('AUTH', 'zones', 'api_gateway/settings/schema_validation')
+ self.add('AUTH', 'zones', 'api_gateway/user_schemas')
+ self.add('AUTH', 'zones', 'api_gateway/user_schemas', 'operations')
+
def radar(self):
""" radar """
@@ -919,20 +961,38 @@
self.add('AUTH', 'radar/attacks/layer3/timeseries_groups/vector')
self.add('AUTH', 'radar/attacks/layer3/timeseries_groups/vertical')
self.add('VOID', 'radar/attacks/layer3/top')
+ self.add('AUTH', 'radar/attacks/layer3/top/attacks')
self.add('AUTH', 'radar/attacks/layer3/top/industry')
+ self.add('VOID', 'radar/attacks/layer3/top/locations')
+ self.add('AUTH', 'radar/attacks/layer3/top/locations/origin')
+ self.add('AUTH', 'radar/attacks/layer3/top/locations/target')
self.add('AUTH', 'radar/attacks/layer3/top/vertical')
self.add('VOID', 'radar/attacks/layer7')
self.add('AUTH', 'radar/attacks/layer7/summary')
+ self.add('AUTH', 'radar/attacks/layer7/summary/http_method')
+ self.add('AUTH', 'radar/attacks/layer7/summary/http_version')
+ self.add('AUTH', 'radar/attacks/layer7/summary/ip_version')
+ self.add('AUTH', 'radar/attacks/layer7/summary/managed_rules')
+ self.add('AUTH', 'radar/attacks/layer7/summary/mitigation_product')
self.add('AUTH', 'radar/attacks/layer7/timeseries')
self.add('AUTH', 'radar/attacks/layer7/timeseries_groups')
+ self.add('AUTH', 'radar/attacks/layer7/timeseries_groups/http_method')
+ self.add('AUTH', 'radar/attacks/layer7/timeseries_groups/http_version')
+ self.add('AUTH', 'radar/attacks/layer7/timeseries_groups/industry')
+ self.add('AUTH', 'radar/attacks/layer7/timeseries_groups/ip_version')
+ self.add('AUTH', 'radar/attacks/layer7/timeseries_groups/managed_rules')
+ self.add('AUTH', 'radar/attacks/layer7/timeseries_groups/mitigation_product')
+ self.add('AUTH', 'radar/attacks/layer7/timeseries_groups/vertical')
self.add('VOID', 'radar/attacks/layer7/top')
self.add('VOID', 'radar/attacks/layer7/top/ases')
self.add('AUTH', 'radar/attacks/layer7/top/ases/origin')
self.add('AUTH', 'radar/attacks/layer7/top/attacks')
+ self.add('AUTH', 'radar/attacks/layer7/top/industry')
self.add('VOID', 'radar/attacks/layer7/top/locations')
self.add('AUTH', 'radar/attacks/layer7/top/locations/origin')
self.add('AUTH', 'radar/attacks/layer7/top/locations/target')
+ self.add('AUTH', 'radar/attacks/layer7/top/vertical')
self.add('VOID', 'radar/bgp')
self.add('VOID', 'radar/bgp/leaks')
@@ -1102,6 +1162,7 @@
self.add('AUTH', 'radar/traffic_anomalies')
self.add('AUTH', 'radar/traffic_anomalies/locations')
+
def from_developers(self):
""" from_developers """
self.add('VOID', 'accounts', 'analytics_engine')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/CloudFlare/cloudflare.py new/cloudflare-2.14.2/CloudFlare/cloudflare.py
--- old/cloudflare-2.12.4/CloudFlare/cloudflare.py 2023-09-21 19:03:51.000000000 +0200
+++ new/cloudflare-2.14.2/CloudFlare/cloudflare.py 2023-11-25 21:03:43.000000000 +0100
@@ -15,6 +15,9 @@
BASE_URL = 'https://api.cloudflare.com/client/v4'
+DEFAULT_GLOBAL_REQUEST_TIMEOUT = 5
+DEFAULT_MAX_REQUEST_RETRIES = 5
+
class CloudFlare():
""" Cloudflare v4 API"""
@@ -24,6 +27,7 @@
def __init__(self, config):
""" Cloudflare v4 API"""
+ self.network = None
self.config = config
self.api_email = config['email'] if 'email' in config else None
@@ -36,8 +40,16 @@
self.raw = config['raw']
self.use_sessions = config['use_sessions']
- self.global_request_timeout = config['global_request_timeout'] if 'global_request_timeout' in config else None
- self.max_request_retries = config['max_request_retries'] if 'max_request_retries' in config else None
+ self.global_request_timeout = config['global_request_timeout'] if 'global_request_timeout' in config else DEFAULT_GLOBAL_REQUEST_TIMEOUT
+ self.max_request_retries = config['max_request_retries'] if 'max_request_retries' in config else DEFAULT_MAX_REQUEST_RETRIES
+ try:
+ self.global_request_timeout = int(self.global_request_timeout)
+ except (TypeError, ValueError):
+ self.global_request_timeout = DEFAULT_GLOBAL_REQUEST_TIMEOUT
+ try:
+ self.max_request_retries = int(self.max_request_retries)
+ except (TypeError, ValueError):
+ self.max_request_retries = DEFAULT_MAX_REQUEST_RETRIES
self.profile = config['profile']
self.network = CFnetwork(
use_sessions=self.use_sessions,
@@ -245,7 +257,10 @@
response_data = response_data.decode("utf-8")
if self.logger:
- self.logger.debug('Response: %d, %s, %s', response_code, response_type, response_data)
+ if 'text/' == response_type[0:5] or response_type in ['application/javascript', 'application/json']:
+ self.logger.debug('Response: %d, %s, %s', response_code, response_type, response_data[0:100])
+ else:
+ self.logger.debug('Response: %d, %s, %s', response_code, response_type, '...')
if response_code >= 500 and response_code <= 599:
# 500 Internal Server Error
@@ -421,6 +436,14 @@
'code': response_code,
'result': str(response_data)}
+ elif response_type[0:6] in ['audio/', 'image/', 'video/']:
+ # raw - just pass thru
+ if response_code == requests_codes.ok:
+ response_data = {'success': True, 'result': response_data}
+ else:
+ response_data = {'success': False,
+ 'code': response_code,
+ 'result': response_data}
else:
# Assuming nothing - but continuing anyway
# A single value is returned (vs an array or object)
@@ -531,7 +554,10 @@
except:
result = response_data
if self.logger:
- self.logger.debug('Response: %s', result)
+ if isinstance(result, str):
+ self.logger.debug('Response: %s', result[0:100])
+ else:
+ self.logger.debug('Response: %s', '...')
return result
def _call_unwrapped(self, method, headers, parts, identifiers, params, data, files):
@@ -913,7 +939,7 @@
return api_decode_from_openapi(self._base.api_from_openapi(url))
- def __init__(self, email=None, key=None, token=None, certtoken=None, debug=False, raw=False, use_sessions=True, profile=None, base_url=None, global_request_timeout=5, max_request_retries=5):
+ def __init__(self, email=None, key=None, token=None, certtoken=None, debug=False, raw=False, use_sessions=True, profile=None, base_url=None, global_request_timeout=None, max_request_retries=None):
""" Cloudflare v4 API"""
self._base = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/CloudFlare/network.py new/cloudflare-2.14.2/CloudFlare/network.py
--- old/cloudflare-2.12.4/CloudFlare/network.py 2023-09-21 19:03:51.000000000 +0200
+++ new/cloudflare-2.14.2/CloudFlare/network.py 2023-11-25 19:54:13.000000000 +0100
@@ -12,7 +12,7 @@
"""Network for Cloudflare API"""
def __init__(
- self, max_request_retries, use_sessions=True, global_request_timeout=5,
+ self, use_sessions=True, global_request_timeout=5, max_request_retries=5
):
"""Network for Cloudflare API"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/CloudFlare/read_configs.py new/cloudflare-2.14.2/CloudFlare/read_configs.py
--- old/cloudflare-2.12.4/CloudFlare/read_configs.py 2022-09-08 01:46:45.000000000 +0200
+++ new/cloudflare-2.14.2/CloudFlare/read_configs.py 2023-11-25 20:15:16.000000000 +0100
@@ -21,6 +21,9 @@
config['extras'] = os.getenv('CLOUDFLARE_API_EXTRAS') if os.getenv('CLOUDFLARE_API_EXTRAS') is not None else os.getenv('CF_API_EXTRAS')
config['base_url'] = os.getenv('CLOUDFLARE_API_URL') if os.getenv('CLOUDFLARE_API_URL') is not None else os.getenv('CF_API_URL')
+ config['global_request_timeout'] = os.getenv('CLOUDFLARE_GLOBAL_REQUEST_TIMEOUT')
+ config['max_request_retries'] = os.getenv('CLOUDFLARE_MAX_REQUEST_RETRIES')
+
# grab values from config files
cp = configparser.ConfigParser()
try:
@@ -55,7 +58,7 @@
if not cp.has_section(profile):
raise Exception("%s: configuration section missing - configuration file only has these sections: %s" % (profile, ','.join(cp.sections())))
- for option in ['email', 'key', 'token', 'certtoken', 'extras', 'base_url']:
+ for option in ['email', 'key', 'token', 'certtoken', 'extras', 'base_url', 'global_request_timeout', 'max_request_retries']:
try:
config_value = cp.get(profile, option)
if option == 'extras':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/PKG-INFO new/cloudflare-2.14.2/PKG-INFO
--- old/cloudflare-2.12.4/PKG-INFO 2023-09-22 03:47:10.381636400 +0200
+++ new/cloudflare-2.14.2/PKG-INFO 2023-11-26 05:05:51.078833000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: cloudflare
-Version: 2.12.4
+Version: 2.14.2
Summary: Python wrapper for the Cloudflare v4 API
Home-page: https://github.com/cloudflare/python-cloudflare
Author: Martin J. Levy
@@ -481,7 +481,7 @@
### Exception examples
-Here's examples using the CLI command cli4 of the responses passed back in exceptions.
+Here's examples using the CLI command `cli4` of the responses passed back in exceptions.
First a simple get with a clean (non-error) response.
@@ -551,16 +551,16 @@
$
```
-It will show up if you are running on an older system. For example, this is the results from running on Win7):
+It will show up if you are running on an older system. For example, this is the results from running on Win7:
```bash
-U:\Users\█████>cli4 -e
+U:\Users\Bobby>cli4 -e
Module "importlib_resources" missing - please "pip install importlib_resources" as your Python version is lower than 3.9
-U:\Users\█████>python -V
+U:\Users\Bobby>python -V
Python 3.8.3
-U:\Users\█████>
+U:\Users\Bobby>
```
Upgrading from an older version of Python is always recommended. Upgrading from Win7 is by-default even more important!
@@ -622,12 +622,23 @@
## CLI
-All API calls can be called from the command line.
-The command will convert domain names prefixed with a colon (`:`) into zone_identifiers: e.g. to view `example.com` you must use `cli4 /zones/:example.com` (the zone ID cannot be used).
-
-```bash
-$ cli4 [-V|--version] [-h|--help] [-v|--verbose] [-q|--quiet] [-j|--json] [-y|--yaml] [-n|ndjson] [-r|--raw] [-d|--dump] [-A|--openapi url] [-b|--binary] [-p|--profile profile-name] [--get|--patch|--post|--put|--delete] [item=value|item=@filename|@filename ...] /command ...
-
+All API calls can be called from the command line via the `cli4` command.
+Additionally, the `cli4` command will convert domain name or account name prefixed with a colon (`:`) into the correct identifier.
+e.g. to view `example.com` you can use `cli4 /zones/:example.com`.
+You can pass the zone identifier (or account identifier or any identifier) with a colon followed by the identifier as a hex number 32 characters long.
+
+```bash
+$ cli4 [-V|--version] [-h|--help] [-v|--verbose] \
+ [-e|--examples] \
+ [-q|--quiet] \
+ [-j|--json] [-y|--yaml] [-n|--ndjson] [-i|--image] \
+ [-r|--raw] \
+ [-d|--dump] \
+ [-A|--openapi url] \
+ [-b|--binary] \
+ [-p|--profile profile-name] \
+ [--get|--patch|--post|--put|--delete] \
+ [item=value|item=@filename|@filename ...] /command ...
```
### CLI parameters for POST/PUT/PATCH
@@ -663,7 +674,13 @@
### CLI output
-The output from the CLI command is in JSON or YAML format (and human readable). This is controled by the **--yaml** or **--json** flags (JSON is the default).
+The default output from the CLI command is in JSON.
+It can also output YAML format (i.e. human readable).
+This is controled by the `--yaml` or `--json` flags (JSON is the default).
+There is also a `--ndjson` flag for use with line based JSON data - this is mainly used for log data.
+
+Additonally the output can be plain text or binary image format depending on the results from the API call (some calls results in non JSON results).
+The `--image` flag will return the data in the same format as the API's results.
### Simple CLI examples
@@ -1266,6 +1283,63 @@
For more information on how to use GraphQL at Cloudflare, refer to the [Cloudflare GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api).
It contains a full overview of Cloudflare's GraphQL features and keywords.
+## Cloudflare AI
+
+See https://blog.cloudflare.com/workers-ai-update-stable-diffusion-code-llama-w… for the introduction,
+along with https://developers.cloudflare.com/workers-ai/models/ for the nitty gritty details.
+
+There are two examples for AI calls included with the code.
+
+```bash
+$ python examples/example_ai_images.py A happy llama running through an orange cloud > /tmp/image.png
+$
+$ file /tmp/image.png
+/tmp/image.png: PNG image data, 1024 x 1024, 8-bit/color RGB, non-interlaced
+$
+```
+
+```bash
+$ python examples/example_ai_translate.py I\'ll have an order of the moule frites
+Je vais avoir une commande des frites de moule
+$
+```
+
+This is presently work-in-progress because of the non-Python calling method. The syntax could change in the future.
+The examples will be updated.
+
+They can also be called via `cli4`.
+
+```bash
+$ cli4 --image --post text="I'll have an order of the moule frites" source_lang=english target_lang=french /accounts/:AccountID/ai/run/@cf/meta/m2m100-1.2b
+{'translated_text': 'Je vais avoir une commande des frites de moule'}
+$
+```
+
+Presently you will need the following in your `cloudflare.cfg` file.
+
+```bash
+$ cat ~/.cloudflare/cloudflare.cfg
+[CloudFlare]
+global_request_timeout = 120
+max_request_retries = 1
+extras =
+ /accounts/:id/ai/run/@cf/meta/llama-2-7b-chat-fp16
+ /accounts/:id/ai/run/@cf/meta/llama-2-7b-chat-int8
+ /accounts/:id/ai/run/@cf/mistral/mistral-7b-instruct-v0.1
+ /accounts/:id/ai/run/@cf/openai/whisper
+ /accounts/:id/ai/run/@cf/meta/m2m100-1.2b
+ /accounts/:id/ai/run/@cf/huggingface/distilbert-sst-2-int8
+ /accounts/:id/ai/run/@cf/microsoft/resnet-50
+ /accounts/:id/ai/run/@cf/stabilityai/stable-diffusion-xl-base-1.0
+ /accounts/:id/ai/run/@cf/baai/bge-base-en-v1.5
+ /accounts/:id/ai/run/@cf/baai/bge-large-en-v1.5
+ /accounts/:id/ai/run/@cf/baai/bge-small-en-v1.5
+
+$
+```
+
+Along with a version of the library above `2.14.1`.
+
## Implemented API calls
The **--dump** argument to cli4 will produce a list of all the call implemented within the library.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/README.md new/cloudflare-2.14.2/README.md
--- old/cloudflare-2.12.4/README.md 2023-09-21 19:32:37.000000000 +0200
+++ new/cloudflare-2.14.2/README.md 2023-11-26 05:04:23.000000000 +0100
@@ -463,7 +463,7 @@
### Exception examples
-Here's examples using the CLI command cli4 of the responses passed back in exceptions.
+Here's examples using the CLI command `cli4` of the responses passed back in exceptions.
First a simple get with a clean (non-error) response.
@@ -533,16 +533,16 @@
$
```
-It will show up if you are running on an older system. For example, this is the results from running on Win7):
+It will show up if you are running on an older system. For example, this is the results from running on Win7:
```bash
-U:\Users\█████>cli4 -e
+U:\Users\Bobby>cli4 -e
Module "importlib_resources" missing - please "pip install importlib_resources" as your Python version is lower than 3.9
-U:\Users\█████>python -V
+U:\Users\Bobby>python -V
Python 3.8.3
-U:\Users\█████>
+U:\Users\Bobby>
```
Upgrading from an older version of Python is always recommended. Upgrading from Win7 is by-default even more important!
@@ -604,12 +604,23 @@
## CLI
-All API calls can be called from the command line.
-The command will convert domain names prefixed with a colon (`:`) into zone_identifiers: e.g. to view `example.com` you must use `cli4 /zones/:example.com` (the zone ID cannot be used).
-
-```bash
-$ cli4 [-V|--version] [-h|--help] [-v|--verbose] [-q|--quiet] [-j|--json] [-y|--yaml] [-n|ndjson] [-r|--raw] [-d|--dump] [-A|--openapi url] [-b|--binary] [-p|--profile profile-name] [--get|--patch|--post|--put|--delete] [item=value|item=@filename|@filename ...] /command ...
-
+All API calls can be called from the command line via the `cli4` command.
+Additionally, the `cli4` command will convert domain name or account name prefixed with a colon (`:`) into the correct identifier.
+e.g. to view `example.com` you can use `cli4 /zones/:example.com`.
+You can pass the zone identifier (or account identifier or any identifier) with a colon followed by the identifier as a hex number 32 characters long.
+
+```bash
+$ cli4 [-V|--version] [-h|--help] [-v|--verbose] \
+ [-e|--examples] \
+ [-q|--quiet] \
+ [-j|--json] [-y|--yaml] [-n|--ndjson] [-i|--image] \
+ [-r|--raw] \
+ [-d|--dump] \
+ [-A|--openapi url] \
+ [-b|--binary] \
+ [-p|--profile profile-name] \
+ [--get|--patch|--post|--put|--delete] \
+ [item=value|item=@filename|@filename ...] /command ...
```
### CLI parameters for POST/PUT/PATCH
@@ -645,7 +656,13 @@
### CLI output
-The output from the CLI command is in JSON or YAML format (and human readable). This is controled by the **--yaml** or **--json** flags (JSON is the default).
+The default output from the CLI command is in JSON.
+It can also output YAML format (i.e. human readable).
+This is controled by the `--yaml` or `--json` flags (JSON is the default).
+There is also a `--ndjson` flag for use with line based JSON data - this is mainly used for log data.
+
+Additonally the output can be plain text or binary image format depending on the results from the API call (some calls results in non JSON results).
+The `--image` flag will return the data in the same format as the API's results.
### Simple CLI examples
@@ -1248,6 +1265,63 @@
For more information on how to use GraphQL at Cloudflare, refer to the [Cloudflare GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api).
It contains a full overview of Cloudflare's GraphQL features and keywords.
+## Cloudflare AI
+
+See https://blog.cloudflare.com/workers-ai-update-stable-diffusion-code-llama-w… for the introduction,
+along with https://developers.cloudflare.com/workers-ai/models/ for the nitty gritty details.
+
+There are two examples for AI calls included with the code.
+
+```bash
+$ python examples/example_ai_images.py A happy llama running through an orange cloud > /tmp/image.png
+$
+$ file /tmp/image.png
+/tmp/image.png: PNG image data, 1024 x 1024, 8-bit/color RGB, non-interlaced
+$
+```
+
+```bash
+$ python examples/example_ai_translate.py I\'ll have an order of the moule frites
+Je vais avoir une commande des frites de moule
+$
+```
+
+This is presently work-in-progress because of the non-Python calling method. The syntax could change in the future.
+The examples will be updated.
+
+They can also be called via `cli4`.
+
+```bash
+$ cli4 --image --post text="I'll have an order of the moule frites" source_lang=english target_lang=french /accounts/:AccountID/ai/run/@cf/meta/m2m100-1.2b
+{'translated_text': 'Je vais avoir une commande des frites de moule'}
+$
+```
+
+Presently you will need the following in your `cloudflare.cfg` file.
+
+```bash
+$ cat ~/.cloudflare/cloudflare.cfg
+[CloudFlare]
+global_request_timeout = 120
+max_request_retries = 1
+extras =
+ /accounts/:id/ai/run/@cf/meta/llama-2-7b-chat-fp16
+ /accounts/:id/ai/run/@cf/meta/llama-2-7b-chat-int8
+ /accounts/:id/ai/run/@cf/mistral/mistral-7b-instruct-v0.1
+ /accounts/:id/ai/run/@cf/openai/whisper
+ /accounts/:id/ai/run/@cf/meta/m2m100-1.2b
+ /accounts/:id/ai/run/@cf/huggingface/distilbert-sst-2-int8
+ /accounts/:id/ai/run/@cf/microsoft/resnet-50
+ /accounts/:id/ai/run/@cf/stabilityai/stable-diffusion-xl-base-1.0
+ /accounts/:id/ai/run/@cf/baai/bge-base-en-v1.5
+ /accounts/:id/ai/run/@cf/baai/bge-large-en-v1.5
+ /accounts/:id/ai/run/@cf/baai/bge-small-en-v1.5
+
+$
+```
+
+Along with a version of the library above `2.14.1`.
+
## Implemented API calls
The **--dump** argument to cli4 will produce a list of all the call implemented within the library.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/cli4/cli4.py new/cloudflare-2.14.2/cli4/cli4.py
--- old/cloudflare-2.12.4/cli4/cli4.py 2023-09-19 18:52:10.000000000 +0200
+++ new/cloudflare-2.14.2/cli4/cli4.py 2023-11-25 21:55:10.000000000 +0100
@@ -320,9 +320,11 @@
if len(results) == 1:
results = results[0]
- if isinstance(results, str):
+ if isinstance(results, str) or isinstance(results, (bytes, bytearray)):
# if the results are a simple string, then it should be dumped directly
# this is only used for /zones/:id/dns_records/export presently
+ # or
+ # output is image or audio or video or something like that so we dump directly
pass
else:
# anything more complex (dict, list, etc) should be dumped as JSON/YAML
@@ -350,14 +352,18 @@
pass
return
else:
- # Internal error
- pass
+ # None of the above, so pass thru results except something in byte form
+ if not isinstance(results, (bytes, bytearray)):
+ results = str(results)
if results:
try:
- sys.stdout.write(results)
- if not results.endswith('\n'):
- sys.stdout.write('\n')
+ if isinstance(results, (bytes, bytearray)):
+ sys.stdout.buffer.write(results)
+ else:
+ sys.stdout.write(results)
+ if not results.endswith('\n'):
+ sys.stdout.write('\n')
except (BrokenPipeError, IOError):
pass
@@ -375,9 +381,10 @@
method = 'GET'
usage = ('usage: cli4 '
- + '[-V|--version] [-h|--help] [-v|--verbose] [-q|--quiet] '
+ + '[-V|--version] [-h|--help] [-v|--verbose] '
+ '[-e|--examples] '
- + '[-j|--json] [-y|--yaml] [-n|ndjson] '
+ + '[-q|--quiet] '
+ + '[-j|--json] [-y|--yaml] [-n|--ndjson] [-i|--image] '
+ '[-r|--raw] '
+ '[-d|--dump] '
+ '[-A|--openapi url] '
@@ -389,12 +396,15 @@
try:
opts, args = getopt.getopt(args,
- 'VhvqejyrdA:bp:GPOUD',
+ 'VhveqjynirdA:bp:GPOUD',
[
- 'version',
- 'help', 'verbose', 'quiet', 'examples', 'json', 'yaml', 'ndjson',
+ 'version', 'help', 'verbose',
+ 'examples',
+ 'quiet',
+ 'json', 'yaml', 'ndjson', 'image',
'raw',
- 'dump', 'openapi=',
+ 'dump',
+ 'openapi=',
'binary',
'profile=',
'get', 'patch', 'post', 'put', 'delete'
@@ -424,6 +434,8 @@
if not my_jsonlines.available():
sys.exit('cli4: install jsonlines support')
output = 'ndjson'
+ elif opt in ('-i', '--image'):
+ output = 'image'
elif opt in ('-r', '--raw'):
raw = True
elif opt in ('-p', '--profile'):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/cloudflare.egg-info/PKG-INFO new/cloudflare-2.14.2/cloudflare.egg-info/PKG-INFO
--- old/cloudflare-2.12.4/cloudflare.egg-info/PKG-INFO 2023-09-22 03:47:10.000000000 +0200
+++ new/cloudflare-2.14.2/cloudflare.egg-info/PKG-INFO 2023-11-26 05:05:51.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: cloudflare
-Version: 2.12.4
+Version: 2.14.2
Summary: Python wrapper for the Cloudflare v4 API
Home-page: https://github.com/cloudflare/python-cloudflare
Author: Martin J. Levy
@@ -481,7 +481,7 @@
### Exception examples
-Here's examples using the CLI command cli4 of the responses passed back in exceptions.
+Here's examples using the CLI command `cli4` of the responses passed back in exceptions.
First a simple get with a clean (non-error) response.
@@ -551,16 +551,16 @@
$
```
-It will show up if you are running on an older system. For example, this is the results from running on Win7):
+It will show up if you are running on an older system. For example, this is the results from running on Win7:
```bash
-U:\Users\█████>cli4 -e
+U:\Users\Bobby>cli4 -e
Module "importlib_resources" missing - please "pip install importlib_resources" as your Python version is lower than 3.9
-U:\Users\█████>python -V
+U:\Users\Bobby>python -V
Python 3.8.3
-U:\Users\█████>
+U:\Users\Bobby>
```
Upgrading from an older version of Python is always recommended. Upgrading from Win7 is by-default even more important!
@@ -622,12 +622,23 @@
## CLI
-All API calls can be called from the command line.
-The command will convert domain names prefixed with a colon (`:`) into zone_identifiers: e.g. to view `example.com` you must use `cli4 /zones/:example.com` (the zone ID cannot be used).
-
-```bash
-$ cli4 [-V|--version] [-h|--help] [-v|--verbose] [-q|--quiet] [-j|--json] [-y|--yaml] [-n|ndjson] [-r|--raw] [-d|--dump] [-A|--openapi url] [-b|--binary] [-p|--profile profile-name] [--get|--patch|--post|--put|--delete] [item=value|item=@filename|@filename ...] /command ...
-
+All API calls can be called from the command line via the `cli4` command.
+Additionally, the `cli4` command will convert domain name or account name prefixed with a colon (`:`) into the correct identifier.
+e.g. to view `example.com` you can use `cli4 /zones/:example.com`.
+You can pass the zone identifier (or account identifier or any identifier) with a colon followed by the identifier as a hex number 32 characters long.
+
+```bash
+$ cli4 [-V|--version] [-h|--help] [-v|--verbose] \
+ [-e|--examples] \
+ [-q|--quiet] \
+ [-j|--json] [-y|--yaml] [-n|--ndjson] [-i|--image] \
+ [-r|--raw] \
+ [-d|--dump] \
+ [-A|--openapi url] \
+ [-b|--binary] \
+ [-p|--profile profile-name] \
+ [--get|--patch|--post|--put|--delete] \
+ [item=value|item=@filename|@filename ...] /command ...
```
### CLI parameters for POST/PUT/PATCH
@@ -663,7 +674,13 @@
### CLI output
-The output from the CLI command is in JSON or YAML format (and human readable). This is controled by the **--yaml** or **--json** flags (JSON is the default).
+The default output from the CLI command is in JSON.
+It can also output YAML format (i.e. human readable).
+This is controled by the `--yaml` or `--json` flags (JSON is the default).
+There is also a `--ndjson` flag for use with line based JSON data - this is mainly used for log data.
+
+Additonally the output can be plain text or binary image format depending on the results from the API call (some calls results in non JSON results).
+The `--image` flag will return the data in the same format as the API's results.
### Simple CLI examples
@@ -1266,6 +1283,63 @@
For more information on how to use GraphQL at Cloudflare, refer to the [Cloudflare GraphQL Analytics API](https://developers.cloudflare.com/analytics/graphql-api).
It contains a full overview of Cloudflare's GraphQL features and keywords.
+## Cloudflare AI
+
+See https://blog.cloudflare.com/workers-ai-update-stable-diffusion-code-llama-w… for the introduction,
+along with https://developers.cloudflare.com/workers-ai/models/ for the nitty gritty details.
+
+There are two examples for AI calls included with the code.
+
+```bash
+$ python examples/example_ai_images.py A happy llama running through an orange cloud > /tmp/image.png
+$
+$ file /tmp/image.png
+/tmp/image.png: PNG image data, 1024 x 1024, 8-bit/color RGB, non-interlaced
+$
+```
+
+```bash
+$ python examples/example_ai_translate.py I\'ll have an order of the moule frites
+Je vais avoir une commande des frites de moule
+$
+```
+
+This is presently work-in-progress because of the non-Python calling method. The syntax could change in the future.
+The examples will be updated.
+
+They can also be called via `cli4`.
+
+```bash
+$ cli4 --image --post text="I'll have an order of the moule frites" source_lang=english target_lang=french /accounts/:AccountID/ai/run/@cf/meta/m2m100-1.2b
+{'translated_text': 'Je vais avoir une commande des frites de moule'}
+$
+```
+
+Presently you will need the following in your `cloudflare.cfg` file.
+
+```bash
+$ cat ~/.cloudflare/cloudflare.cfg
+[CloudFlare]
+global_request_timeout = 120
+max_request_retries = 1
+extras =
+ /accounts/:id/ai/run/@cf/meta/llama-2-7b-chat-fp16
+ /accounts/:id/ai/run/@cf/meta/llama-2-7b-chat-int8
+ /accounts/:id/ai/run/@cf/mistral/mistral-7b-instruct-v0.1
+ /accounts/:id/ai/run/@cf/openai/whisper
+ /accounts/:id/ai/run/@cf/meta/m2m100-1.2b
+ /accounts/:id/ai/run/@cf/huggingface/distilbert-sst-2-int8
+ /accounts/:id/ai/run/@cf/microsoft/resnet-50
+ /accounts/:id/ai/run/@cf/stabilityai/stable-diffusion-xl-base-1.0
+ /accounts/:id/ai/run/@cf/baai/bge-base-en-v1.5
+ /accounts/:id/ai/run/@cf/baai/bge-large-en-v1.5
+ /accounts/:id/ai/run/@cf/baai/bge-small-en-v1.5
+
+$
+```
+
+Along with a version of the library above `2.14.1`.
+
## Implemented API calls
The **--dump** argument to cli4 will produce a list of all the call implemented within the library.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/cloudflare.egg-info/SOURCES.txt new/cloudflare-2.14.2/cloudflare.egg-info/SOURCES.txt
--- old/cloudflare-2.12.4/cloudflare.egg-info/SOURCES.txt 2023-09-22 03:47:10.000000000 +0200
+++ new/cloudflare-2.14.2/cloudflare.egg-info/SOURCES.txt 2023-11-26 05:05:51.000000000 +0100
@@ -31,6 +31,8 @@
cloudflare.egg-info/top_level.txt
examples/__init__.py
examples/example_account_rules_lists_items.py
+examples/example_ai_images.py
+examples/example_ai_translate.py
examples/example_always_use_https.py
examples/example_are_zones_ipv6.py
examples/example_are_zones_ipv6_simple.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/examples/example_ai_images.py new/cloudflare-2.14.2/examples/example_ai_images.py
--- old/cloudflare-2.12.4/examples/example_ai_images.py 1970-01-01 01:00:00.000000000 +0100
+++ new/cloudflare-2.14.2/examples/example_ai_images.py 2023-11-26 04:41:20.000000000 +0100
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import CloudFlare
+
+def find_call(cf, verbs):
+ # So we walk over the @ via a getattr() call.
+ # We also have to deal with a . in a verb - that does not work in Python. So sad.
+ # Also, the - is actually an _ in this Python library.
+ # This is not normally needed for other calls
+ m = cf
+ for verb in verbs.split('/'):
+ m = getattr(m, verb)
+ return m
+
+def doit(account_name, prompt_text):
+
+ # Or place these in your cloudflare.cfg file
+ os.environ['CLOUDFLARE_API_EXTRAS'] = '/accounts/:id/ai/run/@cf/stabilityai/stable-diffusion-xl-base-1.0'
+
+ # We set the timeout because these AI calls take longer than normal API calls
+ cf = CloudFlare.CloudFlare(global_request_timeout=120)
+
+ try:
+ if account_name == None or account_name == '':
+ params = {'per_page': 1}
+ else:
+ params = {'name': account_name, 'per_page': 1}
+ accounts = cf.accounts.get(params=params)
+ except CloudFlare.exceptions.CloudFlareAPIError as e:
+ exit('/accounts %d %s - api call failed' % (e, e))
+
+ try:
+ account_id = accounts[0]['id']
+ except IndexError:
+ exit('%s: account name not found' % (account_name))
+
+ image_create_data = {
+ 'prompt': prompt_text,
+ }
+
+ try:
+ # This should be easy to call; however, the @ will not work in Python (or many languages)
+ # r = cf.accounts.ai.run.(a)cf.stabilityai.stable-diffusion-xl-base-1.0(account_id, data=image_create_data)
+ # We find the endpoint via a quick string search
+ r = find_call(cf, 'accounts/ai/run/(a)cf/stabilityai/stable_diffusion_xl_base_1.0').post(account_id, data=image_create_data)
+ except CloudFlare.exceptions.CloudFlareAPIError as e:
+ exit('/ai.run %d %s - api call failed' % (e, e))
+
+ sys.stdout.buffer.write(r)
+
+def main():
+ if sys.argv[1] == '-a':
+ del sys.argv[1]
+ account_name = sys.argv[1]
+ del sys.argv[1]
+ else:
+ account_name = None
+ if len(sys.argv) > 1:
+ prompt_text = ' '.join(sys.argv[1:])
+ else:
+ prompt_text = "A happy llama running through an orange cloud"
+ doit(account_name, prompt_text)
+
+if __name__ == '__main__':
+ main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/examples/example_ai_translate.py new/cloudflare-2.14.2/examples/example_ai_translate.py
--- old/cloudflare-2.12.4/examples/example_ai_translate.py 1970-01-01 01:00:00.000000000 +0100
+++ new/cloudflare-2.14.2/examples/example_ai_translate.py 2023-11-26 04:41:35.000000000 +0100
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import CloudFlare
+
+def find_call(cf, verbs):
+ # So we walk over the @ via a getattr() call.
+ # We also have to deal with a . in a verb - that does not work in Python. So sad.
+ # Also, the - is actually an _ in this Python library.
+ # This is not normally needed for other calls
+ m = cf
+ for verb in verbs.split('/'):
+ m = getattr(m, verb)
+ return m
+
+def doit(account_name, english_text):
+
+ # Or place these in your cloudflare.cfg file
+ os.environ['CLOUDFLARE_API_EXTRAS'] = '/accounts/:id/ai/run/@cf/meta/m2m100-1.2b'
+
+ # We set the timeout because these AI calls take longer than normal API calls
+ cf = CloudFlare.CloudFlare(global_request_timeout=120)
+
+ try:
+ if account_name == None or account_name == '':
+ params = {'per_page': 1}
+ else:
+ params = {'name': account_name, 'per_page': 1}
+ accounts = cf.accounts.get(params=params)
+ except CloudFlare.exceptions.CloudFlareAPIError as e:
+ exit('/accounts %d %s - api call failed' % (e, e))
+
+ try:
+ account_id = accounts[0]['id']
+ except IndexError:
+ exit('%s: account name not found' % (account_name))
+
+ translate_data = {
+ 'text': english_text,
+ 'source_lang': 'english',
+ 'target_lang': 'french',
+ }
+
+ try:
+ # This should be easy to call; however, the @ will not work in Python (or many languages)
+ # r = cf.accounts.ai.run.(a)cf.meta.m2m100-1.2b(account_id, data=translate_data)
+ # We find the endpoint via a quick string search
+ r = find_call(cf, 'accounts/ai/run/(a)cf/meta/m2m100_1.2b').post(account_id, data=translate_data)
+ except CloudFlare.exceptions.CloudFlareAPIError as e:
+ exit('/ai.run %d %s - api call failed' % (e, e))
+
+ print(r['translated_text'])
+
+def main():
+ if sys.argv[1] == '-a':
+ del sys.argv[1]
+ account_name = sys.argv[1]
+ del sys.argv[1]
+ else:
+ account_name = None
+ if len(sys.argv) > 1:
+ english_text = ' '.join(sys.argv[1:])
+ else:
+ english_text = "I'll have an order of the moule frites"
+ doit(account_name, english_text)
+
+if __name__ == '__main__':
+ main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cloudflare-2.12.4/setup.py new/cloudflare-2.14.2/setup.py
--- old/cloudflare-2.12.4/setup.py 2022-10-02 21:47:42.000000000 +0200
+++ new/cloudflare-2.14.2/setup.py 2023-11-25 19:20:54.000000000 +0100
@@ -9,7 +9,7 @@
def main():
"""Cloudflare API code - setup.py file"""
- with open('README.md') as read_me:
+ with open('README.md', encoding="utf-8") as read_me:
long_description = read_me.read()
with open('CloudFlare/__init__.py', 'r') as f:
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package libphdi for openSUSE:Factory checked in at 2023-11-30 22:00:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libphdi (Old)
and /work/SRC/openSUSE:Factory/.libphdi.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libphdi"
Thu Nov 30 22:00:35 2023 rev:12 rq:1129779 version:20231129
Changes:
--------
--- /work/SRC/openSUSE:Factory/libphdi/libphdi.changes 2023-08-09 17:26:02.765676432 +0200
+++ /work/SRC/openSUSE:Factory/.libphdi.new.25432/libphdi.changes 2023-11-30 22:01:26.117311842 +0100
@@ -1,0 +2,6 @@
+Wed Nov 29 11:01:01 UTC 2023 - Jan Engelhardt <jengelh(a)inai.de>
+
+- Update to release 20231129
+ * Improved Python Unicode handling
+
+-------------------------------------------------------------------
Old:
----
libphdi-experimental-20221025.tar.gz
libphdi-experimental-20221025.tar.gz.asc
New:
----
libphdi-experimental-20231129.tar.gz
libphdi-experimental-20231129.tar.gz.asc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libphdi.spec ++++++
--- /var/tmp/diff_new_pack.Cv3phY/_old 2023-11-30 22:01:26.685332767 +0100
+++ /var/tmp/diff_new_pack.Cv3phY/_new 2023-11-30 22:01:26.685332767 +0100
@@ -15,11 +15,12 @@
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
+
%{?sle15_python_module_pythons}
Name: libphdi
%define lname libphdi1
-Version: 20221025
+Version: 20231129
Release: 0
Summary: Library and tools to access the Parallels Hard Disk images
License: LGPL-3.0-or-later
@@ -34,20 +35,20 @@
BuildRequires: python-rpm-macros
BuildRequires: pkgconfig(fuse) >= 2.6
BuildRequires: pkgconfig(libbfio) >= 20221025
-BuildRequires: pkgconfig(libcdata) >= 20220115
+BuildRequires: pkgconfig(libcdata) >= 20230108
BuildRequires: pkgconfig(libcdirectory) >= 20220105
BuildRequires: pkgconfig(libcerror) >= 20220101
BuildRequires: pkgconfig(libcfile) >= 20220106
-BuildRequires: pkgconfig(libclocale) >= 20220107
+BuildRequires: pkgconfig(libclocale) >= 20221218
BuildRequires: pkgconfig(libcnotify) >= 20220108
BuildRequires: pkgconfig(libcpath) >= 20220108
BuildRequires: pkgconfig(libcsplit) >= 20220109
BuildRequires: pkgconfig(libcthreads) >= 20220102
-BuildRequires: pkgconfig(libfcache) >= 20220110
-BuildRequires: pkgconfig(libfdata) >= 20220111
+BuildRequires: pkgconfig(libfcache) >= 20230115
+BuildRequires: pkgconfig(libfdata) >= 20230319
BuildRequires: pkgconfig(libfguid) >= 20220113
BuildRequires: pkgconfig(libfvalue) >= 20220120
-BuildRequires: pkgconfig(libuna) >= 20220611
+BuildRequires: pkgconfig(libuna) >= 20230710
%python_subpackages
# Various notes: https://en.opensuse.org/libyal
++++++ libphdi-experimental-20221025.tar.gz -> libphdi-experimental-20231129.tar.gz ++++++
++++ 26067 lines of diff (skipped)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package libhmac for openSUSE:Factory checked in at 2023-11-30 22:00:31
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libhmac (Old)
and /work/SRC/openSUSE:Factory/.libhmac.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libhmac"
Thu Nov 30 22:00:31 2023 rev:15 rq:1129842 version:20231127
Changes:
--------
--- /work/SRC/openSUSE:Factory/libhmac/libhmac.changes 2023-04-08 17:39:41.294261032 +0200
+++ /work/SRC/openSUSE:Factory/.libhmac.new.25432/libhmac.changes 2023-11-30 22:01:23.525216353 +0100
@@ -1,0 +2,6 @@
+Mon Nov 27 09:40:31 UTC 2023 - Jan Engelhardt <jengelh(a)inai.de>
+
+- Update to release 20231127
+ * Build system updates only
+
+-------------------------------------------------------------------
Old:
----
libhmac-alpha-20230407.tar.gz
libhmac-alpha-20230407.tar.gz.asc
New:
----
libhmac-alpha-20231127.tar.gz
libhmac-alpha-20231127.tar.gz.asc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libhmac.spec ++++++
--- /var/tmp/diff_new_pack.qCU2HN/_old 2023-11-30 22:01:24.109237868 +0100
+++ /var/tmp/diff_new_pack.qCU2HN/_new 2023-11-30 22:01:24.113238015 +0100
@@ -18,7 +18,7 @@
Name: libhmac
%define lname libhmac1
-Version: 20230407
+Version: 20231127
Release: 0
Summary: Library to support various HMACs
License: LGPL-3.0-or-later
@@ -36,7 +36,7 @@
BuildRequires: pkgconfig(libcpath) >= 20220108
BuildRequires: pkgconfig(libcsplit) >= 20220109
BuildRequires: pkgconfig(libcthreads) >= 20220102
-BuildRequires: pkgconfig(libuna) >= 20220611
+BuildRequires: pkgconfig(libuna) >= 20230710
BuildRequires: pkgconfig(openssl) >= 1.0
# Various notes: https://en.opensuse.org/libyal
++++++ libhmac-alpha-20230407.tar.gz -> libhmac-alpha-20231127.tar.gz ++++++
++++ 15717 lines of diff (skipped)
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package gnome-maps for openSUSE:Factory checked in at 2023-11-30 22:00:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gnome-maps (Old)
and /work/SRC/openSUSE:Factory/.gnome-maps.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gnome-maps"
Thu Nov 30 22:00:30 2023 rev:86 rq:1130014 version:45.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/gnome-maps/gnome-maps.changes 2023-10-24 20:07:14.726099371 +0200
+++ /work/SRC/openSUSE:Factory/.gnome-maps.new.25432/gnome-maps.changes 2023-11-30 22:01:22.429175977 +0100
@@ -97 +97 @@
-- Update to version 44.0:
+- Update to version 44.0 (boo#1216184, boo#1217240):
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package qbittorrent for openSUSE:Factory checked in at 2023-11-30 22:00:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/qbittorrent (Old)
and /work/SRC/openSUSE:Factory/.qbittorrent.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qbittorrent"
Thu Nov 30 22:00:29 2023 rev:115 rq:1129923 version:4.6.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/qbittorrent/qbittorrent.changes 2023-11-28 22:20:09.599456376 +0100
+++ /work/SRC/openSUSE:Factory/.qbittorrent.new.25432/qbittorrent.changes 2023-11-30 22:01:19.421065163 +0100
@@ -12,0 +13,2 @@
+- Also fixes boo#1217677 (CVE-2023-30801, upstream reference
+ gh#qbittorrent/qBittorrent#19738)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
1
0
Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package libfvde for openSUSE:Factory checked in at 2023-11-30 22:00:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libfvde (Old)
and /work/SRC/openSUSE:Factory/.libfvde.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libfvde"
Thu Nov 30 22:00:28 2023 rev:15 rq:1129477 version:20231128
Changes:
--------
--- /work/SRC/openSUSE:Factory/libfvde/libfvde.changes 2023-08-09 17:25:22.053422964 +0200
+++ /work/SRC/openSUSE:Factory/.libfvde.new.25432/libfvde.changes 2023-11-30 22:01:17.244984999 +0100
@@ -1,0 +2,6 @@
+Tue Nov 28 09:17:02 UTC 2023 - Jan Engelhardt <jengelh(a)inai.de>
+
+- Update to release 2023118
+ * Improved Python Unicode handling
+
+-------------------------------------------------------------------
Old:
----
libfvde-experimental-20220915.tar.gz
libfvde-experimental-20220915.tar.gz.asc
New:
----
libfvde-experimental-20231128.tar.gz
libfvde-experimental-20231128.tar.gz.asc
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libfvde.spec ++++++
--- /var/tmp/diff_new_pack.PAVJ8t/_old 2023-11-30 22:01:17.921009903 +0100
+++ /var/tmp/diff_new_pack.PAVJ8t/_new 2023-11-30 22:01:17.925010051 +0100
@@ -15,11 +15,12 @@
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
+
%{?sle15_python_module_pythons}
%define lname libfvde1
Name: libfvde
-Version: 20220915
+Version: 20231128
Release: 0
Summary: Library to access the File Vault Drive Encryption format
License: GFDL-1.3-or-later AND LGPL-3.0-or-later
@@ -34,22 +35,22 @@
BuildRequires: python-rpm-macros
BuildRequires: pkgconfig(fuse)
BuildRequires: pkgconfig(libbfio) >= 20220120
-BuildRequires: pkgconfig(libcaes) >= 20220529
-BuildRequires: pkgconfig(libcdata) >= 20220115
+BuildRequires: pkgconfig(libcaes) >= 20231120
+BuildRequires: pkgconfig(libcdata) >= 20230108
BuildRequires: pkgconfig(libcerror) >= 20220101
BuildRequires: pkgconfig(libcfile) >= 20220106
-BuildRequires: pkgconfig(libclocale) >= 20220107
+BuildRequires: pkgconfig(libclocale) >= 20221218
BuildRequires: pkgconfig(libcnotify) >= 20220108
BuildRequires: pkgconfig(libcpath) >= 20220108
BuildRequires: pkgconfig(libcsplit) >= 20220109
BuildRequires: pkgconfig(libcthreads) >= 20220102
-BuildRequires: pkgconfig(libfcache) >= 20220110
-BuildRequires: pkgconfig(libfdata) >= 20220111
+BuildRequires: pkgconfig(libfcache) >= 20230115
+BuildRequires: pkgconfig(libfdata) >= 20230319
BuildRequires: pkgconfig(libfguid) >= 20220113
-BuildRequires: pkgconfig(libfplist) >= 20220116
+BuildRequires: pkgconfig(libfplist) >= 20231023
BuildRequires: pkgconfig(libfvalue) >= 20220120
-BuildRequires: pkgconfig(libhmac) >= 20220425
-BuildRequires: pkgconfig(libuna) >= 20220611
+BuildRequires: pkgconfig(libhmac) >= 20231127
+BuildRequires: pkgconfig(libuna) >= 20230710
BuildRequires: pkgconfig(openssl)
BuildRequires: pkgconfig(python3)
BuildRequires: pkgconfig(zlib)
++++++ libfvde-experimental-20220915.tar.gz -> libfvde-experimental-20231128.tar.gz ++++++
++++ 46518 lines of diff (skipped)
1
0