forked from CGM_Public/pretix_original
store plugin name for registered types
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
# License for the specific language governing permissions and limitations under the License.
|
# License for the specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
@@ -43,7 +44,7 @@ from django.utils.functional import cached_property
|
|||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||||
|
|
||||||
from pretix.base.signals import logentry_object_link
|
from pretix.base.signals import logentry_object_link, EventPluginRegistry
|
||||||
|
|
||||||
|
|
||||||
class VisibleOnlyManager(models.Manager):
|
class VisibleOnlyManager(models.Manager):
|
||||||
@@ -51,6 +52,27 @@ class VisibleOnlyManager(models.Manager):
|
|||||||
return super().get_queryset().filter(visible=True)
|
return super().get_queryset().filter(visible=True)
|
||||||
|
|
||||||
|
|
||||||
|
def make_link(a_map, wrapper, is_active=True, event=None):
|
||||||
|
if a_map:
|
||||||
|
if is_active:
|
||||||
|
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
|
||||||
|
elif event:
|
||||||
|
a_map['val'] = '<i>{val}</i> <a href="{plugin_href}"><span data-tooltip title="{errmes}" class="fa fa-warning fa-fw"></span></a>'.format_map({
|
||||||
|
**a_map,
|
||||||
|
"errmes": _("The relevant plugin is currently not active. To activate it, click here to go to the plugin settings."),
|
||||||
|
"plugin_href": reverse('control:event.settings.plugins', kwargs={
|
||||||
|
'organizer': event.organizer.slug,
|
||||||
|
'event': event.slug,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
a_map['val'] = '<i>{val}</i> <span data-tooltip title="{errmes}" class="fa fa-warning fa-fw"></span>'.format_map({
|
||||||
|
**a_map,
|
||||||
|
"errmes": _("The relevant plugin is currently not active."),
|
||||||
|
})
|
||||||
|
return wrapper.format_map(a_map)
|
||||||
|
|
||||||
|
|
||||||
class LogEntry(models.Model):
|
class LogEntry(models.Model):
|
||||||
"""
|
"""
|
||||||
Represents a change or action that has been performed on another object
|
Represents a change or action that has been performed on another object
|
||||||
@@ -93,7 +115,7 @@ class LogEntry(models.Model):
|
|||||||
indexes = [models.Index(fields=["datetime", "id"])]
|
indexes = [models.Index(fields=["datetime", "id"])]
|
||||||
|
|
||||||
def display(self):
|
def display(self):
|
||||||
log_entry_type = log_entry_types.find(action_type=self.action_type)
|
log_entry_type, meta = log_entry_types.find(action_type=self.action_type)
|
||||||
if log_entry_type:
|
if log_entry_type:
|
||||||
return log_entry_type.display(self)
|
return log_entry_type.display(self)
|
||||||
|
|
||||||
@@ -142,92 +164,19 @@ class LogEntry(models.Model):
|
|||||||
co = self.content_object
|
co = self.content_object
|
||||||
except:
|
except:
|
||||||
return ''
|
return ''
|
||||||
a_map = None
|
|
||||||
a_text = None
|
|
||||||
|
|
||||||
if isinstance(co, Order):
|
log_entry_type, meta = log_entry_types.find(action_type=self.action_type)
|
||||||
a_text = _('Order {val}')
|
if log_entry_type:
|
||||||
a_map = {
|
return log_entry_type.get_object_link(self, is_active=meta['plugin'] == 'CORE' or (meta['plugin'] and meta['plugin'] in self.event.get_plugins()))
|
||||||
'href': reverse('control:event.order', kwargs={
|
|
||||||
'event': self.event.slug,
|
|
||||||
'organizer': self.event.organizer.slug,
|
|
||||||
'code': co.code
|
|
||||||
}),
|
|
||||||
'val': escape(co.code),
|
|
||||||
}
|
|
||||||
elif isinstance(co, Voucher):
|
|
||||||
a_text = _('Voucher {val}…')
|
|
||||||
a_map = {
|
|
||||||
'href': reverse('control:event.voucher', kwargs={
|
|
||||||
'event': self.event.slug,
|
|
||||||
'organizer': self.event.organizer.slug,
|
|
||||||
'voucher': co.id
|
|
||||||
}),
|
|
||||||
'val': escape(co.code[:6]),
|
|
||||||
}
|
|
||||||
elif isinstance(co, Item):
|
|
||||||
a_text = _('Product {val}')
|
|
||||||
a_map = {
|
|
||||||
'href': reverse('control:event.item', kwargs={
|
|
||||||
'event': self.event.slug,
|
|
||||||
'organizer': self.event.organizer.slug,
|
|
||||||
'item': co.id
|
|
||||||
}),
|
|
||||||
'val': escape(co.name),
|
|
||||||
}
|
|
||||||
elif isinstance(co, SubEvent):
|
|
||||||
a_text = pgettext_lazy('subevent', 'Date {val}')
|
|
||||||
a_map = {
|
|
||||||
'href': reverse('control:event.subevent', kwargs={
|
|
||||||
'event': self.event.slug,
|
|
||||||
'organizer': self.event.organizer.slug,
|
|
||||||
'subevent': co.id
|
|
||||||
}),
|
|
||||||
'val': escape(str(co))
|
|
||||||
}
|
|
||||||
elif isinstance(co, Quota):
|
|
||||||
a_text = _('Quota {val}')
|
|
||||||
a_map = {
|
|
||||||
'href': reverse('control:event.items.quotas.show', kwargs={
|
|
||||||
'event': self.event.slug,
|
|
||||||
'organizer': self.event.organizer.slug,
|
|
||||||
'quota': co.id
|
|
||||||
}),
|
|
||||||
'val': escape(co.name),
|
|
||||||
}
|
|
||||||
elif isinstance(co, Discount):
|
|
||||||
a_text = _('Discount {val}')
|
|
||||||
a_map = {
|
|
||||||
'href': reverse('control:event.items.discounts.edit', kwargs={
|
|
||||||
'event': self.event.slug,
|
|
||||||
'organizer': self.event.organizer.slug,
|
|
||||||
'discount': co.id
|
|
||||||
}),
|
|
||||||
'val': escape(co.internal_name),
|
|
||||||
}
|
|
||||||
elif isinstance(co, Question):
|
|
||||||
a_text = _('Question {val}')
|
|
||||||
a_map = {
|
|
||||||
'href': reverse('control:event.items.questions.show', kwargs={
|
|
||||||
'event': self.event.slug,
|
|
||||||
'organizer': self.event.organizer.slug,
|
|
||||||
'question': co.id
|
|
||||||
}),
|
|
||||||
'val': escape(co.question),
|
|
||||||
}
|
|
||||||
|
|
||||||
if a_text and a_map:
|
for receiver, response in logentry_object_link.send(self.event, logentry=self):
|
||||||
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
|
if response:
|
||||||
return a_text.format_map(a_map)
|
return response
|
||||||
else:
|
|
||||||
log_entry_type = log_entry_types.find(action_type=self.action_type)
|
|
||||||
if log_entry_type:
|
|
||||||
return log_entry_type.get_object_link(self)
|
|
||||||
|
|
||||||
for receiver, response in logentry_object_link.send(self.event, logentry=self):
|
if isinstance(co, (Order, Voucher, Item, SubEvent, Quota, Discount, Question)):
|
||||||
if response:
|
logging.warning("LogEntryType missing or ill-defined: %s", self.action_type)
|
||||||
return response
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def parsed_data(self):
|
def parsed_data(self):
|
||||||
@@ -250,33 +199,23 @@ class LogEntry(models.Model):
|
|||||||
notify_webhooks.apply_async(args=(to_wh,))
|
notify_webhooks.apply_async(args=(to_wh,))
|
||||||
|
|
||||||
|
|
||||||
class Registry:
|
class LogEntryTypeRegistry(EventPluginRegistry):
|
||||||
def __init__(self, keys):
|
def new_from_dict(self, data):
|
||||||
self.registered_items = list()
|
|
||||||
self.keys = keys
|
|
||||||
self.by_key = {key: {} for key in self.keys.keys()}
|
|
||||||
|
|
||||||
def register(self, *objs):
|
|
||||||
for obj in objs:
|
|
||||||
self.registered_items.append(obj)
|
|
||||||
for key, accessor in self.keys.items():
|
|
||||||
self.by_key[key][accessor(obj)] = obj
|
|
||||||
|
|
||||||
def register_instance(self, *args, **kwargs):
|
|
||||||
def reg(clz):
|
def reg(clz):
|
||||||
obj = clz(*args, **kwargs)
|
for action_type, plain in data.items():
|
||||||
self.register(obj)
|
self.register(clz(action_type=action_type, plain=plain))
|
||||||
return reg
|
return reg
|
||||||
|
|
||||||
def find(self, **kwargs):
|
|
||||||
(key, value), = kwargs.items()
|
|
||||||
return self.by_key.get(key).get(value)
|
|
||||||
|
|
||||||
|
log_entry_types = LogEntryTypeRegistry({'action_type': lambda o: getattr(o, 'action_type')})
|
||||||
log_entry_types = Registry({'action_type': lambda o: getattr(o, 'action_type')})
|
|
||||||
|
|
||||||
|
|
||||||
class LogEntryType:
|
class LogEntryType:
|
||||||
|
def __init__(self, action_type=None, plain=None):
|
||||||
|
assert self.__module__ != LogEntryType.__module__ # must not instantiate base classes, only derived ones
|
||||||
|
if action_type: self.action_type = action_type
|
||||||
|
if plain: self.plain = plain
|
||||||
|
|
||||||
def display(self, logentry):
|
def display(self, logentry):
|
||||||
if hasattr(self, 'plain'):
|
if hasattr(self, 'plain'):
|
||||||
plain = str(self.plain)
|
plain = str(self.plain)
|
||||||
@@ -289,25 +228,15 @@ class LogEntryType:
|
|||||||
def get_object_link_info(self, logentry) -> dict:
|
def get_object_link_info(self, logentry) -> dict:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_object_link(self, logentry):
|
def get_object_link(self, logentry, is_active):
|
||||||
a_map = self.get_object_link_info(logentry)
|
a_map = self.get_object_link_info(logentry)
|
||||||
if a_map:
|
return make_link(a_map, self.object_link_wrapper, is_active, logentry.event)
|
||||||
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
|
|
||||||
return self.object_link_wrapper.format_map(a_map)
|
|
||||||
|
|
||||||
object_link_wrapper = '{val}'
|
object_link_wrapper = '{val}'
|
||||||
|
|
||||||
def shred_pii(self, logentry):
|
def shred_pii(self, logentry):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def derive_plains(cls, plains):
|
|
||||||
for action_type, plain_display in plains.items():
|
|
||||||
obj = cls()
|
|
||||||
obj.action_type = action_type
|
|
||||||
obj.plain = plain_display
|
|
||||||
yield obj
|
|
||||||
|
|
||||||
|
|
||||||
class EventLogEntryType(LogEntryType):
|
class EventLogEntryType(LogEntryType):
|
||||||
def get_object_link_info(self, logentry) -> dict:
|
def get_object_link_info(self, logentry) -> dict:
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
# License for the specific language governing permissions and limitations under the License.
|
# License for the specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
from typing import Any, Callable, List, Tuple
|
from typing import Any, Callable, List, Tuple, Optional
|
||||||
|
|
||||||
import django.dispatch
|
import django.dispatch
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
@@ -64,23 +64,10 @@ class EventPluginSignal(django.dispatch.Signal):
|
|||||||
# Send to all events!
|
# Send to all events!
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# If sentry packed this in a wrapper, unpack that
|
name, app = get_defining_app(receiver)
|
||||||
if "sentry" in receiver.__module__:
|
if app == 'CORE':
|
||||||
receiver = receiver.__wrapped__
|
|
||||||
|
|
||||||
# Find the Django application this belongs to
|
|
||||||
searchpath = receiver.__module__
|
|
||||||
|
|
||||||
# Core modules are always active
|
|
||||||
if any(searchpath.startswith(cm) for cm in settings.CORE_MODULES):
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
while True:
|
|
||||||
app = app_cache.get(searchpath)
|
|
||||||
if "." not in searchpath or app:
|
|
||||||
break
|
|
||||||
searchpath, _ = searchpath.rsplit(".", 1)
|
|
||||||
|
|
||||||
# Only fire receivers from active plugins and core modules
|
# Only fire receivers from active plugins and core modules
|
||||||
excluded = settings.PRETIX_PLUGINS_EXCLUDE
|
excluded = settings.PRETIX_PLUGINS_EXCLUDE
|
||||||
if sender and app and app.name in sender.get_plugins() and app.name not in excluded:
|
if sender and app and app.name in sender.get_plugins() and app.name not in excluded:
|
||||||
@@ -204,6 +191,60 @@ class DeprecatedSignal(django.dispatch.Signal):
|
|||||||
super().connect(receiver, sender=None, weak=True, dispatch_uid=None)
|
super().connect(receiver, sender=None, weak=True, dispatch_uid=None)
|
||||||
|
|
||||||
|
|
||||||
|
class Registry:
|
||||||
|
def __init__(self, keys):
|
||||||
|
self.registered_items = list()
|
||||||
|
self.keys = keys
|
||||||
|
self.by_key = {key: {} for key in self.keys.keys()}
|
||||||
|
|
||||||
|
def register(self, *objs):
|
||||||
|
for obj in objs:
|
||||||
|
meta = {k: accessor(obj) for k, accessor in self.keys.items()}
|
||||||
|
tup = (obj, meta)
|
||||||
|
for key, accessor in self.keys.items():
|
||||||
|
self.by_key[key][accessor(obj)] = tup
|
||||||
|
self.registered_items.append(tup)
|
||||||
|
|
||||||
|
def new(self, *args, **kwargs):
|
||||||
|
def reg(clz):
|
||||||
|
obj = clz(*args, **kwargs)
|
||||||
|
self.register(obj)
|
||||||
|
return clz
|
||||||
|
return reg
|
||||||
|
|
||||||
|
def find(self, **kwargs):
|
||||||
|
(key, value), = kwargs.items()
|
||||||
|
return self.by_key.get(key).get(value, (None, None))
|
||||||
|
|
||||||
|
|
||||||
|
def get_defining_app(o) -> Tuple[Optional[str], Optional["django.apps.AppConfig"]]:
|
||||||
|
# If sentry packed this in a wrapper, unpack that
|
||||||
|
if "sentry" in o.__module__:
|
||||||
|
o = o.__wrapped__
|
||||||
|
|
||||||
|
# Find the Django application this belongs to
|
||||||
|
searchpath = o.__module__
|
||||||
|
|
||||||
|
# Core modules are always active
|
||||||
|
if any(searchpath.startswith(cm) for cm in settings.CORE_MODULES):
|
||||||
|
return 'CORE', 'CORE'
|
||||||
|
|
||||||
|
if not app_cache:
|
||||||
|
_populate_app_cache()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
app = app_cache.get(searchpath)
|
||||||
|
if "." not in searchpath or app:
|
||||||
|
break
|
||||||
|
searchpath, _ = searchpath.rsplit(".", 1)
|
||||||
|
return app and app.name, app
|
||||||
|
|
||||||
|
|
||||||
|
class EventPluginRegistry(Registry):
|
||||||
|
def __init__(self, keys):
|
||||||
|
super().__init__({"plugin": lambda o: get_defining_app(o)[0], **keys})
|
||||||
|
|
||||||
|
|
||||||
event_live_issues = EventPluginSignal()
|
event_live_issues = EventPluginSignal()
|
||||||
"""
|
"""
|
||||||
This signal is sent out to determine whether an event can be taken live. If you want to
|
This signal is sent out to determine whether an event can be taken live. If you want to
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, bl
|
|||||||
return _('Blocked because of an API integration')
|
return _('Blocked because of an API integration')
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*OrderLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.order.modified': _('The order details have been changed.'),
|
'pretix.event.order.modified': _('The order details have been changed.'),
|
||||||
'pretix.event.order.unpaid': _('The order has been marked as unpaid.'),
|
'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.secret.changed': _('The order\'s secret has been changed.'),
|
||||||
@@ -451,10 +451,12 @@ log_entry_types.register(*OrderLogEntryType.derive_plains({
|
|||||||
'approval.'),
|
'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.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.email.payment_failed': _('An email has been sent to notify the user that the payment failed.'),
|
||||||
}))
|
})
|
||||||
|
class CoreOrderLogEntryType(OrderLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*VoucherLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.voucher.added': _('The voucher has been created.'),
|
'pretix.voucher.added': _('The voucher has been created.'),
|
||||||
'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
|
'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.added.waitinglist': _('The voucher has been created and sent to a person on the waiting list.'),
|
||||||
@@ -462,10 +464,12 @@ log_entry_types.register(*VoucherLogEntryType.derive_plains({
|
|||||||
'The voucher has been set to expire because the recipient removed themselves from the waiting list.'),
|
'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.changed': _('The voucher has been changed.'),
|
||||||
'pretix.voucher.deleted': _('The voucher has been deleted.'),
|
'pretix.voucher.deleted': _('The voucher has been deleted.'),
|
||||||
}))
|
})
|
||||||
|
class CoreVoucherLogEntryType(VoucherLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@log_entry_types.register_instance()
|
@log_entry_types.new()
|
||||||
class VoucherRedeemedLogEntryType(VoucherLogEntryType):
|
class VoucherRedeemedLogEntryType(VoucherLogEntryType):
|
||||||
action_type = 'pretix.voucher.redeemed'
|
action_type = 'pretix.voucher.redeemed'
|
||||||
plain = _('The voucher has been redeemed in order {order_code}.')
|
plain = _('The voucher has been redeemed in order {order_code}.')
|
||||||
@@ -483,19 +487,23 @@ class VoucherRedeemedLogEntryType(VoucherLogEntryType):
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*ItemCategoryLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.category.added': _('The category has been added.'),
|
'pretix.event.category.added': _('The category has been added.'),
|
||||||
'pretix.event.category.deleted': _('The category has been deleted.'),
|
'pretix.event.category.deleted': _('The category has been deleted.'),
|
||||||
'pretix.event.category.changed': _('The category has been changed.'),
|
'pretix.event.category.changed': _('The category has been changed.'),
|
||||||
'pretix.event.category.reordered': _('The category has been reordered.'),
|
'pretix.event.category.reordered': _('The category has been reordered.'),
|
||||||
}))
|
})
|
||||||
|
class CoreItemCategoryLogEntryType(ItemCategoryLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*TaxRuleLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.taxrule.added': _('The tax rule has been added.'),
|
'pretix.event.taxrule.added': _('The tax rule has been added.'),
|
||||||
'pretix.event.taxrule.deleted': _('The tax rule has been deleted.'),
|
'pretix.event.taxrule.deleted': _('The tax rule has been deleted.'),
|
||||||
'pretix.event.taxrule.changed': _('The tax rule has been changed.'),
|
'pretix.event.taxrule.changed': _('The tax rule has been changed.'),
|
||||||
}))
|
})
|
||||||
|
class CoreTaxRuleLogEntryType(TaxRuleLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TeamMembershipLogEntryType(LogEntryType):
|
class TeamMembershipLogEntryType(LogEntryType):
|
||||||
@@ -503,15 +511,17 @@ class TeamMembershipLogEntryType(LogEntryType):
|
|||||||
return self.plain.format(user=logentry.parsed_data.get('email'))
|
return self.plain.format(user=logentry.parsed_data.get('email'))
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*TeamMembershipLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.team.member.added': _('{user} has been added to the team.'),
|
'pretix.team.member.added': _('{user} has been added to the team.'),
|
||||||
'pretix.team.member.removed': _('{user} has been removed from 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.created': _('{user} has been invited to the team.'),
|
||||||
'pretix.team.invite.resent': _('Invite for {user} has been resent.'),
|
'pretix.team.invite.resent': _('Invite for {user} has been resent.'),
|
||||||
}))
|
})
|
||||||
|
class CoreTeamMembershipLogEntryType(TeamMembershipLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@log_entry_types.register_instance()
|
@log_entry_types.new()
|
||||||
class TeamMemberJoinedLogEntryType(LogEntryType):
|
class TeamMemberJoinedLogEntryType(LogEntryType):
|
||||||
action_type = 'pretix.team.member.joined'
|
action_type = 'pretix.team.member.joined'
|
||||||
|
|
||||||
@@ -521,7 +531,7 @@ class TeamMemberJoinedLogEntryType(LogEntryType):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@log_entry_types.register_instance()
|
@log_entry_types.new()
|
||||||
class UserSettingsChangedLogEntryType(LogEntryType):
|
class UserSettingsChangedLogEntryType(LogEntryType):
|
||||||
action_type = 'pretix.user.settings.changed'
|
action_type = 'pretix.user.settings.changed'
|
||||||
|
|
||||||
@@ -544,13 +554,15 @@ class UserImpersonatedLogEntryType(LogEntryType):
|
|||||||
return self.plain.format(logentry.parsed_data['other_email'])
|
return self.plain.format(logentry.parsed_data['other_email'])
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*UserImpersonatedLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.control.auth.user.impersonated': _('You impersonated {}.'),
|
'pretix.control.auth.user.impersonated': _('You impersonated {}.'),
|
||||||
'pretix.control.auth.user.impersonate_stopped': _('You stopped impersonating {}.'),
|
'pretix.control.auth.user.impersonate_stopped': _('You stopped impersonating {}.'),
|
||||||
}))
|
})
|
||||||
|
class CoreUserImpersonatedLogEntryType(UserImpersonatedLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*LogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.object.cloned': _('This object has been created by cloning.'),
|
'pretix.object.cloned': _('This object has been created by cloning.'),
|
||||||
'pretix.organizer.changed': _('The organizer has been changed.'),
|
'pretix.organizer.changed': _('The organizer has been changed.'),
|
||||||
'pretix.organizer.settings': _('The organizer settings have been changed.'),
|
'pretix.organizer.settings': _('The organizer settings have been changed.'),
|
||||||
@@ -658,9 +670,11 @@ log_entry_types.register(*LogEntryType.derive_plains({
|
|||||||
'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'),
|
'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'),
|
||||||
'pretix.team.token.created': _('The token "{name}" has been created.'),
|
'pretix.team.token.created': _('The token "{name}" has been created.'),
|
||||||
'pretix.team.token.deleted': _('The token "{name}" has been revoked.'),
|
'pretix.team.token.deleted': _('The token "{name}" has been revoked.'),
|
||||||
}))
|
})
|
||||||
|
class CoreLogEntryType(LogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
log_entry_types.register(*EventLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.item_meta_property.added': _('A meta property has been added to this event.'),
|
'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.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.item_meta_property.changed': _('A meta property has been changed on this event.'),
|
||||||
@@ -686,9 +700,11 @@ log_entry_types.register(*EventLogEntryType.derive_plains({
|
|||||||
'pretix.event.permissions.invited': _('A user has been invited 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.changed': _('A user\'s permissions have been changed.'),
|
||||||
'pretix.event.permissions.deleted': _('A user has been removed from the event team.'),
|
'pretix.event.permissions.deleted': _('A user has been removed from the event team.'),
|
||||||
}))
|
})
|
||||||
|
class CoreEventLogEntryType(EventLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
log_entry_types.register(*ItemLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.item.added': _('The product has been created.'),
|
'pretix.event.item.added': _('The product has been created.'),
|
||||||
'pretix.event.item.changed': _('The product has been changed.'),
|
'pretix.event.item.changed': _('The product has been changed.'),
|
||||||
'pretix.event.item.reordered': _('The product has been reordered.'),
|
'pretix.event.item.reordered': _('The product has been reordered.'),
|
||||||
@@ -699,9 +715,16 @@ log_entry_types.register(*ItemLogEntryType.derive_plains({
|
|||||||
'pretix.event.item.bundles.added': _('A bundled item has been added to 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.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.bundles.changed': _('A bundled item has been changed on this product.'),
|
||||||
}))
|
})
|
||||||
|
class CoreItemLogEntryType(ItemLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@log_entry_types.new_from_dict({
|
||||||
|
'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.'),
|
||||||
|
})
|
||||||
class VariationLogEntryType(ItemLogEntryType):
|
class VariationLogEntryType(ItemLogEntryType):
|
||||||
def display(self, logentry):
|
def display(self, logentry):
|
||||||
if 'value' not in logentry.parsed_data:
|
if 'value' not in logentry.parsed_data:
|
||||||
@@ -716,13 +739,7 @@ class VariationLogEntryType(ItemLogEntryType):
|
|||||||
return super().display(logentry_display)
|
return super().display(logentry_display)
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*VariationLogEntryType.derive_plains({
|
@log_entry_types.new_from_dict({
|
||||||
'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.confirmed': _('Payment {local_id} has been confirmed.'),
|
||||||
'pretix.event.order.payment.canceled': _('Payment {local_id} has been canceled.'),
|
'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.canceled.failed': _('Canceling payment {local_id} has failed.'),
|
||||||
@@ -736,31 +753,42 @@ log_entry_types.register(*OrderLogEntryType.derive_plains({
|
|||||||
'pretix.event.order.refund.done': _('Refund {local_id} has been completed.'),
|
'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.canceled': _('Refund {local_id} has been canceled.'),
|
||||||
'pretix.event.order.refund.failed': _('Refund {local_id} has failed.'),
|
'pretix.event.order.refund.failed': _('Refund {local_id} has failed.'),
|
||||||
}))
|
})
|
||||||
|
class CoreOrderLogEntryType(OrderLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
log_entry_types.register(*QuotaLogEntryType.derive_plains({
|
|
||||||
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.quota.added': _('The quota has been added.'),
|
'pretix.event.quota.added': _('The quota has been added.'),
|
||||||
'pretix.event.quota.deleted': _('The quota has been deleted.'),
|
'pretix.event.quota.deleted': _('The quota has been deleted.'),
|
||||||
'pretix.event.quota.changed': _('The quota has been changed.'),
|
'pretix.event.quota.changed': _('The quota has been changed.'),
|
||||||
'pretix.event.quota.closed': _('The quota has closed.'),
|
'pretix.event.quota.closed': _('The quota has closed.'),
|
||||||
'pretix.event.quota.opened': _('The quota has been re-opened.'),
|
'pretix.event.quota.opened': _('The quota has been re-opened.'),
|
||||||
}))
|
})
|
||||||
|
class CoreQuotaLogEntryType(QuotaLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
log_entry_types.register(*QuestionLogEntryType.derive_plains({
|
|
||||||
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.question.added': _('The question has been added.'),
|
'pretix.event.question.added': _('The question has been added.'),
|
||||||
'pretix.event.question.deleted': _('The question has been deleted.'),
|
'pretix.event.question.deleted': _('The question has been deleted.'),
|
||||||
'pretix.event.question.changed': _('The question has been changed.'),
|
'pretix.event.question.changed': _('The question has been changed.'),
|
||||||
'pretix.event.question.reordered': _('The question has been reordered.'),
|
'pretix.event.question.reordered': _('The question has been reordered.'),
|
||||||
}))
|
})
|
||||||
|
class CoreQuestionLogEntryType(QuestionLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
log_entry_types.register(*DiscountLogEntryType.derive_plains({
|
|
||||||
|
@log_entry_types.new_from_dict({
|
||||||
'pretix.event.discount.added': _('The discount has been added.'),
|
'pretix.event.discount.added': _('The discount has been added.'),
|
||||||
'pretix.event.discount.deleted': _('The discount has been deleted.'),
|
'pretix.event.discount.deleted': _('The discount has been deleted.'),
|
||||||
'pretix.event.discount.changed': _('The discount has been changed.'),
|
'pretix.event.discount.changed': _('The discount has been changed.'),
|
||||||
}))
|
})
|
||||||
|
class CoreDiscountLogEntryType(DiscountLogEntryType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@log_entry_types.register_instance()
|
@log_entry_types.new()
|
||||||
class LegacyCheckinLogEntryType(OrderLogEntryType):
|
class LegacyCheckinLogEntryType(OrderLogEntryType):
|
||||||
action_type = 'pretix.control.views.checkin'
|
action_type = 'pretix.control.views.checkin'
|
||||||
|
|
||||||
|
|||||||
@@ -172,15 +172,13 @@ def control_order_info(sender: Event, request, order: Order, **kwargs):
|
|||||||
return template.render(ctx, request=request)
|
return template.render(ctx, request=request)
|
||||||
|
|
||||||
|
|
||||||
|
@log_entry_types.new_from_dict({
|
||||||
|
'pretix.plugins.badges.layout.added': _('Badge layout created.'),
|
||||||
|
'pretix.plugins.badges.layout.deleted': _('Badge layout deleted.'),
|
||||||
|
'pretix.plugins.badges.layout.changed': _('Badge layout changed.'),
|
||||||
|
})
|
||||||
class BadgeLogEntryType(EventLogEntryType):
|
class BadgeLogEntryType(EventLogEntryType):
|
||||||
object_type = BadgeLayout
|
object_type = BadgeLayout
|
||||||
object_link_wrapper = _('Badge layout {val}')
|
object_link_wrapper = _('Badge layout {val}')
|
||||||
object_link_viewname = 'plugins:badges:edit'
|
object_link_viewname = 'plugins:badges:edit'
|
||||||
object_link_argname = 'layout'
|
object_link_argname = 'layout'
|
||||||
|
|
||||||
|
|
||||||
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.'),
|
|
||||||
}))
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ def html_head_presale(sender, request=None, **kwargs):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@log_entry_types.register_instance()
|
@log_entry_types.new()
|
||||||
class BanktransferOrderEmailInvoiceLogEntryType(OrderLogEntryType):
|
class BanktransferOrderEmailInvoiceLogEntryType(OrderLogEntryType):
|
||||||
action_type = 'pretix.plugins.banktransfer.order.email.invoice'
|
action_type = 'pretix.plugins.banktransfer.order.email.invoice'
|
||||||
plain = _('The invoice was sent to the designated email address.')
|
plain = _('The invoice was sent to the designated email address.')
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
|||||||
|
|
||||||
from pretix.base.forms import SecretKeySettingsField
|
from pretix.base.forms import SecretKeySettingsField
|
||||||
from pretix.base.middleware import _merge_csp, _parse_csp, _render_csp
|
from pretix.base.middleware import _merge_csp, _parse_csp, _render_csp
|
||||||
from pretix.base.models.log import EventLogEntryType
|
from pretix.base.models.log import EventLogEntryType, log_entry_types
|
||||||
from pretix.base.settings import settings_hierarkey
|
from pretix.base.settings import settings_hierarkey
|
||||||
from pretix.base.signals import (
|
from pretix.base.signals import (
|
||||||
register_global_settings, register_payment_providers,
|
register_global_settings, register_payment_providers,
|
||||||
@@ -47,6 +47,7 @@ def register_payment_provider(sender, **kwargs):
|
|||||||
return [PaypalSettingsHolder, PaypalWallet, PaypalAPM]
|
return [PaypalSettingsHolder, PaypalWallet, PaypalAPM]
|
||||||
|
|
||||||
|
|
||||||
|
@log_entry_types.new()
|
||||||
class PaypalEventLogEntryType(EventLogEntryType):
|
class PaypalEventLogEntryType(EventLogEntryType):
|
||||||
action_type = 'pretix.plugins.paypal.event'
|
action_type = 'pretix.plugins.paypal.event'
|
||||||
|
|
||||||
|
|||||||
@@ -119,26 +119,23 @@ def control_nav_import(sender, request=None, **kwargs):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@log_entry_types.new('pretix.plugins.sendmail.sent', _('Mass email was sent to customers or attendees.'))
|
||||||
|
@log_entry_types.new('pretix.plugins.sendmail.sent.waitinglist', _('Mass email was sent to waiting list entries.'))
|
||||||
class SendmailPluginLogEntryType(EventLogEntryType):
|
class SendmailPluginLogEntryType(EventLogEntryType):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*SendmailPluginLogEntryType.derive_plains({
|
@log_entry_types.new('pretix.plugins.sendmail.order.email.sent', _('The order received a mass email.'))
|
||||||
'pretix.plugins.sendmail.sent': _('Mass email was sent to customers or attendees.'),
|
@log_entry_types.new('pretix.plugins.sendmail.order.email.sent.attendee', _('A ticket holder of this order received a mass email.'))
|
||||||
'pretix.plugins.sendmail.sent.waitinglist': _('Mass email was sent to waiting list entries.'),
|
|
||||||
}))
|
|
||||||
|
|
||||||
|
|
||||||
class SendmailPluginOrderLogEntryType(OrderLogEntryType):
|
class SendmailPluginOrderLogEntryType(OrderLogEntryType):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
log_entry_types.register(*SendmailPluginOrderLogEntryType.derive_plains({
|
@log_entry_types.new('pretix.plugins.sendmail.rule.added', _('An email rule was created'))
|
||||||
'pretix.plugins.sendmail.order.email.sent': _('The order received a mass email.'),
|
@log_entry_types.new('pretix.plugins.sendmail.rule.changed', _('An email rule was updated'))
|
||||||
'pretix.plugins.sendmail.order.email.sent.attendee': _('A ticket holder of this order received a mass email.'),
|
@log_entry_types.new('pretix.plugins.sendmail.rule.order.email.sent', _('A scheduled email was sent to the order'))
|
||||||
}))
|
@log_entry_types.new('pretix.plugins.sendmail.rule.order.position.email.sent', _('A scheduled email was sent to a ticket holder'))
|
||||||
|
@log_entry_types.new('pretix.plugins.sendmail.rule.deleted', _('An email rule was deleted'))
|
||||||
|
|
||||||
class SendmailPluginRuleLogEntryType(EventLogEntryType):
|
class SendmailPluginRuleLogEntryType(EventLogEntryType):
|
||||||
object_type = Rule
|
object_type = Rule
|
||||||
object_link_wrapper = _('Mail rule {val}')
|
object_link_wrapper = _('Mail rule {val}')
|
||||||
@@ -146,15 +143,6 @@ class SendmailPluginRuleLogEntryType(EventLogEntryType):
|
|||||||
object_link_argname = 'rule'
|
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)
|
@receiver(periodic_task)
|
||||||
def sendmail_run_rules(sender, **kwargs):
|
def sendmail_run_rules(sender, **kwargs):
|
||||||
with scopes_disabled():
|
with scopes_disabled():
|
||||||
|
|||||||
@@ -133,6 +133,11 @@ def pdf_event_copy_data_receiver(sender, other, item_map, question_map, **kwargs
|
|||||||
return layout_map
|
return layout_map
|
||||||
|
|
||||||
|
|
||||||
|
@log_entry_types.new_from_dict({
|
||||||
|
'pretix.plugins.ticketoutputpdf.layout.added': _('Ticket layout created.'),
|
||||||
|
'pretix.plugins.ticketoutputpdf.layout.deleted': _('Ticket layout deleted.'),
|
||||||
|
'pretix.plugins.ticketoutputpdf.layout.changed': _('Ticket layout changed.'),
|
||||||
|
})
|
||||||
class PdfTicketLayoutLogEntryType(EventLogEntryType):
|
class PdfTicketLayoutLogEntryType(EventLogEntryType):
|
||||||
object_type = TicketLayout
|
object_type = TicketLayout
|
||||||
object_link_wrapper = _('Ticket layout {val}')
|
object_link_wrapper = _('Ticket layout {val}')
|
||||||
@@ -140,13 +145,6 @@ class PdfTicketLayoutLogEntryType(EventLogEntryType):
|
|||||||
object_link_argname = 'layout'
|
object_link_argname = 'layout'
|
||||||
|
|
||||||
|
|
||||||
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):
|
def _ticket_layouts_for_item(request, item):
|
||||||
if not hasattr(request, '_ticket_layouts_for_item'):
|
if not hasattr(request, '_ticket_layouts_for_item'):
|
||||||
request._ticket_layouts_for_item = {}
|
request._ticket_layouts_for_item = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user