diff --git a/src/pretix/base/models/log.py b/src/pretix/base/models/log.py
index 752913462..2c399bb04 100644
--- a/src/pretix/base/models/log.py
+++ b/src/pretix/base/models/log.py
@@ -33,6 +33,7 @@
# License for the specific language governing permissions and limitations under the License.
import json
+from collections import defaultdict
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
@@ -130,8 +131,8 @@ class LogEntry(models.Model):
@cached_property
def display_object(self):
from . import (
- Discount, Event, Item, ItemCategory, Order, Question, Quota,
- SubEvent, TaxRule, Voucher,
+ Discount, Event, Item, Order, Question, Quota,
+ SubEvent, Voucher,
)
try:
@@ -204,16 +205,6 @@ class LogEntry(models.Model):
}),
'val': escape(co.internal_name),
}
- elif isinstance(co, ItemCategory):
- a_text = _('Category {val}')
- a_map = {
- 'href': reverse('control:event.items.categories.edit', kwargs={
- 'event': self.event.slug,
- 'organizer': self.event.organizer.slug,
- 'category': co.id
- }),
- 'val': escape(co.name),
- }
elif isinstance(co, Question):
a_text = _('Question {val}')
a_map = {
@@ -224,16 +215,6 @@ class LogEntry(models.Model):
}),
'val': escape(co.question),
}
- elif isinstance(co, TaxRule):
- a_text = _('Tax rule {val}')
- a_map = {
- 'href': reverse('control:event.settings.tax.edit', kwargs={
- 'event': self.event.slug,
- 'organizer': self.event.organizer.slug,
- 'rule': co.id
- }),
- 'val': escape(co.name),
- }
if a_text and a_map:
a_map['val'] = '{val}'.format_map(a_map)
@@ -298,7 +279,12 @@ log_entry_types = Registry({'action_type': lambda o: getattr(o, 'action_type')})
class LogEntryType:
def display(self, logentry):
if hasattr(self, 'plain'):
- return self.plain
+ plain = str(self.plain)
+ if '{' in plain:
+ data = defaultdict(lambda: '?', logentry.parsed_data)
+ return plain.format_map(data)
+ else:
+ return plain
def get_object_link_info(self, logentry) -> dict:
pass
@@ -312,7 +298,7 @@ class LogEntryType:
object_link_wrapper = '{val}'
def shred_pii(self, logentry):
- raise NotImplemented
+ raise NotImplementedError
@classmethod
def derive_plains(cls, plains):
@@ -363,24 +349,6 @@ class VoucherLogEntryType(EventLogEntryType):
return order.code[:6]
-@log_entry_types.register_instance()
-class VoucherRedeemedLogEntryType(VoucherLogEntryType):
- action_type = 'pretix.voucher.redeemed'
- plain = _('The voucher has been redeemed in order {order_code}.')
-
- def display(self, logentry):
- data = json.loads(logentry.data)
- data = defaultdict(lambda: '?', data)
- url = reverse('control:event.order', kwargs={
- 'event': logentry.event.slug,
- 'organizer': logentry.event.organizer.slug,
- 'code': data['order_code']
- })
- return mark_safe(self.plain.format(
- order_code='{}'.format(url, data['order_code']),
- ))
-
-
class ItemLogEntryType(EventLogEntryType):
object_link_wrapper = _('Product {val}')
object_link_viewname = 'control:event.item'
@@ -411,14 +379,6 @@ class ItemCategoryLogEntryType(EventLogEntryType):
object_link_argname = 'category'
-log_entry_types.register(*ItemCategoryLogEntryType.derive_plains({
- 'pretix.event.category.added': _('The category has been added.'),
- 'pretix.event.category.deleted': _('The category has been deleted.'),
- 'pretix.event.category.changed': _('The category has been changed.'),
- 'pretix.event.category.reordered': _('The category has been reordered.'),
-}))
-
-
class QuestionLogEntryType(EventLogEntryType):
object_link_wrapper = _('Question {val}')
object_link_viewname = 'control:event.items.questions.show'
@@ -429,11 +389,3 @@ class TaxRuleLogEntryType(EventLogEntryType):
object_link_wrapper = _('Tax rule {val}')
object_link_viewname = 'control:event.settings.tax.edit'
object_link_argname = 'rule'
-
-
-log_entry_types.register(*TaxRuleLogEntryType.derive_plains({
- 'pretix.event.taxrule.added': _('The tax rule has been added.'),
- 'pretix.event.taxrule.deleted': _('The tax rule has been deleted.'),
- 'pretix.event.taxrule.changed': _('The tax rule has been changed.'),
-}))
-
diff --git a/src/pretix/control/logdisplay.py b/src/pretix/control/logdisplay.py
index c69583bdb..1813f9ebf 100644
--- a/src/pretix/control/logdisplay.py
+++ b/src/pretix/control/logdisplay.py
@@ -51,6 +51,12 @@ from pretix.base.models import (
Checkin, CheckinList, Event, ItemVariation, LogEntry, OrderPosition,
TaxRule,
)
+from pretix.base.models.log import (
+ DiscountLogEntryType, EventLogEntryType, ItemCategoryLogEntryType,
+ ItemLogEntryType, LogEntryType, OrderLogEntryType, QuestionLogEntryType,
+ QuotaLogEntryType, TaxRuleLogEntryType, VoucherLogEntryType,
+ log_entry_types,
+)
from pretix.base.signals import logentry_display, orderposition_blocked_display
from pretix.base.templatetags.money import money_filter
@@ -328,277 +334,6 @@ def _display_checkin(event, logentry):
@receiver(signal=logentry_display, dispatch_uid="pretixcontrol_logentry_display")
def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
- plains = {
- 'pretix.object.cloned': _('This object has been created by cloning.'),
- 'pretix.organizer.changed': _('The organizer has been changed.'),
- 'pretix.organizer.settings': _('The organizer settings have been changed.'),
- 'pretix.organizer.footerlinks.changed': _('The footer links have been changed.'),
- 'pretix.organizer.export.schedule.added': _('A scheduled export has been added.'),
- 'pretix.organizer.export.schedule.changed': _('A scheduled export has been changed.'),
- 'pretix.organizer.export.schedule.deleted': _('A scheduled export has been deleted.'),
- 'pretix.organizer.export.schedule.executed': _('A scheduled export has been executed.'),
- 'pretix.organizer.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
- 'pretix.giftcards.acceptance.added': _('Gift card acceptance for another organizer has been added.'),
- 'pretix.giftcards.acceptance.removed': _('Gift card acceptance for another organizer has been removed.'),
- 'pretix.giftcards.acceptance.acceptor.invited': _('A new gift card acceptor has been invited.'),
- 'pretix.giftcards.acceptance.acceptor.removed': _('A gift card acceptor has been removed.'),
- 'pretix.giftcards.acceptance.issuer.removed': _('A gift card issuer has been removed or declined.'),
- 'pretix.giftcards.acceptance.issuer.accepted': _('A new gift card issuer has been accepted.'),
- 'pretix.webhook.created': _('The webhook has been created.'),
- 'pretix.webhook.changed': _('The webhook has been changed.'),
- 'pretix.webhook.retries.expedited': _('The webhook call retry jobs have been manually expedited.'),
- 'pretix.webhook.retries.dropped': _('The webhook call retry jobs have been dropped.'),
- 'pretix.ssoprovider.created': _('The SSO provider has been created.'),
- 'pretix.ssoprovider.changed': _('The SSO provider has been changed.'),
- 'pretix.ssoprovider.deleted': _('The SSO provider has been deleted.'),
- 'pretix.ssoclient.created': _('The SSO client has been created.'),
- 'pretix.ssoclient.changed': _('The SSO client has been changed.'),
- 'pretix.ssoclient.deleted': _('The SSO client has been deleted.'),
- 'pretix.membershiptype.created': _('The membership type has been created.'),
- 'pretix.membershiptype.changed': _('The membership type has been changed.'),
- 'pretix.membershiptype.deleted': _('The membership type has been deleted.'),
- 'pretix.saleschannel.created': _('The sales channel has been created.'),
- 'pretix.saleschannel.changed': _('The sales channel has been changed.'),
- 'pretix.saleschannel.deleted': _('The sales channel has been deleted.'),
- 'pretix.customer.created': _('The account has been created.'),
- 'pretix.customer.changed': _('The account has been changed.'),
- 'pretix.customer.membership.created': _('A membership for this account has been added.'),
- 'pretix.customer.membership.changed': _('A membership of this account has been changed.'),
- 'pretix.customer.membership.deleted': _('A membership of this account has been deleted.'),
- 'pretix.customer.anonymized': _('The account has been disabled and anonymized.'),
- 'pretix.customer.password.resetrequested': _('A new password has been requested.'),
- 'pretix.customer.password.set': _('A new password has been set.'),
- 'pretix.reusable_medium.created': _('The reusable medium has been created.'),
- 'pretix.reusable_medium.created.auto': _('The reusable medium has been created automatically.'),
- 'pretix.reusable_medium.changed': _('The reusable medium has been changed.'),
- 'pretix.reusable_medium.linked_orderposition.changed': _('The medium has been connected to a new ticket.'),
- 'pretix.reusable_medium.linked_giftcard.changed': _('The medium has been connected to a new gift card.'),
- 'pretix.email.error': _('Sending of an email has failed.'),
- 'pretix.event.comment': _('The event\'s internal comment has been updated.'),
- 'pretix.event.canceled': _('The event has been canceled.'),
- 'pretix.event.deleted': _('An event has been deleted.'),
- 'pretix.event.shredder.started': _('A removal process for personal data has been started.'),
- 'pretix.event.shredder.completed': _('A removal process for personal data has been completed.'),
- 'pretix.event.order.modified': _('The order details have been changed.'),
- 'pretix.event.order.unpaid': _('The order has been marked as unpaid.'),
- 'pretix.event.order.secret.changed': _('The order\'s secret has been changed.'),
- 'pretix.event.order.expirychanged': _('The order\'s expiry date has been changed.'),
- 'pretix.event.order.valid_if_pending.set': _('The order has been set to be usable before it is paid.'),
- 'pretix.event.order.valid_if_pending.unset': _('The order has been set to require payment before use.'),
- 'pretix.event.order.expired': _('The order has been marked as expired.'),
- 'pretix.event.order.paid': _('The order has been marked as paid.'),
- 'pretix.event.order.cancellationrequest.deleted': _('The cancellation request has been deleted.'),
- 'pretix.event.order.refunded': _('The order has been refunded.'),
- 'pretix.event.order.reactivated': _('The order has been reactivated.'),
- 'pretix.event.order.deleted': _('The test mode order {code} has been deleted.'),
- 'pretix.event.order.placed': _('The order has been created.'),
- 'pretix.event.order.placed.require_approval': _('The order requires approval before it can continue to be processed.'),
- 'pretix.event.order.approved': _('The order has been approved.'),
- 'pretix.event.order.denied': _('The order has been denied (comment: "{comment}").'),
- 'pretix.event.order.contact.changed': _('The email address has been changed from "{old_email}" '
- 'to "{new_email}".'),
- 'pretix.event.order.contact.confirmed': _('The email address has been confirmed to be working (the user clicked on a link '
- 'in the email for the first time).'),
- 'pretix.event.order.phone.changed': _('The phone number has been changed from "{old_phone}" '
- 'to "{new_phone}".'),
- 'pretix.event.order.customer.changed': _('The customer account has been changed.'),
- 'pretix.event.order.locale.changed': _('The order locale has been changed.'),
- 'pretix.event.order.invoice.generated': _('The invoice has been generated.'),
- 'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'),
- 'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'),
- 'pretix.event.order.comment': _('The order\'s internal comment has been updated.'),
- 'pretix.event.order.custom_followup_at': _('The order\'s follow-up date has been updated.'),
- 'pretix.event.order.checkin_attention': _('The order\'s flag to require attention at check-in has been '
- 'toggled.'),
- 'pretix.event.order.checkin_text': _('The order\'s check-in text has been changed.'),
- 'pretix.event.order.pretix.event.order.valid_if_pending': _('The order\'s flag to be considered valid even if '
- 'unpaid has been toggled.'),
- 'pretix.event.order.payment.changed': _('A new payment {local_id} has been started instead of the previous one.'),
- 'pretix.event.order.email.sent': _('An unidentified type email has been sent.'),
- 'pretix.event.order.email.error': _('Sending of an email has failed.'),
- 'pretix.event.order.email.attachments.skipped': _('The email has been sent without attached tickets since they '
- 'would have been too large to be likely to arrive.'),
- 'pretix.event.order.email.custom_sent': _('A custom email has been sent.'),
- 'pretix.event.order.position.email.custom_sent': _('A custom email has been sent to an attendee.'),
- 'pretix.event.order.email.download_reminder_sent': _('An email has been sent with a reminder that the ticket '
- 'is available for download.'),
- 'pretix.event.order.email.expire_warning_sent': _('An email has been sent with a warning that the order is about '
- 'to expire.'),
- 'pretix.event.order.email.order_canceled': _('An email has been sent to notify the user that the order has been canceled.'),
- 'pretix.event.order.email.event_canceled': _('An email has been sent to notify the user that the event has '
- 'been canceled.'),
- 'pretix.event.order.email.order_changed': _('An email has been sent to notify the user that the order has been changed.'),
- 'pretix.event.order.email.order_free': _('An email has been sent to notify the user that the order has been received.'),
- 'pretix.event.order.email.order_paid': _('An email has been sent to notify the user that payment has been received.'),
- 'pretix.event.order.email.order_denied': _('An email has been sent to notify the user that the order has been denied.'),
- 'pretix.event.order.email.order_approved': _('An email has been sent to notify the user that the order has '
- 'been approved.'),
- 'pretix.event.order.email.order_placed': _('An email has been sent to notify the user that the order has been received and requires payment.'),
- 'pretix.event.order.email.order_placed_require_approval': _('An email has been sent to notify the user that '
- 'the order has been received and requires '
- 'approval.'),
- 'pretix.event.order.email.resend': _('An email with a link to the order detail page has been resent to the user.'),
- 'pretix.event.order.email.payment_failed': _('An email has been sent to notify the user that the payment failed.'),
- 'pretix.event.order.payment.confirmed': _('Payment {local_id} has been confirmed.'),
- 'pretix.event.order.payment.canceled': _('Payment {local_id} has been canceled.'),
- 'pretix.event.order.payment.canceled.failed': _('Canceling payment {local_id} has failed.'),
- 'pretix.event.order.payment.started': _('Payment {local_id} has been started.'),
- 'pretix.event.order.payment.failed': _('Payment {local_id} has failed.'),
- 'pretix.event.order.quotaexceeded': _('The order could not be marked as paid: {message}'),
- 'pretix.event.order.overpaid': _('The order has been overpaid.'),
- 'pretix.event.order.refund.created': _('Refund {local_id} has been created.'),
- 'pretix.event.order.refund.created.externally': _('Refund {local_id} has been created by an external entity.'),
- 'pretix.event.order.refund.requested': _('The customer requested you to issue a refund.'),
- 'pretix.event.order.refund.done': _('Refund {local_id} has been completed.'),
- 'pretix.event.order.refund.canceled': _('Refund {local_id} has been canceled.'),
- 'pretix.event.order.refund.failed': _('Refund {local_id} has failed.'),
- 'pretix.event.export.schedule.added': _('A scheduled export has been added.'),
- 'pretix.event.export.schedule.changed': _('A scheduled export has been changed.'),
- 'pretix.event.export.schedule.deleted': _('A scheduled export has been deleted.'),
- 'pretix.event.export.schedule.executed': _('A scheduled export has been executed.'),
- 'pretix.event.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
- 'pretix.control.auth.user.created': _('The user has been created.'),
- 'pretix.control.auth.user.new_source': _('A first login using {agent_type} on {os_type} from {country} has '
- 'been detected.'),
- 'pretix.user.settings.2fa.enabled': _('Two-factor authentication has been enabled.'),
- 'pretix.user.settings.2fa.disabled': _('Two-factor authentication has been disabled.'),
- 'pretix.user.settings.2fa.regenemergency': _('Your two-factor emergency codes have been regenerated.'),
- 'pretix.user.settings.2fa.emergency': _('A two-factor emergency code has been generated.'),
- 'pretix.user.settings.2fa.device.added': _('A new two-factor authentication device "{name}" has been added to '
- 'your account.'),
- 'pretix.user.settings.2fa.device.deleted': _('The two-factor authentication device "{name}" has been removed '
- 'from your account.'),
- 'pretix.user.settings.notifications.enabled': _('Notifications have been enabled.'),
- 'pretix.user.settings.notifications.disabled': _('Notifications have been disabled.'),
- 'pretix.user.settings.notifications.changed': _('Your notification settings have been changed.'),
- 'pretix.user.anonymized': _('This user has been anonymized.'),
- 'pretix.user.oauth.authorized': _('The application "{application_name}" has been authorized to access your '
- 'account.'),
- 'pretix.control.auth.user.forgot_password.mail_sent': _('Password reset mail sent.'),
- 'pretix.control.auth.user.forgot_password.recovered': _('The password has been reset.'),
- 'pretix.control.auth.user.forgot_password.denied.repeated': _('A repeated password reset has been denied, as '
- 'the last request was less than 24 hours ago.'),
- 'pretix.organizer.deleted': _('The organizer "{name}" has been deleted.'),
- 'pretix.voucher.added': _('The voucher has been created.'),
- 'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
- 'pretix.voucher.added.waitinglist': _('The voucher has been created and sent to a person on the waiting list.'),
- 'pretix.voucher.expired.waitinglist': _('The voucher has been set to expire because the recipient removed themselves from the waiting list.'),
- 'pretix.voucher.changed': _('The voucher has been changed.'),
- 'pretix.voucher.deleted': _('The voucher has been deleted.'),
- 'pretix.voucher.redeemed': _('The voucher has been redeemed in order {order_code}.'),
- 'pretix.event.item.added': _('The product has been created.'),
- 'pretix.event.item.changed': _('The product has been changed.'),
- 'pretix.event.item.reordered': _('The product has been reordered.'),
- 'pretix.event.item.deleted': _('The product has been deleted.'),
- 'pretix.event.item.variation.added': _('The variation "{value}" has been created.'),
- 'pretix.event.item.variation.deleted': _('The variation "{value}" has been deleted.'),
- 'pretix.event.item.variation.changed': _('The variation "{value}" has been changed.'),
- 'pretix.event.item.addons.added': _('An add-on has been added to this product.'),
- 'pretix.event.item.addons.removed': _('An add-on has been removed from this product.'),
- 'pretix.event.item.addons.changed': _('An add-on has been changed on this product.'),
- 'pretix.event.item.bundles.added': _('A bundled item has been added to this product.'),
- 'pretix.event.item.bundles.removed': _('A bundled item has been removed from this product.'),
- 'pretix.event.item.bundles.changed': _('A bundled item has been changed on this product.'),
- 'pretix.event.item_meta_property.added': _('A meta property has been added to this event.'),
- 'pretix.event.item_meta_property.deleted': _('A meta property has been removed from this event.'),
- 'pretix.event.item_meta_property.changed': _('A meta property has been changed on this event.'),
- 'pretix.event.quota.added': _('The quota has been added.'),
- 'pretix.event.quota.deleted': _('The quota has been deleted.'),
- 'pretix.event.quota.changed': _('The quota has been changed.'),
- 'pretix.event.quota.closed': _('The quota has closed.'),
- 'pretix.event.quota.opened': _('The quota has been re-opened.'),
- 'pretix.event.category.added': _('The category has been added.'),
- 'pretix.event.category.deleted': _('The category has been deleted.'),
- 'pretix.event.category.changed': _('The category has been changed.'),
- 'pretix.event.category.reordered': _('The category has been reordered.'),
- 'pretix.event.question.added': _('The question has been added.'),
- 'pretix.event.question.deleted': _('The question has been deleted.'),
- 'pretix.event.question.changed': _('The question has been changed.'),
- 'pretix.event.question.reordered': _('The question has been reordered.'),
- 'pretix.event.discount.added': _('The discount has been added.'),
- 'pretix.event.discount.deleted': _('The discount has been deleted.'),
- 'pretix.event.discount.changed': _('The discount has been changed.'),
- 'pretix.event.taxrule.added': _('The tax rule has been added.'),
- 'pretix.event.taxrule.deleted': _('The tax rule has been deleted.'),
- 'pretix.event.taxrule.changed': _('The tax rule has been changed.'),
- 'pretix.event.checkinlist.added': _('The check-in list has been added.'),
- 'pretix.event.checkinlist.deleted': _('The check-in list has been deleted.'),
- 'pretix.event.checkinlists.deleted': _('The check-in list has been deleted.'), # backwards compatibility
- 'pretix.event.checkinlist.changed': _('The check-in list has been changed.'),
- 'pretix.event.settings': _('The event settings have been changed.'),
- 'pretix.event.tickets.settings': _('The ticket download settings have been changed.'),
- 'pretix.event.plugins.enabled': _('A plugin has been enabled.'),
- 'pretix.event.plugins.disabled': _('A plugin has been disabled.'),
- 'pretix.event.live.activated': _('The shop has been taken live.'),
- 'pretix.event.live.deactivated': _('The shop has been taken offline.'),
- 'pretix.event.testmode.activated': _('The shop has been taken into test mode.'),
- 'pretix.event.testmode.deactivated': _('The test mode has been disabled.'),
- 'pretix.event.added': _('The event has been created.'),
- 'pretix.event.changed': _('The event details have been changed.'),
- 'pretix.event.footerlinks.changed': _('The footer links have been changed.'),
- 'pretix.event.question.option.added': _('An answer option has been added to the question.'),
- 'pretix.event.question.option.deleted': _('An answer option has been removed from the question.'),
- 'pretix.event.question.option.changed': _('An answer option has been changed.'),
- 'pretix.event.permissions.added': _('A user has been added to the event team.'),
- 'pretix.event.permissions.invited': _('A user has been invited to the event team.'),
- 'pretix.event.permissions.changed': _('A user\'s permissions have been changed.'),
- 'pretix.event.permissions.deleted': _('A user has been removed from the event team.'),
- 'pretix.waitinglist.voucher': _('A voucher has been sent to a person on the waiting list.'), # legacy
- 'pretix.event.orders.waitinglist.voucher_assigned': _('A voucher has been sent to a person on the waiting list.'),
- 'pretix.event.orders.waitinglist.deleted': _('An entry has been removed from the waiting list.'),
- 'pretix.event.order.waitinglist.transferred': _('An entry has been transferred to another waiting list.'), # legacy
- 'pretix.event.orders.waitinglist.changed': _('An entry has been changed on the waiting list.'),
- 'pretix.event.orders.waitinglist.added': _('An entry has been added to the waiting list.'),
- 'pretix.team.created': _('The team has been created.'),
- 'pretix.team.changed': _('The team settings have been changed.'),
- 'pretix.team.deleted': _('The team has been deleted.'),
- 'pretix.gate.created': _('The gate has been created.'),
- 'pretix.gate.changed': _('The gate has been changed.'),
- 'pretix.gate.deleted': _('The gate has been deleted.'),
- 'pretix.subevent.deleted': pgettext_lazy('subevent', 'The event date has been deleted.'),
- 'pretix.subevent.canceled': pgettext_lazy('subevent', 'The event date has been canceled.'),
- 'pretix.subevent.changed': pgettext_lazy('subevent', 'The event date has been changed.'),
- 'pretix.subevent.added': pgettext_lazy('subevent', 'The event date has been created.'),
- 'pretix.subevent.quota.added': pgettext_lazy('subevent', 'A quota has been added to the event date.'),
- 'pretix.subevent.quota.changed': pgettext_lazy('subevent', 'A quota has been changed on the event date.'),
- 'pretix.subevent.quota.deleted': pgettext_lazy('subevent', 'A quota has been removed from the event date.'),
- 'pretix.device.created': _('The device has been created.'),
- 'pretix.device.changed': _('The device has been changed.'),
- 'pretix.device.revoked': _('Access of the device has been revoked.'),
- 'pretix.device.initialized': _('The device has been initialized.'),
- 'pretix.device.keyroll': _('The access token of the device has been regenerated.'),
- 'pretix.device.updated': _('The device has notified the server of an hardware or software update.'),
- 'pretix.giftcards.created': _('The gift card has been created.'),
- 'pretix.giftcards.modified': _('The gift card has been changed.'),
- 'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'),
- }
-
- if logentry.action_type.startswith('pretix.event.item.variation'):
- data = logentry.parsed_data
- if 'value' not in data:
- # Backwards compatibility
- var = ItemVariation.objects.filter(id=data['id']).first()
- if var:
- data['value'] = str(var.value)
- else:
- data['value'] = '?'
- else:
- data['value'] = LazyI18nString(data['value'])
-
- if logentry.action_type == "pretix.voucher.redeemed":
- data = defaultdict(lambda: '?', logentry.parsed_data)
- url = reverse('control:event.order', kwargs={
- 'event': logentry.event.slug,
- 'organizer': logentry.event.organizer.slug,
- 'code': data['order_code']
- })
- return mark_safe(plains[logentry.action_type].format(
- order_code='{}'.format(url, data['order_code']),
- ))
-
- if logentry.action_type in plains:
- data = defaultdict(lambda: '?', logentry.parsed_data)
- return plains[logentry.action_type].format_map(data)
if logentry.action_type.startswith('pretix.event.order.changed'):
return _display_order_changed(sender, logentry)
@@ -638,14 +373,405 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
if sender and logentry.action_type.startswith('pretix.event.checkin'):
return _display_checkin(sender, logentry)
- if logentry.action_type == 'pretix.control.views.checkin':
+
+@receiver(signal=orderposition_blocked_display, dispatch_uid="pretixcontrol_orderposition_blocked_display")
+def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, block_name, **kwargs):
+ if block_name == 'admin':
+ return _('Blocked manually')
+ elif block_name.startswith('api:'):
+ return _('Blocked because of an API integration')
+
+
+log_entry_types.register(*OrderLogEntryType.derive_plains({
+ 'pretix.event.order.modified': _('The order details have been changed.'),
+ 'pretix.event.order.unpaid': _('The order has been marked as unpaid.'),
+ 'pretix.event.order.secret.changed': _('The order\'s secret has been changed.'),
+ 'pretix.event.order.expirychanged': _('The order\'s expiry date has been changed.'),
+ 'pretix.event.order.valid_if_pending.set': _('The order has been set to be usable before it is paid.'),
+ 'pretix.event.order.valid_if_pending.unset': _('The order has been set to require payment before use.'),
+ 'pretix.event.order.expired': _('The order has been marked as expired.'),
+ 'pretix.event.order.paid': _('The order has been marked as paid.'),
+ 'pretix.event.order.cancellationrequest.deleted': _('The cancellation request has been deleted.'),
+ 'pretix.event.order.refunded': _('The order has been refunded.'),
+ 'pretix.event.order.reactivated': _('The order has been reactivated.'),
+ 'pretix.event.order.deleted': _('The test mode order {code} has been deleted.'),
+ 'pretix.event.order.placed': _('The order has been created.'),
+ 'pretix.event.order.placed.require_approval': _(
+ 'The order requires approval before it can continue to be processed.'),
+ 'pretix.event.order.approved': _('The order has been approved.'),
+ 'pretix.event.order.denied': _('The order has been denied (comment: "{comment}").'),
+ 'pretix.event.order.contact.changed': _('The email address has been changed from "{old_email}" '
+ 'to "{new_email}".'),
+ 'pretix.event.order.contact.confirmed': _(
+ 'The email address has been confirmed to be working (the user clicked on a link '
+ 'in the email for the first time).'),
+ 'pretix.event.order.phone.changed': _('The phone number has been changed from "{old_phone}" '
+ 'to "{new_phone}".'),
+ 'pretix.event.order.customer.changed': _('The customer account has been changed.'),
+ 'pretix.event.order.locale.changed': _('The order locale has been changed.'),
+ 'pretix.event.order.invoice.generated': _('The invoice has been generated.'),
+ 'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'),
+ 'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'),
+ 'pretix.event.order.comment': _('The order\'s internal comment has been updated.'),
+ 'pretix.event.order.custom_followup_at': _('The order\'s follow-up date has been updated.'),
+ 'pretix.event.order.checkin_attention': _('The order\'s flag to require attention at check-in has been '
+ 'toggled.'),
+ 'pretix.event.order.checkin_text': _('The order\'s check-in text has been changed.'),
+ 'pretix.event.order.pretix.event.order.valid_if_pending': _('The order\'s flag to be considered valid even if '
+ 'unpaid has been toggled.'),
+ 'pretix.event.order.payment.changed': _('A new payment {local_id} has been started instead of the previous one.'),
+ 'pretix.event.order.email.sent': _('An unidentified type email has been sent.'),
+ 'pretix.event.order.email.error': _('Sending of an email has failed.'),
+ 'pretix.event.order.email.attachments.skipped': _('The email has been sent without attached tickets since they '
+ 'would have been too large to be likely to arrive.'),
+ 'pretix.event.order.email.custom_sent': _('A custom email has been sent.'),
+ 'pretix.event.order.position.email.custom_sent': _('A custom email has been sent to an attendee.'),
+ 'pretix.event.order.email.download_reminder_sent': _('An email has been sent with a reminder that the ticket '
+ 'is available for download.'),
+ 'pretix.event.order.email.expire_warning_sent': _('An email has been sent with a warning that the order is about '
+ 'to expire.'),
+ 'pretix.event.order.email.order_canceled': _(
+ 'An email has been sent to notify the user that the order has been canceled.'),
+ 'pretix.event.order.email.event_canceled': _('An email has been sent to notify the user that the event has '
+ 'been canceled.'),
+ 'pretix.event.order.email.order_changed': _(
+ 'An email has been sent to notify the user that the order has been changed.'),
+ 'pretix.event.order.email.order_free': _(
+ 'An email has been sent to notify the user that the order has been received.'),
+ 'pretix.event.order.email.order_paid': _(
+ 'An email has been sent to notify the user that payment has been received.'),
+ 'pretix.event.order.email.order_denied': _(
+ 'An email has been sent to notify the user that the order has been denied.'),
+ 'pretix.event.order.email.order_approved': _('An email has been sent to notify the user that the order has '
+ 'been approved.'),
+ 'pretix.event.order.email.order_placed': _(
+ 'An email has been sent to notify the user that the order has been received and requires payment.'),
+ 'pretix.event.order.email.order_placed_require_approval': _('An email has been sent to notify the user that '
+ 'the order has been received and requires '
+ 'approval.'),
+ 'pretix.event.order.email.resend': _('An email with a link to the order detail page has been resent to the user.'),
+ 'pretix.event.order.email.payment_failed': _('An email has been sent to notify the user that the payment failed.'),
+}))
+
+
+log_entry_types.register(*VoucherLogEntryType.derive_plains({
+ 'pretix.voucher.added': _('The voucher has been created.'),
+ 'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
+ 'pretix.voucher.added.waitinglist': _('The voucher has been created and sent to a person on the waiting list.'),
+ 'pretix.voucher.expired.waitinglist': _(
+ 'The voucher has been set to expire because the recipient removed themselves from the waiting list.'),
+ 'pretix.voucher.changed': _('The voucher has been changed.'),
+ 'pretix.voucher.deleted': _('The voucher has been deleted.'),
+}))
+
+
+@log_entry_types.register_instance()
+class VoucherRedeemedLogEntryType(VoucherLogEntryType):
+ action_type = 'pretix.voucher.redeemed'
+ plain = _('The voucher has been redeemed in order {order_code}.')
+
+ def display(self, logentry):
+ data = json.loads(logentry.data)
+ data = defaultdict(lambda: '?', data)
+ url = reverse('control:event.order', kwargs={
+ 'event': logentry.event.slug,
+ 'organizer': logentry.event.organizer.slug,
+ 'code': data['order_code']
+ })
+ return mark_safe(self.plain.format(
+ order_code='{}'.format(url, data['order_code']),
+ ))
+
+
+log_entry_types.register(*ItemCategoryLogEntryType.derive_plains({
+ 'pretix.event.category.added': _('The category has been added.'),
+ 'pretix.event.category.deleted': _('The category has been deleted.'),
+ 'pretix.event.category.changed': _('The category has been changed.'),
+ 'pretix.event.category.reordered': _('The category has been reordered.'),
+}))
+
+
+log_entry_types.register(*TaxRuleLogEntryType.derive_plains({
+ 'pretix.event.taxrule.added': _('The tax rule has been added.'),
+ 'pretix.event.taxrule.deleted': _('The tax rule has been deleted.'),
+ 'pretix.event.taxrule.changed': _('The tax rule has been changed.'),
+}))
+
+
+class TeamMembershipLogEntryType(LogEntryType):
+ def display(self, logentry):
+ return self.plain.format(user=logentry.parsed_data.get('email'))
+
+
+log_entry_types.register(*TeamMembershipLogEntryType.derive_plains({
+ 'pretix.team.member.added': _('{user} has been added to the team.'),
+ 'pretix.team.member.removed': _('{user} has been removed from the team.'),
+ 'pretix.team.invite.created': _('{user} has been invited to the team.'),
+ 'pretix.team.invite.resent': _('Invite for {user} has been resent.'),
+}))
+
+
+@log_entry_types.register_instance()
+class TeamMemberJoinedLogEntryType(LogEntryType):
+ action_type = 'pretix.team.member.joined'
+
+ def display(self, logentry):
+ return _('{user} has joined the team using the invite sent to {email}.').format(
+ user=logentry.parsed_data.get('email'), email=logentry.parsed_data.get('invite_email')
+ )
+
+
+@log_entry_types.register_instance()
+class UserSettingsChangedLogEntryType(LogEntryType):
+ action_type = 'pretix.user.settings.changed'
+
+ def display(self, logentry):
+ text = str(_('Your account settings have been changed.'))
+ if 'email' in logentry.parsed_data:
+ text = text + ' ' + str(
+ _('Your email address has been changed to {email}.').format(email=logentry.parsed_data['email']))
+ if 'new_pw' in logentry.parsed_data:
+ text = text + ' ' + str(_('Your password has been changed.'))
+ if logentry.parsed_data.get('is_active') is True:
+ text = text + ' ' + str(_('Your account has been enabled.'))
+ elif logentry.parsed_data.get('is_active') is False:
+ text = text + ' ' + str(_('Your account has been disabled.'))
+ return text
+
+
+class UserImpersonatedLogEntryType(LogEntryType):
+ def display(self, logentry):
+ return self.plain.format(logentry.parsed_data['other_email'])
+
+
+log_entry_types.register(*UserImpersonatedLogEntryType.derive_plains({
+ 'pretix.control.auth.user.impersonated': _('You impersonated {}.'),
+ 'pretix.control.auth.user.impersonate_stopped': _('You stopped impersonating {}.'),
+}))
+
+
+log_entry_types.register(*LogEntryType.derive_plains({
+ 'pretix.object.cloned': _('This object has been created by cloning.'),
+ 'pretix.organizer.changed': _('The organizer has been changed.'),
+ 'pretix.organizer.settings': _('The organizer settings have been changed.'),
+ 'pretix.organizer.footerlinks.changed': _('The footer links have been changed.'),
+ 'pretix.organizer.export.schedule.added': _('A scheduled export has been added.'),
+ 'pretix.organizer.export.schedule.changed': _('A scheduled export has been changed.'),
+ 'pretix.organizer.export.schedule.deleted': _('A scheduled export has been deleted.'),
+ 'pretix.organizer.export.schedule.executed': _('A scheduled export has been executed.'),
+ 'pretix.organizer.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
+ 'pretix.giftcards.acceptance.added': _('Gift card acceptance for another organizer has been added.'),
+ 'pretix.giftcards.acceptance.removed': _('Gift card acceptance for another organizer has been removed.'),
+ 'pretix.giftcards.acceptance.acceptor.invited': _('A new gift card acceptor has been invited.'),
+ 'pretix.giftcards.acceptance.acceptor.removed': _('A gift card acceptor has been removed.'),
+ 'pretix.giftcards.acceptance.issuer.removed': _('A gift card issuer has been removed or declined.'),
+ 'pretix.giftcards.acceptance.issuer.accepted': _('A new gift card issuer has been accepted.'),
+ 'pretix.webhook.created': _('The webhook has been created.'),
+ 'pretix.webhook.changed': _('The webhook has been changed.'),
+ 'pretix.webhook.retries.expedited': _('The webhook call retry jobs have been manually expedited.'),
+ 'pretix.webhook.retries.dropped': _('The webhook call retry jobs have been dropped.'),
+ 'pretix.ssoprovider.created': _('The SSO provider has been created.'),
+ 'pretix.ssoprovider.changed': _('The SSO provider has been changed.'),
+ 'pretix.ssoprovider.deleted': _('The SSO provider has been deleted.'),
+ 'pretix.ssoclient.created': _('The SSO client has been created.'),
+ 'pretix.ssoclient.changed': _('The SSO client has been changed.'),
+ 'pretix.ssoclient.deleted': _('The SSO client has been deleted.'),
+ 'pretix.membershiptype.created': _('The membership type has been created.'),
+ 'pretix.membershiptype.changed': _('The membership type has been changed.'),
+ 'pretix.membershiptype.deleted': _('The membership type has been deleted.'),
+ 'pretix.saleschannel.created': _('The sales channel has been created.'),
+ 'pretix.saleschannel.changed': _('The sales channel has been changed.'),
+ 'pretix.saleschannel.deleted': _('The sales channel has been deleted.'),
+ 'pretix.customer.created': _('The account has been created.'),
+ 'pretix.customer.changed': _('The account has been changed.'),
+ 'pretix.customer.membership.created': _('A membership for this account has been added.'),
+ 'pretix.customer.membership.changed': _('A membership of this account has been changed.'),
+ 'pretix.customer.membership.deleted': _('A membership of this account has been deleted.'),
+ 'pretix.customer.anonymized': _('The account has been disabled and anonymized.'),
+ 'pretix.customer.password.resetrequested': _('A new password has been requested.'),
+ 'pretix.customer.password.set': _('A new password has been set.'),
+ 'pretix.reusable_medium.created': _('The reusable medium has been created.'),
+ 'pretix.reusable_medium.created.auto': _('The reusable medium has been created automatically.'),
+ 'pretix.reusable_medium.changed': _('The reusable medium has been changed.'),
+ 'pretix.reusable_medium.linked_orderposition.changed': _('The medium has been connected to a new ticket.'),
+ 'pretix.reusable_medium.linked_giftcard.changed': _('The medium has been connected to a new gift card.'),
+ 'pretix.email.error': _('Sending of an email has failed.'),
+ 'pretix.event.comment': _('The event\'s internal comment has been updated.'),
+ 'pretix.event.canceled': _('The event has been canceled.'),
+ 'pretix.event.deleted': _('An event has been deleted.'),
+ 'pretix.event.shredder.started': _('A removal process for personal data has been started.'),
+ 'pretix.event.shredder.completed': _('A removal process for personal data has been completed.'),
+ 'pretix.event.export.schedule.added': _('A scheduled export has been added.'),
+ 'pretix.event.export.schedule.changed': _('A scheduled export has been changed.'),
+ 'pretix.event.export.schedule.deleted': _('A scheduled export has been deleted.'),
+ 'pretix.event.export.schedule.executed': _('A scheduled export has been executed.'),
+ 'pretix.event.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
+ 'pretix.control.auth.user.created': _('The user has been created.'),
+ 'pretix.control.auth.user.new_source': _('A first login using {agent_type} on {os_type} from {country} has '
+ 'been detected.'),
+ 'pretix.user.settings.2fa.enabled': _('Two-factor authentication has been enabled.'),
+ 'pretix.user.settings.2fa.disabled': _('Two-factor authentication has been disabled.'),
+ 'pretix.user.settings.2fa.regenemergency': _('Your two-factor emergency codes have been regenerated.'),
+ 'pretix.user.settings.2fa.emergency': _('A two-factor emergency code has been generated.'),
+ 'pretix.user.settings.2fa.device.added': _('A new two-factor authentication device "{name}" has been added to '
+ 'your account.'),
+ 'pretix.user.settings.2fa.device.deleted': _('The two-factor authentication device "{name}" has been removed '
+ 'from your account.'),
+ 'pretix.user.settings.notifications.enabled': _('Notifications have been enabled.'),
+ 'pretix.user.settings.notifications.disabled': _('Notifications have been disabled.'),
+ 'pretix.user.settings.notifications.changed': _('Your notification settings have been changed.'),
+ 'pretix.user.anonymized': _('This user has been anonymized.'),
+ 'pretix.user.oauth.authorized': _('The application "{application_name}" has been authorized to access your '
+ 'account.'),
+ 'pretix.control.auth.user.forgot_password.mail_sent': _('Password reset mail sent.'),
+ 'pretix.control.auth.user.forgot_password.recovered': _('The password has been reset.'),
+ 'pretix.control.auth.user.forgot_password.denied.repeated': _('A repeated password reset has been denied, as '
+ 'the last request was less than 24 hours ago.'),
+ 'pretix.organizer.deleted': _('The organizer "{name}" has been deleted.'),
+ 'pretix.waitinglist.voucher': _('A voucher has been sent to a person on the waiting list.'), # legacy
+ 'pretix.event.orders.waitinglist.voucher_assigned': _('A voucher has been sent to a person on the waiting list.'),
+ 'pretix.event.orders.waitinglist.deleted': _('An entry has been removed from the waiting list.'),
+ 'pretix.event.order.waitinglist.transferred': _('An entry has been transferred to another waiting list.'), # legacy
+ 'pretix.event.orders.waitinglist.changed': _('An entry has been changed on the waiting list.'),
+ 'pretix.event.orders.waitinglist.added': _('An entry has been added to the waiting list.'),
+ 'pretix.team.created': _('The team has been created.'),
+ 'pretix.team.changed': _('The team settings have been changed.'),
+ 'pretix.team.deleted': _('The team has been deleted.'),
+ 'pretix.gate.created': _('The gate has been created.'),
+ 'pretix.gate.changed': _('The gate has been changed.'),
+ 'pretix.gate.deleted': _('The gate has been deleted.'),
+ 'pretix.subevent.deleted': pgettext_lazy('subevent', 'The event date has been deleted.'),
+ 'pretix.subevent.canceled': pgettext_lazy('subevent', 'The event date has been canceled.'),
+ 'pretix.subevent.changed': pgettext_lazy('subevent', 'The event date has been changed.'),
+ 'pretix.subevent.added': pgettext_lazy('subevent', 'The event date has been created.'),
+ 'pretix.subevent.quota.added': pgettext_lazy('subevent', 'A quota has been added to the event date.'),
+ 'pretix.subevent.quota.changed': pgettext_lazy('subevent', 'A quota has been changed on the event date.'),
+ 'pretix.subevent.quota.deleted': pgettext_lazy('subevent', 'A quota has been removed from the event date.'),
+ 'pretix.device.created': _('The device has been created.'),
+ 'pretix.device.changed': _('The device has been changed.'),
+ 'pretix.device.revoked': _('Access of the device has been revoked.'),
+ 'pretix.device.initialized': _('The device has been initialized.'),
+ 'pretix.device.keyroll': _('The access token of the device has been regenerated.'),
+ 'pretix.device.updated': _('The device has notified the server of an hardware or software update.'),
+ 'pretix.giftcards.created': _('The gift card has been created.'),
+ 'pretix.giftcards.modified': _('The gift card has been changed.'),
+ 'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'),
+ 'pretix.team.token.created': _('The token "{name}" has been created.'),
+ 'pretix.team.token.deleted': _('The token "{name}" has been revoked.'),
+}))
+
+log_entry_types.register(*EventLogEntryType.derive_plains({
+ 'pretix.event.item_meta_property.added': _('A meta property has been added to this event.'),
+ 'pretix.event.item_meta_property.deleted': _('A meta property has been removed from this event.'),
+ 'pretix.event.item_meta_property.changed': _('A meta property has been changed on this event.'),
+ 'pretix.event.checkinlist.added': _('The check-in list has been added.'),
+ 'pretix.event.checkinlist.deleted': _('The check-in list has been deleted.'),
+ 'pretix.event.checkinlists.deleted': _('The check-in list has been deleted.'), # backwards compatibility
+ 'pretix.event.checkinlist.changed': _('The check-in list has been changed.'),
+ 'pretix.event.settings': _('The event settings have been changed.'),
+ 'pretix.event.tickets.settings': _('The ticket download settings have been changed.'),
+ 'pretix.event.plugins.enabled': _('A plugin has been enabled.'),
+ 'pretix.event.plugins.disabled': _('A plugin has been disabled.'),
+ 'pretix.event.live.activated': _('The shop has been taken live.'),
+ 'pretix.event.live.deactivated': _('The shop has been taken offline.'),
+ 'pretix.event.testmode.activated': _('The shop has been taken into test mode.'),
+ 'pretix.event.testmode.deactivated': _('The test mode has been disabled.'),
+ 'pretix.event.added': _('The event has been created.'),
+ 'pretix.event.changed': _('The event details have been changed.'),
+ 'pretix.event.footerlinks.changed': _('The footer links have been changed.'),
+ 'pretix.event.question.option.added': _('An answer option has been added to the question.'),
+ 'pretix.event.question.option.deleted': _('An answer option has been removed from the question.'),
+ 'pretix.event.question.option.changed': _('An answer option has been changed.'),
+ 'pretix.event.permissions.added': _('A user has been added to the event team.'),
+ 'pretix.event.permissions.invited': _('A user has been invited to the event team.'),
+ 'pretix.event.permissions.changed': _('A user\'s permissions have been changed.'),
+ 'pretix.event.permissions.deleted': _('A user has been removed from the event team.'),
+}))
+
+log_entry_types.register(*ItemLogEntryType.derive_plains({
+ 'pretix.event.item.added': _('The product has been created.'),
+ 'pretix.event.item.changed': _('The product has been changed.'),
+ 'pretix.event.item.reordered': _('The product has been reordered.'),
+ 'pretix.event.item.deleted': _('The product has been deleted.'),
+ 'pretix.event.item.addons.added': _('An add-on has been added to this product.'),
+ 'pretix.event.item.addons.removed': _('An add-on has been removed from this product.'),
+ 'pretix.event.item.addons.changed': _('An add-on has been changed on this product.'),
+ 'pretix.event.item.bundles.added': _('A bundled item has been added to this product.'),
+ 'pretix.event.item.bundles.removed': _('A bundled item has been removed from this product.'),
+ 'pretix.event.item.bundles.changed': _('A bundled item has been changed on this product.'),
+}))
+
+
+class VariationLogEntryType(ItemLogEntryType):
+ def display(self, logentry):
+ if 'value' not in logentry.parsed_data:
+ # Backwards compatibility
+ var = ItemVariation.objects.filter(id=logentry.parsed_data['id']).first()
+ if var:
+ logentry.parsed_data['value'] = str(var.value)
+ else:
+ logentry.parsed_data['value'] = '?'
+ else:
+ logentry.parsed_data['value'] = LazyI18nString(logentry.parsed_data['value'])
+ return super().display(logentry_display)
+
+
+log_entry_types.register(*VariationLogEntryType.derive_plains({
+ 'pretix.event.item.variation.added': _('The variation "{value}" has been created.'),
+ 'pretix.event.item.variation.deleted': _('The variation "{value}" has been deleted.'),
+ 'pretix.event.item.variation.changed': _('The variation "{value}" has been changed.'),
+}))
+
+log_entry_types.register(*OrderLogEntryType.derive_plains({
+ 'pretix.event.order.payment.confirmed': _('Payment {local_id} has been confirmed.'),
+ 'pretix.event.order.payment.canceled': _('Payment {local_id} has been canceled.'),
+ 'pretix.event.order.payment.canceled.failed': _('Canceling payment {local_id} has failed.'),
+ 'pretix.event.order.payment.started': _('Payment {local_id} has been started.'),
+ 'pretix.event.order.payment.failed': _('Payment {local_id} has failed.'),
+ 'pretix.event.order.quotaexceeded': _('The order could not be marked as paid: {message}'),
+ 'pretix.event.order.overpaid': _('The order has been overpaid.'),
+ 'pretix.event.order.refund.created': _('Refund {local_id} has been created.'),
+ 'pretix.event.order.refund.created.externally': _('Refund {local_id} has been created by an external entity.'),
+ 'pretix.event.order.refund.requested': _('The customer requested you to issue a refund.'),
+ 'pretix.event.order.refund.done': _('Refund {local_id} has been completed.'),
+ 'pretix.event.order.refund.canceled': _('Refund {local_id} has been canceled.'),
+ 'pretix.event.order.refund.failed': _('Refund {local_id} has failed.'),
+}))
+
+log_entry_types.register(*QuotaLogEntryType.derive_plains({
+ 'pretix.event.quota.added': _('The quota has been added.'),
+ 'pretix.event.quota.deleted': _('The quota has been deleted.'),
+ 'pretix.event.quota.changed': _('The quota has been changed.'),
+ 'pretix.event.quota.closed': _('The quota has closed.'),
+ 'pretix.event.quota.opened': _('The quota has been re-opened.'),
+}))
+
+log_entry_types.register(*QuestionLogEntryType.derive_plains({
+ 'pretix.event.question.added': _('The question has been added.'),
+ 'pretix.event.question.deleted': _('The question has been deleted.'),
+ 'pretix.event.question.changed': _('The question has been changed.'),
+ 'pretix.event.question.reordered': _('The question has been reordered.'),
+}))
+
+log_entry_types.register(*DiscountLogEntryType.derive_plains({
+ 'pretix.event.discount.added': _('The discount has been added.'),
+ 'pretix.event.discount.deleted': _('The discount has been deleted.'),
+ 'pretix.event.discount.changed': _('The discount has been changed.'),
+}))
+
+
+@log_entry_types.register_instance()
+class LegacyCheckinLogEntryType(OrderLogEntryType):
+ action_type = 'pretix.control.views.checkin'
+
+ def display(self, logentry):
# deprecated
dt = dateutil.parser.parse(logentry.parsed_data.get('datetime'))
- tz = sender.timezone
+ tz = logentry.event.timezone
dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if 'list' in logentry.parsed_data:
try:
- checkin_list = sender.checkin_lists.get(pk=logentry.parsed_data.get('list')).name
+ checkin_list = logentry.event.checkin_lists.get(pk=logentry.parsed_data.get('list')).name
except CheckinList.DoesNotExist:
checkin_list = _("(unknown)")
else:
@@ -662,55 +788,3 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
datetime=dt_formatted,
list=checkin_list
)
-
- if logentry.action_type == 'pretix.team.member.added':
- return _('{user} has been added to the team.').format(user=logentry.parsed_data.get('email'))
-
- if logentry.action_type == 'pretix.team.member.removed':
- return _('{user} has been removed from the team.').format(user=logentry.parsed_data.get('email'))
-
- if logentry.action_type == 'pretix.team.member.joined':
- return _('{user} has joined the team using the invite sent to {email}.').format(
- user=logentry.parsed_data.get('email'), email=logentry.parsed_data.get('invite_email')
- )
-
- if logentry.action_type == 'pretix.team.invite.created':
- return _('{user} has been invited to the team.').format(user=logentry.parsed_data.get('email'))
-
- if logentry.action_type == 'pretix.team.invite.resent':
- return _('Invite for {user} has been resent.').format(user=logentry.parsed_data.get('email'))
-
- if logentry.action_type == 'pretix.team.invite.deleted':
- return _('The invite for {user} has been revoked.').format(user=logentry.parsed_data.get('email'))
-
- if logentry.action_type == 'pretix.team.token.created':
- return _('The token "{name}" has been created.').format(name=logentry.parsed_data.get('name'))
-
- if logentry.action_type == 'pretix.team.token.deleted':
- return _('The token "{name}" has been revoked.').format(name=logentry.parsed_data.get('name'))
-
- if logentry.action_type == 'pretix.user.settings.changed':
- text = str(_('Your account settings have been changed.'))
- if 'email' in logentry.parsed_data:
- text = text + ' ' + str(_('Your email address has been changed to {email}.').format(email=logentry.parsed_data['email']))
- if 'new_pw' in logentry.parsed_data:
- text = text + ' ' + str(_('Your password has been changed.'))
- if logentry.parsed_data.get('is_active') is True:
- text = text + ' ' + str(_('Your account has been enabled.'))
- elif logentry.parsed_data.get('is_active') is False:
- text = text + ' ' + str(_('Your account has been disabled.'))
- return text
-
- if logentry.action_type == 'pretix.control.auth.user.impersonated':
- return str(_('You impersonated {}.')).format(logentry.parsed_data['other_email'])
-
- if logentry.action_type == 'pretix.control.auth.user.impersonate_stopped':
- return str(_('You stopped impersonating {}.')).format(logentry.parsed_data['other_email'])
-
-
-@receiver(signal=orderposition_blocked_display, dispatch_uid="pretixcontrol_orderposition_blocked_display")
-def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, block_name, **kwargs):
- if block_name == 'admin':
- return _('Blocked manually')
- elif block_name.startswith('api:'):
- return _('Blocked because of an API integration')
diff --git a/src/pretix/plugins/badges/signals.py b/src/pretix/plugins/badges/signals.py
index dd315b1d1..c867ae0dc 100644
--- a/src/pretix/plugins/badges/signals.py
+++ b/src/pretix/plugins/badges/signals.py
@@ -26,13 +26,12 @@ from collections import defaultdict
from django.dispatch import receiver
from django.template.loader import get_template
from django.urls import resolve, reverse
-from django.utils.html import escape
from django.utils.translation import gettext_lazy as _
from pretix.base.models import Event, Order
+from pretix.base.models.log import EventLogEntryType, log_entry_types
from pretix.base.signals import (
- event_copy_data, item_copy_data, logentry_display, logentry_object_link,
- register_data_exporters,
+ event_copy_data, item_copy_data, register_data_exporters,
)
from pretix.control.signals import (
item_forms, nav_event, order_info, order_position_buttons,
@@ -173,35 +172,15 @@ def control_order_info(sender: Event, request, order: Order, **kwargs):
return template.render(ctx, request=request)
-@receiver(signal=logentry_display, dispatch_uid="badges_logentry_display")
-def badges_logentry_display(sender, logentry, **kwargs):
- if not logentry.action_type.startswith('pretix.plugins.badges'):
- return
-
- plains = {
- 'pretix.plugins.badges.layout.added': _('Badge layout created.'),
- 'pretix.plugins.badges.layout.deleted': _('Badge layout deleted.'),
- 'pretix.plugins.badges.layout.changed': _('Badge layout changed.'),
- }
-
- if logentry.action_type in plains:
- return plains[logentry.action_type]
+class BadgeLogEntryType(EventLogEntryType):
+ object_type = BadgeLayout
+ object_link_wrapper = _('Badge layout {val}')
+ object_link_viewname = 'plugins:badges:edit'
+ object_link_argname = 'layout'
-@receiver(signal=logentry_object_link, dispatch_uid="badges_logentry_object_link")
-def badges_logentry_object_link(sender, logentry, **kwargs):
- if not logentry.action_type.startswith('pretix.plugins.badges.layout') or not isinstance(logentry.content_object,
- BadgeLayout):
- return
-
- a_text = _('Badge layout {val}')
- a_map = {
- 'href': reverse('plugins:badges:edit', kwargs={
- 'event': sender.slug,
- 'organizer': sender.organizer.slug,
- 'layout': logentry.content_object.id
- }),
- 'val': escape(logentry.content_object.name),
- }
- a_map['val'] = '{val}'.format_map(a_map)
- return a_text.format_map(a_map)
+log_entry_types.register(*BadgeLogEntryType.derive_plains({
+ 'pretix.plugins.badges.layout.added': _('Badge layout created.'),
+ 'pretix.plugins.badges.layout.deleted': _('Badge layout deleted.'),
+ 'pretix.plugins.badges.layout.changed': _('Badge layout changed.'),
+}))
diff --git a/src/pretix/plugins/banktransfer/signals.py b/src/pretix/plugins/banktransfer/signals.py
index 0d8d0aa76..4a4924cd6 100644
--- a/src/pretix/plugins/banktransfer/signals.py
+++ b/src/pretix/plugins/banktransfer/signals.py
@@ -25,7 +25,8 @@ from django.urls import resolve, reverse
from django.utils.translation import gettext_lazy as _, gettext_noop
from i18nfield.strings import LazyI18nString
-from pretix.base.signals import logentry_display, register_payment_providers
+from pretix.base.models.log import OrderLogEntryType, log_entry_types
+from pretix.base.signals import register_payment_providers
from pretix.control.signals import html_head, nav_event, nav_organizer
from ...base.settings import settings_hierarkey
@@ -117,13 +118,10 @@ def html_head_presale(sender, request=None, **kwargs):
return ""
-@receiver(signal=logentry_display)
-def pretixcontrol_logentry_display(sender, logentry, **kwargs):
- plains = {
- 'pretix.plugins.banktransfer.order.email.invoice': _('The invoice was sent to the designated email address.'),
- }
- if logentry.action_type in plains:
- return plains[logentry.action_type]
+@log_entry_types.register_instance()
+class BanktransferOrderEmailInvoiceLogEntryType(OrderLogEntryType):
+ action_type = 'pretix.plugins.banktransfer.order.email.invoice'
+ plain = _('The invoice was sent to the designated email address.')
settings_hierarkey.add_default(
diff --git a/src/pretix/plugins/paypal/signals.py b/src/pretix/plugins/paypal/signals.py
index 3c7d36f50..572a79c81 100644
--- a/src/pretix/plugins/paypal/signals.py
+++ b/src/pretix/plugins/paypal/signals.py
@@ -22,17 +22,10 @@
from django.dispatch import receiver
-from pretix.base.signals import logentry_display, register_payment_providers
+from pretix.base.signals import register_payment_providers
@receiver(register_payment_providers, dispatch_uid="payment_paypal")
def register_payment_provider(sender, **kwargs):
from .payment import Paypal
return Paypal
-
-
-@receiver(signal=logentry_display, dispatch_uid="paypal_logentry_display")
-def pretixcontrol_logentry_display(sender, logentry, **kwargs):
- from pretix.plugins.paypal2.signals import pretixcontrol_logentry_display
-
- return pretixcontrol_logentry_display(sender, logentry, **kwargs)
diff --git a/src/pretix/plugins/paypal2/signals.py b/src/pretix/plugins/paypal2/signals.py
index 50ca242cf..bbb3e5b5d 100644
--- a/src/pretix/plugins/paypal2/signals.py
+++ b/src/pretix/plugins/paypal2/signals.py
@@ -19,7 +19,6 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# .
#
-import json
from collections import OrderedDict
from django import forms
@@ -33,9 +32,10 @@ from django.utils.translation import gettext_lazy as _, pgettext_lazy
from pretix.base.forms import SecretKeySettingsField
from pretix.base.middleware import _merge_csp, _parse_csp, _render_csp
+from pretix.base.models.log import EventLogEntryType
from pretix.base.settings import settings_hierarkey
from pretix.base.signals import (
- logentry_display, register_global_settings, register_payment_providers,
+ register_global_settings, register_payment_providers,
)
from pretix.plugins.paypal2.payment import PaypalMethod
from pretix.presale.signals import html_head, process_response
@@ -47,33 +47,31 @@ def register_payment_provider(sender, **kwargs):
return [PaypalSettingsHolder, PaypalWallet, PaypalAPM]
-@receiver(signal=logentry_display, dispatch_uid="paypal2_logentry_display")
-def pretixcontrol_logentry_display(sender, logentry, **kwargs):
- if logentry.action_type != 'pretix.plugins.paypal.event':
- return
+class PaypalEventLogEntryType(EventLogEntryType):
+ action_type = 'pretix.plugins.paypal.event'
- data = json.loads(logentry.data)
- event_type = data.get('event_type')
- text = None
- plains = {
- 'PAYMENT.SALE.COMPLETED': _('Payment completed.'),
- 'PAYMENT.SALE.DENIED': _('Payment denied.'),
- 'PAYMENT.SALE.REFUNDED': _('Payment refunded.'),
- 'PAYMENT.SALE.REVERSED': _('Payment reversed.'),
- 'PAYMENT.SALE.PENDING': _('Payment pending.'),
- 'CHECKOUT.ORDER.APPROVED': pgettext_lazy('paypal', 'Order approved.'),
- 'CHECKOUT.ORDER.COMPLETED': pgettext_lazy('paypal', 'Order completed.'),
- 'PAYMENT.CAPTURE.COMPLETED': pgettext_lazy('paypal', 'Capture completed.'),
- 'PAYMENT.CAPTURE.PENDING': pgettext_lazy('paypal', 'Capture pending.'),
- }
+ def display(self, logentry):
+ event_type = logentry.parsed_data.get('event_type')
+ text = None
+ plains = {
+ 'PAYMENT.SALE.COMPLETED': _('Payment completed.'),
+ 'PAYMENT.SALE.DENIED': _('Payment denied.'),
+ 'PAYMENT.SALE.REFUNDED': _('Payment refunded.'),
+ 'PAYMENT.SALE.REVERSED': _('Payment reversed.'),
+ 'PAYMENT.SALE.PENDING': _('Payment pending.'),
+ 'CHECKOUT.ORDER.APPROVED': pgettext_lazy('paypal', 'Order approved.'),
+ 'CHECKOUT.ORDER.COMPLETED': pgettext_lazy('paypal', 'Order completed.'),
+ 'PAYMENT.CAPTURE.COMPLETED': pgettext_lazy('paypal', 'Capture completed.'),
+ 'PAYMENT.CAPTURE.PENDING': pgettext_lazy('paypal', 'Capture pending.'),
+ }
- if event_type in plains:
- text = plains[event_type]
- else:
- text = event_type
+ if event_type in plains:
+ text = plains[event_type]
+ else:
+ text = event_type
- if text:
- return _('PayPal reported an event: {}').format(text)
+ if text:
+ return _('PayPal reported an event: {}').format(text)
@receiver(register_global_settings, dispatch_uid='paypal2_global_settings')
diff --git a/src/pretix/plugins/sendmail/signals.py b/src/pretix/plugins/sendmail/signals.py
index 418f2545c..fb71c3eea 100644
--- a/src/pretix/plugins/sendmail/signals.py
+++ b/src/pretix/plugins/sendmail/signals.py
@@ -47,12 +47,15 @@ from django.utils.translation import gettext_lazy as _
from django_scopes import scope, scopes_disabled
from pretix.base.models import SubEvent
+from pretix.base.models.log import (
+ EventLogEntryType, OrderLogEntryType, log_entry_types,
+)
from pretix.base.signals import (
- EventPluginSignal, event_copy_data, logentry_display, periodic_task,
+ EventPluginSignal, event_copy_data, periodic_task,
)
from pretix.control.signals import nav_event
from pretix.helpers import OF_SELF
-from pretix.plugins.sendmail.models import ScheduledMail
+from pretix.plugins.sendmail.models import Rule, ScheduledMail
from pretix.plugins.sendmail.views import OrderSendView, WaitinglistSendView
logger = logging.getLogger(__name__)
@@ -116,21 +119,40 @@ def control_nav_import(sender, request=None, **kwargs):
]
-@receiver(signal=logentry_display)
-def pretixcontrol_logentry_display(sender, logentry, **kwargs):
- plains = {
- 'pretix.plugins.sendmail.sent': _('Mass email was sent to customers or attendees.'),
- 'pretix.plugins.sendmail.sent.waitinglist': _('Mass email was sent to waiting list entries.'),
- 'pretix.plugins.sendmail.order.email.sent': _('The order received a mass email.'),
- 'pretix.plugins.sendmail.order.email.sent.attendee': _('A ticket holder of this order received a mass email.'),
- 'pretix.plugins.sendmail.rule.added': _('An email rule was created'),
- 'pretix.plugins.sendmail.rule.changed': _('An email rule was updated'),
- 'pretix.plugins.sendmail.rule.order.email.sent': _('A scheduled email was sent to the order'),
- 'pretix.plugins.sendmail.rule.order.position.email.sent': _('A scheduled email was sent to a ticket holder'),
- 'pretix.plugins.sendmail.rule.deleted': _('An email rule was deleted'),
- }
- if logentry.action_type in plains:
- return plains[logentry.action_type]
+class SendmailPluginLogEntryType(EventLogEntryType):
+ pass
+
+
+log_entry_types.register(*SendmailPluginLogEntryType.derive_plains({
+ 'pretix.plugins.sendmail.sent': _('Mass email was sent to customers or attendees.'),
+ 'pretix.plugins.sendmail.sent.waitinglist': _('Mass email was sent to waiting list entries.'),
+}))
+
+
+class SendmailPluginOrderLogEntryType(OrderLogEntryType):
+ pass
+
+
+log_entry_types.register(*SendmailPluginOrderLogEntryType.derive_plains({
+ 'pretix.plugins.sendmail.order.email.sent': _('The order received a mass email.'),
+ 'pretix.plugins.sendmail.order.email.sent.attendee': _('A ticket holder of this order received a mass email.'),
+}))
+
+
+class SendmailPluginRuleLogEntryType(EventLogEntryType):
+ object_type = Rule
+ object_link_wrapper = _('Mail rule {val}')
+ object_link_viewname = 'plugins:sendmail:rule.update'
+ object_link_argname = 'rule'
+
+
+log_entry_types.register(*SendmailPluginRuleLogEntryType.derive_plains({
+ 'pretix.plugins.sendmail.rule.added': _('An email rule was created'),
+ 'pretix.plugins.sendmail.rule.changed': _('An email rule was updated'),
+ 'pretix.plugins.sendmail.rule.order.email.sent': _('A scheduled email was sent to the order'),
+ 'pretix.plugins.sendmail.rule.order.position.email.sent': _('A scheduled email was sent to a ticket holder'),
+ 'pretix.plugins.sendmail.rule.deleted': _('An email rule was deleted'),
+}))
@receiver(periodic_task)
diff --git a/src/pretix/plugins/ticketoutputpdf/signals.py b/src/pretix/plugins/ticketoutputpdf/signals.py
index eb1d377a9..a6c54ea1e 100644
--- a/src/pretix/plugins/ticketoutputpdf/signals.py
+++ b/src/pretix/plugins/ticketoutputpdf/signals.py
@@ -24,11 +24,10 @@ import json
from django.dispatch import receiver
from django.template.loader import get_template
-from django.urls import reverse
-from django.utils.html import escape
from django.utils.translation import gettext_lazy as _
from pretix.base.models import Event, SalesChannel
+from pretix.base.models.log import EventLogEntryType, log_entry_types
from pretix.base.signals import ( # NOQA: legacy import
EventPluginSignal, event_copy_data, item_copy_data, layout_text_variables,
logentry_display, logentry_object_link, register_data_exporters,
@@ -134,38 +133,18 @@ def pdf_event_copy_data_receiver(sender, other, item_map, question_map, **kwargs
return layout_map
-@receiver(signal=logentry_display, dispatch_uid="pretix_ticketoutputpdf_logentry_display")
-def pdf_logentry_display(sender, logentry, **kwargs):
- if not logentry.action_type.startswith('pretix.plugins.ticketoutputpdf'):
- return
-
- plains = {
- 'pretix.plugins.ticketoutputpdf.layout.added': _('Ticket layout created.'),
- 'pretix.plugins.ticketoutputpdf.layout.deleted': _('Ticket layout deleted.'),
- 'pretix.plugins.ticketoutputpdf.layout.changed': _('Ticket layout changed.'),
- }
-
- if logentry.action_type in plains:
- return plains[logentry.action_type]
+class PdfTicketLayoutLogEntryType(EventLogEntryType):
+ object_type = TicketLayout
+ object_link_wrapper = _('Ticket layout {val}')
+ object_link_viewname = 'plugins:ticketoutputpdf:edit'
+ object_link_argname = 'layout'
-@receiver(signal=logentry_object_link, dispatch_uid="pretix_ticketoutputpdf_logentry_object_link")
-def pdf_logentry_object_link(sender, logentry, **kwargs):
- if not logentry.action_type.startswith('pretix.plugins.ticketoutputpdf.layout') or not isinstance(
- logentry.content_object, TicketLayout):
- return
-
- a_text = _('Ticket layout {val}')
- a_map = {
- 'href': reverse('plugins:ticketoutputpdf:edit', kwargs={
- 'event': sender.slug,
- 'organizer': sender.organizer.slug,
- 'layout': logentry.content_object.id
- }),
- 'val': escape(logentry.content_object.name),
- }
- a_map['val'] = '{val}'.format_map(a_map)
- return a_text.format_map(a_map)
+log_entry_types.register(*PdfTicketLayoutLogEntryType.derive_plains({
+ 'pretix.plugins.ticketoutputpdf.layout.added': _('Ticket layout created.'),
+ 'pretix.plugins.ticketoutputpdf.layout.deleted': _('Ticket layout deleted.'),
+ 'pretix.plugins.ticketoutputpdf.layout.changed': _('Ticket layout changed.'),
+}))
def _ticket_layouts_for_item(request, item):