diff --git a/doc/development/setup.rst b/doc/development/setup.rst index d019846ff..a48be06c9 100644 --- a/doc/development/setup.rst +++ b/doc/development/setup.rst @@ -26,9 +26,11 @@ Your should install the following on your system: * ``libssl`` (Debian package: ``libssl-dev``) * ``libxml2`` (Debian package ``libxml2-dev``) * ``libxslt`` (Debian package ``libxslt1-dev``) -* ``libenchant1c2a`` (Debian package ``libenchant1c2a``) +* ``libenchant1c2a`` (Debian package ``libenchant1c2a`` or ``libenchant2-2``) * ``msgfmt`` (Debian package ``gettext``) +* ``freetype`` (Debian package ``libfreetype-dev``) * ``git`` +* for pillow: ``libjpeg`` (Debian Package ``libjpeg-dev``) Your local python environment ----------------------------- diff --git a/src/pretix/api/middleware.py b/src/pretix/api/middleware.py index fa77fba10..1179eac90 100644 --- a/src/pretix/api/middleware.py +++ b/src/pretix/api/middleware.py @@ -68,7 +68,7 @@ def __call__(self, request: HttpRequest): call.response_body = json.dumps(resp.data) else: call.response_body = repr(resp).encode() - call.response_headers = json.dumps(resp._headers) + call.response_headers = json.dumps(resp.headers._store) call.locked = None call.save(update_fields=['locked', 'response_code', 'response_headers', 'response_body']) diff --git a/src/pretix/base/i18n.py b/src/pretix/base/i18n.py index 99ba153b5..cb0be9732 100644 --- a/src/pretix/base/i18n.py +++ b/src/pretix/base/i18n.py @@ -73,10 +73,11 @@ def __str__(self): def get_babel_locale(): babel_locale = 'en' # Babel, and therefore django-phonenumberfield, do not support our custom locales such das de_Informal - if localedata.exists(translation.get_language()): - babel_locale = translation.get_language() - elif localedata.exists(translation.get_language()[:2]): - babel_locale = translation.get_language()[:2] + if translation.get_language(): + if localedata.exists(translation.get_language()): + babel_locale = translation.get_language() + elif localedata.exists(translation.get_language()[:2]): + babel_locale = translation.get_language()[:2] return babel_locale diff --git a/src/pretix/base/migrations/0102_auto_20181017_0024.py b/src/pretix/base/migrations/0102_auto_20181017_0024.py index 945ef0feb..cbab44764 100644 --- a/src/pretix/base/migrations/0102_auto_20181017_0024.py +++ b/src/pretix/base/migrations/0102_auto_20181017_0024.py @@ -1,8 +1,7 @@ # Generated by Django 2.1 on 2018-10-17 00:24 -import jsonfallback.fields from django.core.exceptions import ImproperlyConfigured -from django.db import migrations +from django.db import migrations, models from django_mysql.checks import mysql_connections from django_mysql.utils import connection_is_mariadb @@ -77,19 +76,19 @@ class Migration(migrations.Migration): migrations.AddField( model_name='cartposition', name='attendee_name_parts', - field=jsonfallback.fields.FallbackJSONField(null=False, default=dict), + field=models.JSONField(null=False, default=dict), preserve_default=False, ), migrations.AddField( model_name='orderposition', name='attendee_name_parts', - field=jsonfallback.fields.FallbackJSONField(null=False, default=dict), + field=models.JSONField(null=False, default=dict), preserve_default=False, ), migrations.AddField( model_name='invoiceaddress', name='name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), preserve_default=False, ), migrations.RunPython(set_attendee_name_parts, migrations.RunPython.noop) diff --git a/src/pretix/base/migrations/0103_auto_20181121_1224.py b/src/pretix/base/migrations/0103_auto_20181121_1224.py index 5c6b3b78e..de770832c 100644 --- a/src/pretix/base/migrations/0103_auto_20181121_1224.py +++ b/src/pretix/base/migrations/0103_auto_20181121_1224.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.1 on 2018-11-21 12:24 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0104_auto_20181114_1526.py b/src/pretix/base/migrations/0104_auto_20181114_1526.py index 31e1119b0..52241a19c 100644 --- a/src/pretix/base/migrations/0104_auto_20181114_1526.py +++ b/src/pretix/base/migrations/0104_auto_20181114_1526.py @@ -2,7 +2,6 @@ import django.db.models.deletion import django.db.models.manager -import jsonfallback.fields from django.db import migrations, models diff --git a/src/pretix/base/migrations/0105_auto_20190112_1512.py b/src/pretix/base/migrations/0105_auto_20190112_1512.py index aa5bb9010..79060a0ac 100644 --- a/src/pretix/base/migrations/0105_auto_20190112_1512.py +++ b/src/pretix/base/migrations/0105_auto_20190112_1512.py @@ -1,7 +1,6 @@ # Generated by Django 2.1 on 2019-01-12 15:12 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0107_auto_20190129_1337.py b/src/pretix/base/migrations/0107_auto_20190129_1337.py index 187fcc7f9..2ddd14660 100644 --- a/src/pretix/base/migrations/0107_auto_20190129_1337.py +++ b/src/pretix/base/migrations/0107_auto_20190129_1337.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.5 on 2019-01-29 13:37 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0108_auto_20190201_1527.py b/src/pretix/base/migrations/0108_auto_20190201_1527.py index 30dd42e7d..8edbd38f5 100644 --- a/src/pretix/base/migrations/0108_auto_20190201_1527.py +++ b/src/pretix/base/migrations/0108_auto_20190201_1527.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.5 on 2019-02-01 15:27 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0108_auto_20190201_1527_squashed_0141_seat_sorting_rank.py b/src/pretix/base/migrations/0108_auto_20190201_1527_squashed_0141_seat_sorting_rank.py index 280f9e1e0..123f0001f 100644 --- a/src/pretix/base/migrations/0108_auto_20190201_1527_squashed_0141_seat_sorting_rank.py +++ b/src/pretix/base/migrations/0108_auto_20190201_1527_squashed_0141_seat_sorting_rank.py @@ -3,7 +3,6 @@ from decimal import Decimal import django.db.models.deletion -import jsonfallback.fields from django.conf import settings from django.core.cache import cache from django.db import migrations, models @@ -190,7 +189,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='cartposition', name='attendee_name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AlterField( model_name='cartposition', @@ -210,7 +209,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='invoiceaddress', name='name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AlterField( model_name='item', @@ -225,7 +224,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='orderposition', name='attendee_name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AlterField( model_name='orderposition', diff --git a/src/pretix/base/migrations/0109_auto_20190208_1432.py b/src/pretix/base/migrations/0109_auto_20190208_1432.py index c7a491115..b72a4c961 100644 --- a/src/pretix/base/migrations/0109_auto_20190208_1432.py +++ b/src/pretix/base/migrations/0109_auto_20190208_1432.py @@ -1,7 +1,6 @@ # Generated by Django 2.1 on 2019-02-08 14:32 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0110_auto_20190219_1245.py b/src/pretix/base/migrations/0110_auto_20190219_1245.py index 92da90819..76cfd55b7 100644 --- a/src/pretix/base/migrations/0110_auto_20190219_1245.py +++ b/src/pretix/base/migrations/0110_auto_20190219_1245.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.5 on 2019-02-19 12:45 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0111_auto_20190219_0949.py b/src/pretix/base/migrations/0111_auto_20190219_0949.py index 75bea99da..ad296f456 100644 --- a/src/pretix/base/migrations/0111_auto_20190219_0949.py +++ b/src/pretix/base/migrations/0111_auto_20190219_0949.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.5 on 2019-02-19 09:49 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0113_auto_20190312_0942.py b/src/pretix/base/migrations/0113_auto_20190312_0942.py index 308c69685..4c2f5320f 100644 --- a/src/pretix/base/migrations/0113_auto_20190312_0942.py +++ b/src/pretix/base/migrations/0113_auto_20190312_0942.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.5 on 2019-03-12 09:42 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0114_auto_20190316_1014.py b/src/pretix/base/migrations/0114_auto_20190316_1014.py index b74854a62..2d81043c9 100644 --- a/src/pretix/base/migrations/0114_auto_20190316_1014.py +++ b/src/pretix/base/migrations/0114_auto_20190316_1014.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.7 on 2019-03-16 10:14 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0115_auto_20190323_2238.py b/src/pretix/base/migrations/0115_auto_20190323_2238.py index 6559ab246..72820d062 100644 --- a/src/pretix/base/migrations/0115_auto_20190323_2238.py +++ b/src/pretix/base/migrations/0115_auto_20190323_2238.py @@ -3,7 +3,6 @@ from decimal import Decimal import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0116_auto_20190402_0722.py b/src/pretix/base/migrations/0116_auto_20190402_0722.py index 7d1c5d62a..fc88c0e06 100644 --- a/src/pretix/base/migrations/0116_auto_20190402_0722.py +++ b/src/pretix/base/migrations/0116_auto_20190402_0722.py @@ -1,7 +1,6 @@ # Generated by Django 2.1.5 on 2019-04-02 07:22 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0118_auto_20190423_0839.py b/src/pretix/base/migrations/0118_auto_20190423_0839.py index 94396b97b..839a16fa0 100644 --- a/src/pretix/base/migrations/0118_auto_20190423_0839.py +++ b/src/pretix/base/migrations/0118_auto_20190423_0839.py @@ -1,7 +1,6 @@ # Generated by Django 2.2 on 2019-04-23 08:39 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0119_auto_20190509_0654.py b/src/pretix/base/migrations/0119_auto_20190509_0654.py index e16ba93f1..04246fc8e 100644 --- a/src/pretix/base/migrations/0119_auto_20190509_0654.py +++ b/src/pretix/base/migrations/0119_auto_20190509_0654.py @@ -1,7 +1,6 @@ # Generated by Django 2.2 on 2019-05-09 06:54 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields diff --git a/src/pretix/base/migrations/0120_auto_20190509_0736.py b/src/pretix/base/migrations/0120_auto_20190509_0736.py index c0904e832..17ae129ac 100644 --- a/src/pretix/base/migrations/0120_auto_20190509_0736.py +++ b/src/pretix/base/migrations/0120_auto_20190509_0736.py @@ -1,7 +1,6 @@ # Generated by Django 2.2 on 2019-05-09 07:36 import django.db.models.deletion -import jsonfallback.fields from django.db import migrations, models import pretix.base.models.fields @@ -17,7 +16,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='cartposition', name='attendee_name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AlterField( model_name='cartposition', @@ -37,7 +36,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='invoiceaddress', name='name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AlterField( model_name='item', @@ -52,7 +51,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='orderposition', name='attendee_name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AlterField( model_name='orderposition', diff --git a/src/pretix/base/migrations/0152_auto_20200511_1504.py b/src/pretix/base/migrations/0152_auto_20200511_1504.py index ee514a291..36f2e171c 100644 --- a/src/pretix/base/migrations/0152_auto_20200511_1504.py +++ b/src/pretix/base/migrations/0152_auto_20200511_1504.py @@ -2,7 +2,6 @@ import django.db.models.deletion import django_countries.fields -import jsonfallback.fields from django.db import migrations, models import pretix.helpers.countries @@ -43,7 +42,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='checkinlist', name='rules', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AlterUniqueTogether( name='checkin', diff --git a/src/pretix/base/migrations/0177_auto_20210301_1510.py b/src/pretix/base/migrations/0177_auto_20210301_1510.py index 7a2795ed2..2ed389153 100644 --- a/src/pretix/base/migrations/0177_auto_20210301_1510.py +++ b/src/pretix/base/migrations/0177_auto_20210301_1510.py @@ -1,6 +1,5 @@ # Generated by Django 3.0.10 on 2021-03-01 15:10 -import jsonfallback.fields import phonenumber_field.modelfields from django.db import migrations, models @@ -20,7 +19,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='waitinglistentry', name='name_parts', - field=jsonfallback.fields.FallbackJSONField(default=dict), + field=models.JSONField(default=dict), ), migrations.AddField( model_name='waitinglistentry', diff --git a/src/pretix/base/models/checkin.py b/src/pretix/base/models/checkin.py index 46502a1df..a162a3c84 100644 --- a/src/pretix/base/models/checkin.py +++ b/src/pretix/base/models/checkin.py @@ -1,11 +1,10 @@ from django.conf import settings from django.core.exceptions import ValidationError from django.db import models -from django.db.models import Exists, F, Max, OuterRef, Q, Subquery +from django.db.models import Exists, F, Max, OuterRef, Q, Subquery, JSONField from django.utils.timezone import now from django.utils.translation import gettext_lazy as _, pgettext_lazy from django_scopes import ScopedManager, scopes_disabled -from jsonfallback.fields import FallbackJSONField from pretix.base.models import LoggedModel from pretix.base.models.fields import MultiStringField @@ -48,7 +47,7 @@ class CheckinList(LoggedModel): 'any of the selected sales channels. This option can be useful when tickets sold at the box office ' 'are not checked again before entry and should be considered validated directly upon purchase.') ) - rules = FallbackJSONField(default=dict, blank=True) + rules = JSONField(default=dict, blank=True) objects = ScopedManager(organizer='event__organizer') diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 509d4fce3..5de1fdc53 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -14,7 +14,7 @@ from django.conf import settings from django.db import models, transaction from django.db.models import ( - Case, Exists, F, Max, OuterRef, Q, Subquery, Sum, Value, When, + Case, Exists, F, Max, OuterRef, Q, Subquery, Sum, Value, When, JSONField, ) from django.db.models.functions import Coalesce, Greatest from django.db.models.signals import post_delete @@ -29,7 +29,6 @@ from django_countries.fields import Country from django_scopes import ScopedManager, scopes_disabled from i18nfield.strings import LazyI18nString -from jsonfallback.fields import FallbackJSONField from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.phonenumber import PhoneNumber from phonenumbers import NumberParseException @@ -333,12 +332,12 @@ def annotate_overpayments(cls, qs, results=True, refunds=True, sums=False): refund_sum=refund_sum_sq, ) qs = qs.annotate( - computed_payment_refund_sum=Coalesce(payment_sum_sq, 0) - Coalesce(refund_sum_sq, 0), + computed_payment_refund_sum=Coalesce(payment_sum_sq, Decimal('0.00')) - Coalesce(refund_sum_sq, Decimal('0.00')), ) qs = qs.annotate( - pending_sum_t=F('total') - Coalesce(payment_sum_sq, 0) + Coalesce(refund_sum_sq, 0), - pending_sum_rc=-1 * Coalesce(payment_sum_sq, 0) + Coalesce(refund_sum_sq, 0), + pending_sum_t=F('total') - Coalesce(payment_sum_sq, Decimal('0.00')) + Coalesce(refund_sum_sq, Decimal('0.00')), + pending_sum_rc=-1 * Coalesce(payment_sum_sq, Decimal('0.00')) + Coalesce(refund_sum_sq, Decimal('0.00')), ) if refunds: qs = qs.annotate( @@ -349,23 +348,23 @@ def annotate_overpayments(cls, qs, results=True, refunds=True, sums=False): qs = qs.annotate( is_overpaid=Case( When(~Q(status=Order.STATUS_CANCELED) & Q(pending_sum_t__lt=-1e-8), - then=Value('1')), + then=Value(1)), When(Q(status=Order.STATUS_CANCELED) & Q(pending_sum_rc__lt=-1e-8), - then=Value('1')), - default=Value('0'), + then=Value(1)), + default=Value(0), output_field=models.IntegerField() ), is_pending_with_full_payment=Case( When(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=1e-8) & Q(require_approval=False), - then=Value('1')), - default=Value('0'), + then=Value(1)), + default=Value(0), output_field=models.IntegerField() ), is_underpaid=Case( When(Q(status=Order.STATUS_PAID) & Q(pending_sum_t__gt=1e-8), - then=Value('1')), - default=Value('0'), + then=Value(1)), + default=Value(0), output_field=models.IntegerField() ) ) @@ -1135,7 +1134,7 @@ class AbstractPosition(models.Model): blank=True, null=True, help_text=_("Empty, if this product is not an admission ticket") ) - attendee_name_parts = FallbackJSONField( + attendee_name_parts = JSONField( blank=True, default=dict ) attendee_email = models.EmailField( @@ -2255,7 +2254,7 @@ class InvoiceAddress(models.Model): is_business = models.BooleanField(default=False, verbose_name=_('Business customer')) company = models.CharField(max_length=255, blank=True, verbose_name=_('Company name')) name_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True) - name_parts = FallbackJSONField(default=dict) + name_parts = JSONField(default=dict) street = models.TextField(verbose_name=_('Address'), blank=False) zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), blank=False) city = models.CharField(max_length=255, verbose_name=_('City'), blank=False) diff --git a/src/pretix/base/models/waitinglist.py b/src/pretix/base/models/waitinglist.py index 2dd5bcc0f..d0bc6861e 100644 --- a/src/pretix/base/models/waitinglist.py +++ b/src/pretix/base/models/waitinglist.py @@ -2,10 +2,10 @@ from django.core.exceptions import ValidationError from django.db import models, transaction +from django.db.models import JSONField from django.utils.timezone import now from django.utils.translation import gettext_lazy as _, pgettext_lazy from django_scopes import ScopedManager -from jsonfallback.fields import FallbackJSONField from phonenumber_field.modelfields import PhoneNumberField from pretix.base.email import get_email_context @@ -45,7 +45,7 @@ class WaitingListEntry(LoggedModel): verbose_name=_("Name"), blank=True, null=True, ) - name_parts = FallbackJSONField( + name_parts = JSONField( blank=True, default=dict ) email = models.EmailField( diff --git a/src/pretix/helpers/models.py b/src/pretix/helpers/models.py index 2451a71d0..a0b0b2b68 100644 --- a/src/pretix/helpers/models.py +++ b/src/pretix/helpers/models.py @@ -1,5 +1,6 @@ import copy +from django.core.files import File from django.db import models @@ -16,7 +17,7 @@ def modelcopy(obj: models.Model, **kwargs): n = obj.__class__(**kwargs) for f in obj._meta.fields: val = getattr(obj, f.name) - if isinstance(val, models.Model): + if isinstance(val, (models.Model, File)): setattr(n, f.name, copy.copy(val)) else: setattr(n, f.name, copy.deepcopy(val)) diff --git a/src/pretix/helpers/templatetags/jsonfield.py b/src/pretix/helpers/templatetags/jsonfield.py new file mode 100644 index 000000000..bb04757ab --- /dev/null +++ b/src/pretix/helpers/templatetags/jsonfield.py @@ -0,0 +1,61 @@ +# replacement for jsonfallback functions copied from +# https://github.com/raphaelm/django-jsonfallback + +import copy +from django.db import NotSupportedError +from django.db.models import Expression, JSONField + +def mysql_compile_json_path(key_transforms): + path = ['$'] + for key_transform in key_transforms: + try: + num = int(key_transform) + path.append('[{}]'.format(num)) + except ValueError: # non-integer + path.append('.') + path.append(key_transform) + return ''.join(path) + +def postgres_compile_json_path(key_transforms): + return "{" + ','.join(key_transforms) + "}" + +class JSONExtract(Expression): + def __init__(self, expression, *path, output_field=JSONField(), **extra): + super().__init__(output_field=output_field) + self.path = path + self.source_expression = self._parse_expressions(expression)[0] + self.extra = extra + + def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False): + c = self.copy() + c.is_summary = summarize + c.source_expression = c.source_expression.resolve_expression(query, allow_joins, reuse, summarize, for_save) + return c + + def as_sql(self, compiler, connection, function=None, template=None, arg_joiner=None, **extra_context): + if '.postgresql' in connection.settings_dict['ENGINE']: + params = [] + arg_sql, arg_params = compiler.compile(self.source_expression) + params.extend(arg_params) + json_path = postgres_compile_json_path(self.path) + params.append(json_path) + template = '{} #> %s'.format(arg_sql) + return template, params + elif '.mysql' in connection.settings_dict['ENGINE']: + params = [] + arg_sql, arg_params = compiler.compile(self.source_expression) + params.extend(arg_params) + json_path = mysql_compile_json_path(self.path) + params.append(json_path) + template = 'JSON_EXTRACT({}, %s)'.format(arg_sql) + return template, params + else: + raise NotSupportedError( + 'Functions on JSONFields are only supported on PostgreSQL and MySQL at the moment.' + ) + + def copy(self): + c = super().copy() + c.source_expression = copy.copy(self.source_expression) + c.extra = self.extra.copy() + return c diff --git a/src/pretix/plugins/badges/exporters.py b/src/pretix/plugins/badges/exporters.py index be3042cbc..407b85bb0 100644 --- a/src/pretix/plugins/badges/exporters.py +++ b/src/pretix/plugins/badges/exporters.py @@ -15,7 +15,6 @@ from django.db.models.functions import Coalesce from django.utils.timezone import make_aware from django.utils.translation import gettext as _, gettext_lazy -from jsonfallback.functions import JSONExtract from reportlab.lib import pagesizes from reportlab.lib.units import mm from reportlab.pdfgen import canvas @@ -28,6 +27,7 @@ from pretix.base.settings import PERSON_NAME_SCHEMES from pretix.plugins.badges.models import BadgeItem, BadgeLayout +from ...helpers.templatetags.jsonfield import JSONExtract def _renderer(event, layout): if layout is None: diff --git a/src/pretix/plugins/checkinlists/exporters.py b/src/pretix/plugins/checkinlists/exporters.py index 197e2dcff..b05522087 100644 --- a/src/pretix/plugins/checkinlists/exporters.py +++ b/src/pretix/plugins/checkinlists/exporters.py @@ -12,7 +12,6 @@ from django.utils.formats import date_format from django.utils.timezone import is_aware, make_aware from django.utils.translation import gettext as _, gettext_lazy, pgettext -from jsonfallback.functions import JSONExtract from pytz import UTC from reportlab.lib.units import mm from reportlab.platypus import Flowable, Paragraph, Spacer, Table, TableStyle @@ -26,6 +25,8 @@ from pretix.control.forms.widgets import Select2 from pretix.plugins.reports.exporters import ReportlabExportMixin +from ...helpers.templatetags.jsonfield import JSONExtract + class CheckInListMixin(BaseExporter): @property diff --git a/src/pretix/plugins/ticketoutputpdf/exporters.py b/src/pretix/plugins/ticketoutputpdf/exporters.py index 6f70de65c..31ac21923 100644 --- a/src/pretix/plugins/ticketoutputpdf/exporters.py +++ b/src/pretix/plugins/ticketoutputpdf/exporters.py @@ -10,7 +10,6 @@ from django.db.models.functions import Coalesce from django.utils.timezone import make_aware from django.utils.translation import gettext as _, gettext_lazy -from jsonfallback.functions import JSONExtract from PyPDF2.merger import PdfFileMerger from pretix.base.exporter import BaseExporter @@ -18,6 +17,8 @@ from pretix.base.models import Event, Order, OrderPosition from pretix.base.settings import PERSON_NAME_SCHEMES +from ...helpers.templatetags.jsonfield import JSONExtract + from .ticketoutput import PdfTicketOutput diff --git a/src/requirements/dev.txt b/src/requirements/dev.txt index 11bb51df2..8d5474468 100644 --- a/src/requirements/dev.txt +++ b/src/requirements/dev.txt @@ -1,4 +1,4 @@ -django-debug-toolbar==2.1 +django-debug-toolbar==3.2 # Testing requirements pycodestyle==2.5.* pyflakes==2.1.* @@ -12,7 +12,7 @@ pytest-django==4.* isort pytest-rerunfailures==9.* pytest-mock==2.0.* -responses +responses==0.23.0 potypo freezegun diff --git a/src/requirements/production.txt b/src/requirements/production.txt index e5664b371..f31b4bc4c 100644 --- a/src/requirements/production.txt +++ b/src/requirements/production.txt @@ -1,25 +1,25 @@ # Functional requirements -Django==3.0.*,>=3.0.14 -djangorestframework==3.11.* +Django==3.2.* +djangorestframework==3.12.* python-dateutil==2.8.* isoweek -requests==2.24.0 +requests==2.25.0 pytz -django-bootstrap3==12.0.* +django-bootstrap3==15.0.* django-formset-js-improved==0.5.0.2 django-compressor==2.4.* django-hierarkey==1.0.*,>=1.0.4 -django-filter==2.2.* +django-filter==2.4.* django-scopes==1.2.* -reportlab>=3.5.18 +reportlab>=3.5.65 PyPDF2==1.26.* -Pillow>=8.*,<9.0 +Pillow==8.* django-libsass==0.8 libsass==0.20.* django-otp==0.7.*,>=0.7.5 python-u2flib-server==4.* webauthn==0.4.* -django-formtools==2.2 +django-formtools==2.3 celery==4.4.* kombu==4.6.* django-statici18n==1.9.* @@ -41,8 +41,8 @@ jsonschema openpyxl==3.0.* django-oauth-toolkit==1.2.* oauthlib==3.1.* -django-jsonfallback>=2.1.2 psycopg2-binary +django-mysql==4.5.0 tqdm==4.* # Stripe stripe==2.42.* @@ -58,7 +58,7 @@ django-countries>=6.0 pyuca # for better sorting of country names in django-countries defusedcsv>=1.1.0 vat_moss_forked==2020.3.20.0.11.0 -django-localflavor>=2.2 +django-localflavor==3.0.* django-redis==4.11.* redis==3.4.* django-phonenumber-field==4.0.* @@ -68,6 +68,6 @@ arabic-reshaper==2.0.15 # Support for Aabic in reportlab packaging tlds>=2020041600 text-unidecode==1.* -protobuf==3.13.* +protobuf==3.15.* cryptography>=3.4.2 sepaxml==2.4.*,>=2.4.1 diff --git a/src/setup.py b/src/setup.py index 58b8854f2..5ff0d47d9 100644 --- a/src/setup.py +++ b/src/setup.py @@ -113,27 +113,27 @@ def run(self): keywords='tickets web shop ecommerce', install_requires=[ - 'Django==3.0.*,>=3.0.14', - 'djangorestframework==3.11.*', + 'Django==3.2.*', + 'djangorestframework==3.12.*', 'python-dateutil==2.8.*', 'isoweek', - 'requests==2.24.*', + 'requests==2.25.0', 'pytz', - 'django-bootstrap3==12.0.*', + 'django-bootstrap3==15.0.*', 'django-formset-js-improved==0.5.0.2', 'django-compressor==2.4.*', 'django-hierarkey==1.0.*,>=1.0.4', - 'django-filter==2.2.*', + 'django-filter==2.4.*', 'django-scopes==1.2.*', - 'reportlab>=3.5.18', - 'Pillow>=8.*,<9.0', + 'reportlab>=3.5.65', + 'Pillow=8.*', 'PyPDF2==1.26.*', 'django-libsass==0.8', 'libsass==0.20.*', 'django-otp==0.7.*,>=0.7.5', 'webauthn==0.4.*', 'python-u2flib-server==4.*', - 'django-formtools==2.2', + 'django-formtools==2.3', 'celery==4.4.*', 'kombu==4.6.*', 'django-statici18n==1.9.*', @@ -157,8 +157,8 @@ def run(self): 'chardet<3.1.0,>=3.0.2', 'mt-940==3.2', 'django-i18nfield==1.9.*,>=1.9.1', - 'django-jsonfallback>=2.1.2', 'psycopg2-binary', + 'django-mysql', 'tqdm==4.*', 'vobject==0.9.*', 'pycountry', @@ -166,7 +166,7 @@ def run(self): 'pyuca', 'defusedcsv>=1.1.0', 'vat_moss_forked==2020.3.20.0.11.0', - 'django-localflavor>=2.2', + 'django-localflavor==3.0', 'jsonschema', 'django-hijack>=2.1.10,<2.2.0', 'openpyxl==3.0.*', @@ -179,13 +179,13 @@ def run(self): 'packaging', 'tlds>=2020041600', 'text-unidecode==1.*', - 'protobuf==3.13.*', + 'protobuf==3.15.*', 'cryptography>=3.4.2', 'sepaxml==2.4.*,>=2.4.1', ], extras_require={ 'dev': [ - 'django-debug-toolbar==2.1', + 'django-debug-toolbar==3.2', 'pycodestyle==2.5.*', 'pyflakes==2.1.*', 'flake8==3.7.*', @@ -198,7 +198,7 @@ def run(self): 'isort', 'pytest-mock==2.0.*', 'pytest-rerunfailures==9.*', - 'responses', + 'responses==0.23.0', 'potypo', 'freezegun', ], diff --git a/src/tests/api/test_idempotency.py b/src/tests/api/test_idempotency.py index c92545d5d..950040d5b 100644 --- a/src/tests/api/test_idempotency.py +++ b/src/tests/api/test_idempotency.py @@ -46,7 +46,7 @@ def test_scoped_by_key(token_client, organizer): PAYLOAD, format='json', HTTP_X_IDEMPOTENCY_KEY='foo') assert resp.status_code == 201 assert d1.data == json.loads(resp.content.decode()) - assert d1._headers == resp._headers + assert d1.headers._store == resp.headers._store resp = token_client.post('/api/v1/organizers/{}/events/'.format(organizer.slug), PAYLOAD, format='json', HTTP_X_IDEMPOTENCY_KEY='bar') assert resp.status_code == 400 diff --git a/src/tests/control/test_auth.py b/src/tests/control/test_auth.py index 70462ff77..34d38cee2 100644 --- a/src/tests/control/test_auth.py +++ b/src/tests/control/test_auth.py @@ -1,5 +1,5 @@ import time -from datetime import date, timedelta +from datetime import datetime, timedelta import pytest from django.conf import settings @@ -492,8 +492,8 @@ def test_recovery_invalid_token(self): def test_recovery_expired_token(self): class Mocked(PasswordResetTokenGenerator): - def _today(self): - return date.today() - timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1) + def _now(self): + return datetime.now() - timedelta(seconds=settings.PASSWORD_RESET_TIMEOUT + 3600) generator = Mocked() token = generator.make_token(self.user)