"""Base Implementation of a Delivery Backend.""" import abc from json import dumps import six import pika from django.contrib.auth import get_user_model from .models import Notification from . import default_settings as settings @six.add_metaclass(abc.ABCMeta) class BaseNotificationChannel(): """Base channel for sending notifications.""" def __init__(self, **kwargs): self.notification_kwargs = kwargs @abc.abstractmethod def construct_message(self): """Constructs a message from notification details.""" pass @abc.abstractmethod def notify(self, message): """Sends the notification.""" pass class ConsoleChannel(BaseNotificationChannel): """Dummy channel that prints to the console.""" def construct_message(self): """Stringify the notification kwargs.""" return str(self.notification_kwargs) def notify(self, message): print(message) class BasicWebSocketChannel(BaseNotificationChannel): """It creates a RabbitMQ user for each user (based on their username).""" def _connect(self): """Connect to the RabbitMQ Server.""" rabbit_mq_url = settings.NOTIFICATIONS_RABBIT_MQ_URL connection = pika.BlockingConnection( pika.connection.URLParameters(rabbit_mq_url) ) return connection def construct_message(self): """Construct message from notification details.""" return self.notification_kwargs def notify(self, message): """ Puts a new message on the queue. The queue is named based on the username (for Uniqueness) """ connection = self._connect() channel = connection.channel() # Get user instance User = get_user_model() source = User.objects.get(id=message['source']) recipient = User.objects.get(id=message['recipient']) channel.queue_declare(queue=source.username) jsonified_messasge = dumps(message) channel.basic_publish( exchange='', routing_key=recipient.username, body=jsonified_messasge ) connection.close()