Source code for pretalx.common.models.log

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django_scopes import ScopedManager

from pretalx.mail.models import MailTemplate, QueuedMail
from pretalx.submission.models import Answer, AnswerOption, CfP, Question, Submission

LOG_NAMES = {
    'pretalx.cfp.update': _('The CfP has been modified.'),
    'pretalx.event.create': _('The event has been added.'),
    'pretalx.event.update': _('The event was modified.'),
    'pretalx.event.activate': _('The event was made public.'),
    'pretalx.event.deactivate': _('The event was deactivated.'),
    'pretalx.event.plugins.enabled': _('A plugin was enabled.'),
    'pretalx.event.plugins.disabled': _('A plugin was disabled.'),
    'pretalx.invite.orga.accept': _('The invitation to the event orga was accepted.'),
    'pretalx.invite.orga.retract': _('An invitation to the event orga was retracted.'),
    'pretalx.invite.orga.send': _('An invitation to the event orga was sent.'),
    'pretalx.invite.reviewer.retract': _(
        'The invitation to the review team was retracted.'
    ),
    'pretalx.invite.reviewer.send': _('The invitation to the review team was sent.'),
    'pretalx.event.invite.orga.accept': _(
        'The invitation to the event orga was accepted.'
    ),  # compat
    'pretalx.event.invite.orga.retract': _(
        'An invitation to the event orga was retracted.'
    ),  # compat
    'pretalx.event.invite.orga.send': _(
        'An invitation to the event orga was sent.'
    ),  # compat
    'pretalx.event.invite.reviewer.retract': _(
        'The invitation to the review team was retracted.'
    ),  # compat
    'pretalx.event.invite.reviewer.send': _(
        'The invitation to the review team was sent.'
    ),  # compat
    'pretalx.mail.create': _('An email was modified.'),
    'pretalx.mail.delete': _('A pending email was deleted.'),
    'pretalx.mail.delete_all': _('All pending emails were deleted.'),
    'pretalx.mail.sent': _('An email was sent.'),
    'pretalx.mail.update': _('An email was modified.'),
    'pretalx.mail_template.create': _('A mail template was added.'),
    'pretalx.mail_template.delete': _('A mail template was deleted.'),
    'pretalx.mail_template.update': _('A mail template was modified.'),
    'pretalx.question.create': _('A question was added.'),
    'pretalx.question.delete': _('A question was deleted.'),
    'pretalx.question.update': _('A question was modified.'),
    'pretalx.question.option.create': _('A question option was added.'),
    'pretalx.question.option.delete': _('A question option was deleted.'),
    'pretalx.question.option.update': _('A question option was modified.'),
    'pretalx.room.create': _('A new room was added.'),
    'pretalx.schedule.release': _('A new schedule version was released.'),
    'pretalx.submission.accept': _('The submission was accepted.'),
    'pretalx.submission.cancel': _('The submission was cancelled.'),
    'pretalx.submission.confirm': _('The submission was confirmed.'),
    'pretalx.submission.confirmation': _('The submission was confirmed.'),  # Legacy
    'pretalx.submission.create': _('The submission was added.'),
    'pretalx.submission.deleted': _('The submission was deleted.'),
    'pretalx.submission.reject': _('The submission was rejected.'),
    'pretalx.submission.resource.create': _('A submission resource was added.'),
    'pretalx.submission.resource.delete': _('A submission resource was deleted.'),
    'pretalx.submission.resource.update': _('A submission resource was modified.'),
    'pretalx.submission.speakers.add': _('A speaker was added to the submission.'),
    'pretalx.submission.speakers.invite': _('A speaker was invited to the submission.'),
    'pretalx.submission.speakers.remove': _(
        'A speaker was removed from the submission.'
    ),
    'pretalx.submission.unconfirm': _('The submission was unconfirmed.'),
    'pretalx.submission.update': _('The submission was modified.'),
    'pretalx.submission.withdraw': _('The submission was withdrawn.'),
    'pretalx.submission.answer.update': _('A submission answer was modified.'),
    'pretalx.submission.answerupdate': _('A submission answer was modified.'),  # compat
    'pretalx.submission.answer.create': _('A submission answer was added.'),
    'pretalx.submission.answercreate': _('A submission answer was added.'),
    'pretalx.submission_type.create': _('A submission type was added.'),
    'pretalx.submission_type.delete': _('A submission type was deleted.'),
    'pretalx.submission_type.make_default': _('The submission type was made default.'),
    'pretalx.submission_type.update': _('A submission type was modified.'),
    'pretalx.track.create': _('A track was added.'),
    'pretalx.track.delete': _('A track was deleted.'),
    'pretalx.track.update': _('A track was modified.'),
    'pretalx.speaker.arrived': _('A speaker has been marked as arrived.'),
    'pretalx.speaker.unarrived': _('A speaker has been marked as not arrived.'),
    'pretalx.user.token.reset': _('The API token was reset.'),
    'pretalx.user.password.reset': _('The password was reset.'),
    'pretalx.user.password.update': _('The password was modified.'),
    'pretalx.user.profile.update': _('The profile was modified.'),
}


[docs]class ActivityLog(models.Model): """This model logs actions within an event. It is **not** designed to provide a complete or reliable audit trail.""" event = models.ForeignKey( to='event.Event', on_delete=models.PROTECT, related_name='log_entries', null=True, blank=True, ) person = models.ForeignKey( to='person.User', on_delete=models.PROTECT, related_name='log_entries', null=True, blank=True, ) content_type = models.ForeignKey(to=ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField(db_index=True) content_object = GenericForeignKey('content_type', 'object_id') timestamp = models.DateTimeField(auto_now_add=True, db_index=True) action_type = models.CharField(max_length=200) data = models.TextField(null=True, blank=True) is_orga_action = models.BooleanField(default=False) objects = ScopedManager(event='event') class Meta: ordering = ('-timestamp',) def __str__(self): """Custom __str__ to help with debugging.""" event = getattr(self.event, 'slug', 'None') person = getattr(self.person, 'name', 'None') return f'ActivityLog(event={event}, person={person}, content_object={self.content_object}, action_type={self.action_type})' def display(self): response = LOG_NAMES.get(self.action_type) if response is None: import logging logger = logging.getLogger(__name__) logger.warning(f'Unknown log action "{self.action_type}".') return self.action_type return response
[docs] def get_public_url(self) -> str: """Returns a public URL to the object in question (if any).""" if isinstance(self.content_object, Submission): return self.content_object.urls.public if isinstance(self.content_object, CfP): return self.content_object.urls.public return ''
[docs] def get_orga_url(self) -> str: """Returns an organiser backend URL to the object in question (if any).""" if isinstance(self.content_object, Submission): return self.content_object.orga_urls.base if isinstance(self.content_object, Question): return self.content_object.urls.base if isinstance(self.content_object, AnswerOption): return self.content_object.question.urls.base if isinstance(self.content_object, Answer): if self.content_object.submission: return self.content_object.submission.orga_urls.base return self.content_object.question.urls.base if isinstance(self.content_object, CfP): return self.content_object.urls.text if isinstance(self.content_object, (MailTemplate, QueuedMail)): return self.content_object.urls.base return ''