Source code for shuup.utils.analog

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _
from enumfields import Enum, EnumIntegerField
from jsonfield import JSONField

from shuup.utils.django_compat import force_text


[docs] class LogEntryKind(Enum): OTHER = 0 AUDIT = 1 EDIT = 2 DELETION = 3 NOTE = 4 EMAIL = 5 WARNING = 6 ERROR = 7 class Labels: OTHER = _("other") AUDIT = _("audit") EDIT = _("edit") DELETION = _("deletion") NOTE = _("note") EMAIL = _("email") WARNING = _("warning") ERROR = _("error")
[docs] class BaseLogEntry(models.Model): target = None # This will be overridden dynamically created_on = models.DateTimeField(auto_now_add=True, editable=False, verbose_name=_("created on")) user = models.ForeignKey( to=settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_("user"), ) message = models.CharField(max_length=1024, verbose_name=_("message")) identifier = models.CharField(max_length=256, db_index=True, blank=True, verbose_name=_("identifier")) kind = EnumIntegerField(LogEntryKind, default=LogEntryKind.OTHER, verbose_name=_("log entry kind")) extra = JSONField(null=True, blank=True, verbose_name=_("extra data"))
[docs] class Meta: abstract = True
all_known_log_models = {}
[docs] def define_log_model(model_class): log_model_name = f"{model_class.__name__}LogEntry" class Meta: app_label = model_class._meta.app_label abstract = False class_dict = { "target": models.ForeignKey( model_class, related_name="log_entries", on_delete=models.CASCADE, verbose_name=_("target"), ), "__module__": model_class.__module__, "Meta": Meta, "logged_model": model_class, } log_entry_class = type(str(log_model_name), (BaseLogEntry,), class_dict) def _add_log_entry( self, message, identifier=None, kind=LogEntryKind.OTHER, user=None, extra=None, save=True, ): # You can also pass something that contains "user" as an # attribute for an user user = getattr(user, "user", user) or None if not getattr(user, "pk", None): user = None log_entry = log_entry_class( target=self, message=force_text(message or "", errors="ignore")[:1024], identifier=force_text(identifier or "", errors="ignore")[:256], user=user, kind=kind, extra=(extra or None), ) if save: log_entry.save() return log_entry model_class.add_log_entry = _add_log_entry all_known_log_models[model_class] = log_entry_class return log_entry_class