Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update python and django versions in CI #37

Merged
merged 10 commits into from Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 28 additions & 23 deletions .github/workflows/actions.yml
@@ -1,45 +1,39 @@
name: Run Tests

on: [ push, pull_request ]
on: [ pull_request ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
django_version:
- '2.2'
- '3.2'
- '4.0'
- '4.2'
- '5.0'
python-version:
- 3.6
- 3.7
- 3.8
- 3.9
- "3.10"
- "3.11"
- "3.12"
exclude:
- django_version: '2.2'
python-version: '3.10'

- django_version: '4.0'
python-version: '3.6'

- django_version: '4.0'
python-version: '3.7'

- django_version: "5.0"
python-version: 3.8
- django_version: "5.0"
python-version: 3.9
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Cache pip
uses: actions/cache@v2
uses: actions/cache@v4
with:
# This path is specific to Ubuntu
path: ~/.cache/pip
Expand All @@ -49,7 +43,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -e .
pip install -U flake8 coveralls argparse
pip install -U flake8 coverage
pip install -U Django~=${{ matrix.django_version }}

- name: Lint with flake8
Expand All @@ -60,7 +54,18 @@ jobs:
python -W error::DeprecationWarning -W error::PendingDeprecationWarning \
-m coverage run ./runtests.py

- name: Coverage
if: ${{ success() }}
run: |
coveralls --service=github
- name: Coveralls Parallel
uses: coverallsapp/github-action@v2
with:
flag-name: run-${{ join(matrix.*, '-') }}
parallel: true

finish:
needs: test
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Coveralls Finished
uses: coverallsapp/github-action@v2
with:
parallel-finished: true
20 changes: 10 additions & 10 deletions README.rst
Expand Up @@ -35,7 +35,7 @@ Usage

* Add ``jsignature`` to your ``INSTALLED_APPS``:

::
.. code-block:: python

# settings.py
INSTALLED_APPS = (
Expand All @@ -45,7 +45,7 @@ Usage

* Use provided model field (for easy storage):

::
.. code-block:: python

# models.py
from django.db import models
Expand All @@ -56,7 +56,7 @@ Usage

* In your form template

::
.. code-block:: html+django

{{ form.media }}
<form action="" method="post">
Expand All @@ -67,7 +67,7 @@ Usage

* Render image from db value in your display template:

::
.. code-block:: html+django

{# yourtemplate.html #}
{% load jsignature_filters %}
Expand All @@ -93,15 +93,15 @@ JSignature plugin options are available in python:

* Globally, in your settings:

::
.. code-block:: python

# settings.py
JSIGNATURE_WIDTH = 500
JSIGNATURE_HEIGHT = 200

* Specifically, in your form:

::
.. code-block:: python

# forms.py
from jsignature.forms import JSignatureField
Expand All @@ -127,7 +127,7 @@ In your models
If you want to store signatures easily, a provided mixin gives a ``signature``
and a ``signature_date`` that update themselves:

::
.. code-block:: python

from django.db import models
from jsignature.mixins import JSignatureFieldsMixin
Expand All @@ -142,7 +142,7 @@ In your forms

* If you need more precise handling of the form field, you can use it directly:

::
.. code-block:: python

# forms.py
from django import forms
Expand All @@ -154,7 +154,7 @@ In your forms

* And upon saving, have direct access to the image with ``draw_signature()``

::
.. code-block:: python

# views.py
from jsignature.utils import draw_signature
Expand All @@ -177,7 +177,7 @@ Example project

If you want to have a demo of this package, just use the example project:

::
.. code-block:: shell

git clone https://github.com/fle/django-jsignature.git
cd django-jsignature
Expand Down
9 changes: 1 addition & 8 deletions jsignature/fields.py
Expand Up @@ -12,13 +12,6 @@
JSIGNATURE_EMPTY_VALUES,
)

try:
from django.utils import six

string_types = six.string_types
except ImportError:
string_types = str


class JSignatureField(models.Field):
"""
Expand Down Expand Up @@ -46,7 +39,7 @@ def to_python(self, value):
def get_prep_value(self, value):
if value in JSIGNATURE_EMPTY_VALUES:
return None
elif isinstance(value, string_types):
elif isinstance(value, str):
return value
elif isinstance(value, list):
return json.dumps(value)
Expand Down
4 changes: 2 additions & 2 deletions jsignature/mixins.py
Expand Up @@ -3,8 +3,8 @@
with jSignature jQuery plugin
"""
import json
from datetime import datetime
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from .fields import JSignatureField

Expand All @@ -30,7 +30,7 @@ def save(self, *args, **kwargs):

if self.signature:
if is_new or json.dumps(self.signature) != original.signature:
self.signature_date = datetime.now()
self.signature_date = timezone.now()
else:
self.signature_date = None

Expand Down
9 changes: 1 addition & 8 deletions jsignature/widgets.py
Expand Up @@ -17,13 +17,6 @@
JSIGNATURE_EMPTY_VALUES = validators.EMPTY_VALUES + ('[]', )


try:
from django.utils import six
string_types = six.string_types
except ImportError:
string_types = str


class JSignatureWidget(forms.HiddenInput):
"""
A widget handling a signature capture field with with jSignature
Expand Down Expand Up @@ -73,7 +66,7 @@ def prep_value(self, value):
""" Prepare value before effectively render widget """
if value in JSIGNATURE_EMPTY_VALUES:
return "[]"
elif isinstance(value, string_types):
elif isinstance(value, str):
return value
elif isinstance(value, list):
return json.dumps(value)
Expand Down
16 changes: 7 additions & 9 deletions setup.py
Expand Up @@ -14,7 +14,7 @@
long_description=open(os.path.join(here, 'README.rst')).read() + '\n\n' +
open(os.path.join(here, 'CHANGES')).read(),
license='LPGL, see LICENSE file.',
install_requires=['Django>=1.11', 'pillow', 'pyquery>=1.4.2'],
install_requires=['Django>=4.2', 'pillow<9.1.0', 'pyquery>=1.4.2'],
packages=find_packages(exclude=['example_project*', 'tests']),
include_package_data=True,
zip_safe=False,
Expand All @@ -25,17 +25,15 @@
'Intended Audience :: Developers',
'Environment :: Web Environment',
'Framework :: Django',
'Framework :: Django :: 1.11',
'Framework :: Django :: 2.2',
'Framework :: Django :: 3.0',
'Framework :: Django :: 4.2',
'Framework :: Django :: 5.0',
'Development Status :: 5 - Production/Stable',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
],
)
2 changes: 2 additions & 0 deletions tests/settings.py
Expand Up @@ -34,3 +34,5 @@
'APP_DIRS': True,
},
]

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
11 changes: 7 additions & 4 deletions tests/test_mixins.py
@@ -1,5 +1,6 @@
from datetime import date
from datetime import date, datetime
from django.test import TestCase
from django.utils.timezone import make_aware

from .models import JSignatureTestModel

Expand All @@ -18,7 +19,7 @@ def test_save_no_change(self):
signature_value = [{"x": [1, 2], "y": [3, 4]}]
i = JSignatureTestModel(signature=signature_value)
i.save()
i.signature_date = date(2013, 1, 1)
i.signature_date = make_aware(datetime(2013, 1, 1))
i.save()
i = JSignatureTestModel.objects.get(pk=i.pk)
self.assertEqual(date(2013, 1, 1), i.signature_date.date())
Expand All @@ -27,8 +28,10 @@ def test_save_change(self):
# If signature changes, signature date must be updated too
signature_value = [{"x": [1, 2], "y": [3, 4]}]
new_signature_value = [{"x": [5, 6], "y": [7, 8]}]
i = JSignatureTestModel(signature=signature_value,
signature_date=date(2013, 1, 1))
i = JSignatureTestModel(
signature=signature_value,
signature_date=make_aware(datetime(2013, 1, 1)),
)
i.save()
i.signature_date = date(2013, 1, 1)
i.signature = new_signature_value
Expand Down
5 changes: 3 additions & 2 deletions tests/test_utils.py
@@ -1,6 +1,5 @@
import json
import os
import imghdr
from PIL import Image
from django.test import SimpleTestCase

Expand Down Expand Up @@ -28,7 +27,9 @@ def test_inputs_good_str_value(self):
def test_outputs_as_file(self):
output = draw_signature(DUMMY_VALUE, as_file=True)
self.assertTrue(os.path.isfile(output))
self.assertIsNotNone(imghdr.what(output))
# Load image with pillow and check PNG
im = Image.open(output)
self.assertIsNone(im.verify())

def test_outputs_as_image(self):
output = draw_signature(DUMMY_VALUE)
Expand Down
21 changes: 9 additions & 12 deletions tox.ini
@@ -1,15 +1,12 @@
[tox]
envlist =
{py36,py37,py38,py39,py310}-django22,
{py36,py37,py38,py39,py310}-django32,
{py38,py39,py310}-django{40,master},
py310-djangomaster
{py38,py39,py310,py311,py312}-django42,
{py310,py311,py312}-django{50,master},

[testenv]
deps=
django22: Django>=2.2,<3.0
django32: Django>=3.2,<4.0
django40: Django>=4.0,<4.1
django42: Django>=4.2,<5.0
django50: Django>=5.0,<5.1
djangomaster: https://github.com/django/django/archive/main.tar.gz
-r requirements.txt
coverage
Expand All @@ -18,8 +15,8 @@ commands= coverage run ./runtests.py

[gh-actions]
python =
3.6: py36-django{22,32}
3.7: py37-django{22,32}
3.8: py38-django{22,32,40}
3.9: py39-django{22,32,40}
3.10: py310-django{22,32,40,master}
3.8: py38-django42
3.9: py39-django42
3.10: py310-django{42,50,master}
3.11: py311-django{42,50,master}
3.12: py312-django{42,50,master}