62 lines
2.8 KiB
Python
62 lines
2.8 KiB
Python
"""Customised storage for notifications."""
|
|
|
|
from __future__ import absolute_import
|
|
from django.contrib.messages.storage.base import Message
|
|
from django.utils.safestring import mark_safe
|
|
from messages_extends.storages import FallbackStorage
|
|
from messages_extends.models import Message as PersistentMessage
|
|
from messages_extends.constants import PERSISTENT_MESSAGE_LEVELS
|
|
|
|
|
|
class FallbackUniqueStorage(FallbackStorage):
|
|
|
|
"""
|
|
Persistent message fallback storage, but only stores unique notifications.
|
|
|
|
This loops through all backends to find messages to store, but will skip
|
|
this step if the message already exists for the user in the database.
|
|
|
|
Deduplication is important here, as a persistent message may ask a user to
|
|
perform a specific action, such as change a build option. Duplicated
|
|
messages would lead to confusing UX, where a duplicate message may not be
|
|
dismissed when the prescribed action is taken. Instead of detecting
|
|
duplication while triggering the message, we handle this at the storage
|
|
level.
|
|
|
|
This class also assumes that notifications set as persistent messages are
|
|
more likely to have HTML that should be marked safe. If the level matches a
|
|
persistent message level, mark the message text as safe so that we can
|
|
render the text in templates.
|
|
"""
|
|
|
|
def _get(self, *args, **kwargs):
|
|
# The database backend for persistent messages doesn't support setting
|
|
# messages with ``mark_safe``, therefore, we need to do it broadly here.
|
|
messages, all_ret = (super(FallbackUniqueStorage, self)
|
|
._get(self, *args, **kwargs))
|
|
safe_messages = []
|
|
for message in messages:
|
|
# Handle all message types, if the message is persistent, take
|
|
# special action. As the default message handler, this will also
|
|
# process ephemeral messages
|
|
if message.level in PERSISTENT_MESSAGE_LEVELS:
|
|
message_pk = message.pk
|
|
message = Message(message.level,
|
|
mark_safe(message.message),
|
|
message.extra_tags)
|
|
message.pk = message_pk
|
|
safe_messages.append(message)
|
|
return safe_messages, all_ret
|
|
|
|
def add(self, level, message, extra_tags='', *args, **kwargs): # noqa
|
|
user = kwargs.get('user') or self.request.user
|
|
if not user.is_anonymous():
|
|
persist_messages = (PersistentMessage.objects
|
|
.filter(message=message,
|
|
user=user,
|
|
read=False))
|
|
if persist_messages.exists():
|
|
return
|
|
super(FallbackUniqueStorage, self).add(level, message, extra_tags,
|
|
*args, **kwargs)
|