From f2c9e4b895bf32b157bc3548de62d745c98a7d54 Mon Sep 17 00:00:00 2001 From: Gael Le Mignot Date: Thu, 16 Jun 2022 10:08:37 +0200 Subject: [PATCH] Uncommited changes from Yoan --- teleforma/models/chat.py | 2 - teleforma/models/notification.py | 56 ++++++++++++++++++++ teleforma/src/js/components/Notification.vue | 56 ++++++++++++++++++++ teleforma/src/js/main.ts | 8 +++ teleforma/templates/teleforma/base.html | 3 ++ teleforma/ws/notification.py | 28 ++++++++++ teleforma/ws/routing.py | 3 ++ 7 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 teleforma/models/notification.py create mode 100644 teleforma/src/js/components/Notification.vue create mode 100644 teleforma/ws/notification.py diff --git a/teleforma/models/chat.py b/teleforma/models/chat.py index 53c804b4..ac52266b 100644 --- a/teleforma/models/chat.py +++ b/teleforma/models/chat.py @@ -65,8 +65,6 @@ class ChatMessage(models.Model): 'content': self.message, 'senderId': self.user and self.user.id or "system", 'username': self.user and self.user.username or "Système", - 'date': '13 November', - 'timestamp': '10:20', 'date': self.created.strftime('%d/%m/%Y'), 'timestamp': self.created.strftime('%H:%M'), 'system': self.system diff --git a/teleforma/models/notification.py b/teleforma/models/notification.py new file mode 100644 index 00000000..126382f2 --- /dev/null +++ b/teleforma/models/notification.py @@ -0,0 +1,56 @@ + +from datetime import datetime, timedelta +from django.contrib.auth.models import User +from django.contrib.sites.models import Site +from django.db import models +from django.urls.base import reverse +from django.utils.translation import ugettext_lazy as _ + +from ..models import MetaCore +from ..models.core import app_label +from channels.layers import get_channel_layer +from asgiref.sync import async_to_sync + +def in_one_week(): + return datetime.utcnow() + timedelta(days=1) + +class Notification(models.Model): + """A notification message""" + + message = models.CharField('Message', max_length=255) + url = models.CharField('Url', max_length=255) + user = models.ForeignKey( + User, related_name='notifications', verbose_name=_('user'), on_delete=models.CASCADE) + created = models.DateTimeField('Creation date', auto_now_add=True) + expired = models.DateTimeField("Date d'expiration", default=in_one_week) + + class Meta(MetaCore): + db_table = app_label + '_' + 'notifications' + + def __str__(self): + return f"{str(self.user)} - {self.message[:20]}" + + @classmethod + def create(cls, user, room_name, message, system=False): + notification = Notification(user=user, message=message, + room_name=room_name, system=system) + notification.save() + return notification.to_dict() + + def broadcast(self): + """ + broadcast a notification to socket + """ + channel_layer = get_channel_layer() + async_to_sync(channel_layer.send)(f"usernotification_{self.user.id}", { + 'type': 'notification', + 'message': self.to_dict() + }) + + def to_dict(self): + return { + '_id': self.id, + 'content': self.message, + 'url': self.url, + 'date': self.created.strftime('%d/%m/%Y'), + } diff --git a/teleforma/src/js/components/Notification.vue b/teleforma/src/js/components/Notification.vue new file mode 100644 index 00000000..7fda57eb --- /dev/null +++ b/teleforma/src/js/components/Notification.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/teleforma/src/js/main.ts b/teleforma/src/js/main.ts index 2fbd4164..d75b08b5 100644 --- a/teleforma/src/js/main.ts +++ b/teleforma/src/js/main.ts @@ -1,6 +1,7 @@ import "./compatibility" import Vue from "vue" import Chat from "./components/Chat.vue" +import Notification from "./components/Notification.vue" Vue.config.productionTip = false @@ -9,3 +10,10 @@ if (document.getElementById("chat")) { render: (h) => h(Chat) }).$mount("#chat") } + + +if (document.getElementById("notification")) { + new Vue({ + render: (h) => h(Notification) + }).$mount("#notification") +} diff --git a/teleforma/templates/teleforma/base.html b/teleforma/templates/teleforma/base.html index 80dd0aae..8e0381f0 100644 --- a/teleforma/templates/teleforma/base.html +++ b/teleforma/templates/teleforma/base.html @@ -184,6 +184,9 @@ {% endblock menu %} + + +
{% endblock header %} diff --git a/teleforma/ws/notification.py b/teleforma/ws/notification.py new file mode 100644 index 00000000..006cd1df --- /dev/null +++ b/teleforma/ws/notification.py @@ -0,0 +1,28 @@ +from teleforma.ws.logger import log_consumer_exceptions +from teleforma.models.notification import Notification +from django.conf import settings +from channels.generic.websocket import AsyncJsonWebsocketConsumer +from channels.db import database_sync_to_async + + +@log_consumer_exceptions +class NotificationConsumer(AsyncJsonWebsocketConsumer): + + async def connect(self): + await self.accept() + + # send initial messages + data = await self.get_notifications_list() + await self.send_json(content={'type': 'initial', 'messages': data}) + + @database_sync_to_async + def get_notifications_list(self): + messages = [message.to_dict() for message in Notification.objects.filter( + user=self.user).order_by('-created')] + return messages + + # Receive message from channel + async def notification_message(self, event): + message = event['message'] + # Send message to WebSocket + await self.send_json(content={'type': 'new', 'messages': [message]}) diff --git a/teleforma/ws/routing.py b/teleforma/ws/routing.py index 649baec3..3f3b1098 100644 --- a/teleforma/ws/routing.py +++ b/teleforma/ws/routing.py @@ -4,7 +4,9 @@ from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application from django.urls import re_path + from . import chat +from . import notification os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'teleforma.settings') sys.path.append(os.path.dirname('.')) @@ -12,6 +14,7 @@ sys.path.append(os.path.dirname('.')) websocket_urlpatterns = [ re_path(r'ws/chat/(?P\w+)/$', chat.ChatConsumer.as_asgi()), + re_path(r'ws/notification/(?P\w+)/$', notification.NotificationConsumer.as_asgi()), ] -- 2.39.5