diff --git a/src/pretix/base/i18n.py b/src/pretix/base/i18n.py index 4de5bc344d..f39935a6da 100644 --- a/src/pretix/base/i18n.py +++ b/src/pretix/base/i18n.py @@ -1,4 +1,3 @@ -import json from contextlib import contextmanager from django.conf import settings @@ -48,27 +47,14 @@ def language(lng): class LazyLocaleException(Exception): - def __init__(self, msg, msgargs=None): - self.msg = msg - - if isinstance(msgargs, list) or isinstance(msgargs, tuple) or isinstance(msgargs, dict): - msgargs = json.dumps(msgargs, cls=I18nJSONEncoder) - - self.msgargs = msgargs - super().__init__(msg, self.msgargs) + def __init__(self, *args): + self.msg = args[0] + self.msgargs = args[1] if len(args) > 1 else None + self.args = args + super().__init__(self.msg, self.msgargs) def __str__(self): if self.msgargs: - data = json.loads(self.msgargs) - if isinstance(data, dict): - for k, v in data.items(): - if isinstance(v, dict): - data[k] = LazyI18nString(v) - elif isinstance(data, list): - for i, v in enumerate(data): - if isinstance(v, dict): - data[i] = LazyI18nString(v) - - return ugettext(self.msg) % data + return ugettext(self.msg) % self.msgargs else: return ugettext(self.msg) diff --git a/src/pretix/base/services/async.py b/src/pretix/base/services/async.py index a27050a6fe..25a96bf428 100644 --- a/src/pretix/base/services/async.py +++ b/src/pretix/base/services/async.py @@ -19,7 +19,6 @@ from pretix.celery_app import app class ProfiledTask(app.Task): - def __call__(self, *args, **kwargs): if settings.PROFILING_RATE > 0 and random.random() < settings.PROFILING_RATE / 100: diff --git a/src/pretix/base/services/cart.py b/src/pretix/base/services/cart.py index 5ad77edfe0..6a449fc362 100644 --- a/src/pretix/base/services/cart.py +++ b/src/pretix/base/services/cart.py @@ -1,6 +1,7 @@ from collections import Counter, namedtuple from datetime import timedelta from decimal import Decimal + from typing import List, Optional from celery.exceptions import MaxRetriesExceededError @@ -10,7 +11,7 @@ from django.utils.timezone import now from django.utils.translation import ugettext as _ from pretix.base.decimal import round_decimal -from pretix.base.i18n import LazyLocaleException +from pretix.base.i18n import LazyLocaleException, language from pretix.base.models import ( CartPosition, Event, Item, ItemVariation, Voucher, ) @@ -116,7 +117,7 @@ class CartManager: cartsize -= len([1 for op in self._operations if isinstance(op, self.RemoveOperation)]) if cartsize > int(self.event.settings.max_items_per_order): # TODO: i18n plurals - raise CartError(error_messages['max_items'], (self.event.settings.max_items_per_order,)) + raise CartError(_(error_messages['max_items']) % (self.event.settings.max_items_per_order,)) def _check_item_constraints(self, op): if isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation): @@ -144,8 +145,12 @@ class CartManager: ) if new_total > op.item.max_per_order: - raise CartError(error_messages['max_items_per_product'], {'max': op.item.max_per_order, - 'product': op.item.name}) + raise CartError( + _(error_messages['max_items_per_product']) % { + 'max': op.item.max_per_order, + 'product': op.item.name + } + ) def _get_price(self, item: Item, variation: Optional[ItemVariation], voucher: Optional[Voucher], custom_price: Optional[Decimal]): @@ -369,7 +374,7 @@ class CartManager: @app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,)) -def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None) -> None: +def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None, locale='en') -> None: """ Adds a list of items to a user's cart. :param event: The event ID in question @@ -378,33 +383,35 @@ def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None) -> :param coupon: A coupon that should also be reeemed :raises CartError: On any error that occured """ - event = Event.objects.get(id=event) - try: + with language(locale): + event = Event.objects.get(id=event) try: - cm = CartManager(event=event, cart_id=cart_id) - cm.add_new_items(items) - cm.commit() - except LockTimeoutException: - self.retry() - except (MaxRetriesExceededError, LockTimeoutException): - raise CartError(error_messages['busy']) + try: + cm = CartManager(event=event, cart_id=cart_id) + cm.add_new_items(items) + cm.commit() + except LockTimeoutException: + self.retry() + except (MaxRetriesExceededError, LockTimeoutException): + raise CartError(error_messages['busy']) @app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,)) -def remove_items_from_cart(self, event: int, items: List[dict], cart_id: str=None) -> None: +def remove_items_from_cart(self, event: int, items: List[dict], cart_id: str=None, locale='en') -> None: """ Removes a list of items from a user's cart. :param event: The event ID in question :param items: A list of tuple of the form (item id, variation id or None, number) :param session: Session ID of a guest """ - event = Event.objects.get(id=event) - try: + with language(locale): + event = Event.objects.get(id=event) try: - cm = CartManager(event=event, cart_id=cart_id) - cm.remove_items(items) - cm.commit() - except LockTimeoutException: - self.retry() - except (MaxRetriesExceededError, LockTimeoutException): - raise CartError(error_messages['busy']) + try: + cm = CartManager(event=event, cart_id=cart_id) + cm.remove_items(items) + cm.commit() + except LockTimeoutException: + self.retry() + except (MaxRetriesExceededError, LockTimeoutException): + raise CartError(error_messages['busy']) diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index 92854fe010..035114019d 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -390,37 +390,36 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str], if not order.invoices.exists(): generate_invoice(order) - with language(order.locale): - if order.total == Decimal('0.00'): - mailtext = event.settings.mail_text_order_free - else: - mailtext = event.settings.mail_text_order_placed + if order.total == Decimal('0.00'): + mailtext = event.settings.mail_text_order_free + else: + mailtext = event.settings.mail_text_order_placed - try: - invoice_name = order.invoice_address.name - invoice_company = order.invoice_address.company - except InvoiceAddress.DoesNotExist: - invoice_name = "" - invoice_company = "" + try: + invoice_name = order.invoice_address.name + invoice_company = order.invoice_address.company + except InvoiceAddress.DoesNotExist: + invoice_name = "" + invoice_company = "" - mail( - order.email, _('Your order: %(code)s') % {'code': order.code}, - mailtext, - { - 'total': LazyNumber(order.total), - 'currency': event.currency, - 'date': LazyDate(order.expires), - 'event': event.name, - 'url': build_absolute_uri(event, 'presale:event.order', kwargs={ - 'order': order.code, - 'secret': order.secret - }), - 'paymentinfo': str(pprov.order_pending_mail_render(order)), - 'invoice_name': invoice_name, - 'invoice_company': invoice_company, - }, - event, locale=order.locale - ) + mail( + order.email, _('Your order: %(code)s') % {'code': order.code}, + mailtext, + { + 'total': LazyNumber(order.total), + 'currency': event.currency, + 'date': LazyDate(order.expires), + 'event': event.name, + 'url': build_absolute_uri(event, 'presale:event.order', kwargs={ + 'order': order.code, + 'secret': order.secret + }), + 'paymentinfo': str(pprov.order_pending_mail_render(order)), + 'invoice_name': invoice_name, + 'invoice_company': invoice_company, + }, + event, locale=order.locale + ) return order.id @@ -671,13 +670,14 @@ class OrderChangeManager: @app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,)) def perform_order(self, event: str, payment_provider: str, positions: List[str], email: str=None, locale: str=None, address: int=None, meta_info: dict=None): - try: + with language(locale): try: - return _perform_order(event, payment_provider, positions, email, locale, address, meta_info) - except LockTimeoutException: - self.retry() - except (MaxRetriesExceededError, LockTimeoutException): - return OrderError(error_messages['busy']) + try: + return _perform_order(event, payment_provider, positions, email, locale, address, meta_info) + except LockTimeoutException: + self.retry() + except (MaxRetriesExceededError, LockTimeoutException): + return OrderError(error_messages['busy']) @app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,)) diff --git a/src/pretix/presale/views/cart.py b/src/pretix/presale/views/cart.py index e040588f87..1c9e2d72de 100644 --- a/src/pretix/presale/views/cart.py +++ b/src/pretix/presale/views/cart.py @@ -2,6 +2,7 @@ from django.contrib import messages from django.db.models import Count, Q from django.http import JsonResponse from django.shortcuts import redirect +from django.utils import translation from django.utils.timezone import now from django.utils.translation import ugettext as _ from django.views.generic import TemplateView, View @@ -116,7 +117,7 @@ class CartRemove(EventViewMixin, CartActionMixin, AsyncAction, View): def post(self, request, *args, **kwargs): items = self._items_from_post_data() if items: - return self.do(self.request.event.id, items, self.request.session.session_key) + return self.do(self.request.event.id, items, self.request.session.session_key, translation.get_language()) else: if 'ajax' in self.request.GET or 'ajax' in self.request.POST: return JsonResponse({ @@ -136,7 +137,7 @@ class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View): def post(self, request, *args, **kwargs): items = self._items_from_post_data() if items: - return self.do(self.request.event.id, items, self.request.session.session_key) + return self.do(self.request.event.id, items, self.request.session.session_key, translation.get_language()) else: if 'ajax' in self.request.GET or 'ajax' in self.request.POST: return JsonResponse({