From 5e2c828c3b744807b3ea337c5d4fd711ca6def41 Mon Sep 17 00:00:00 2001 From: Adarnof Date: Sat, 13 Feb 2016 21:53:43 +0000 Subject: [PATCH] Front-end notification system Currently only creates notifications for logging events Addresses #75 --- alliance_auth/settings.py.example | 37 ++++++---- alliance_auth/urls.py | 3 + notifications/admin.py | 3 +- notifications/context_processors.py | 2 +- notifications/handlers.py | 4 +- notifications/models.py | 10 ++- notifications/views.py | 15 ++-- stock/templates/public/base.html | 9 +++ .../registered/notification_list.html | 74 +++++++++++++++++++ .../registered/notification_view.html | 22 ++++++ 10 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 stock/templates/registered/notification_list.html create mode 100644 stock/templates/registered/notification_view.html diff --git a/alliance_auth/settings.py.example b/alliance_auth/settings.py.example index ed91e333..830ed9ad 100755 --- a/alliance_auth/settings.py.example +++ b/alliance_auth/settings.py.example @@ -410,67 +410,72 @@ LOGGING = { 'level': 'DEBUG', # edit this line to change logging level to console 'class': 'logging.StreamHandler', 'formatter': 'verbose', - } + }, + 'notifications': { # creates notifications for users with logging_notifications permission + 'level': 'ERROR', # edit this line to change logging level to notifications + 'class': 'notifications.handlers.NotificationHandler', + 'formatter': 'verbose', + }, }, 'loggers': { 'authentication': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'celerytask': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'eveonline': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'groupmanagement': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'hrapplications': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'portal': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'registration': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'services': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'srp': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'timerboard': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'sigtracker': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'optimer': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'corputils': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'util': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'DEBUG', }, 'django': { - 'handlers': ['log_file', 'console'], + 'handlers': ['log_file', 'console', 'notifications'], 'level': 'ERROR', }, } diff --git a/alliance_auth/urls.py b/alliance_auth/urls.py index df632863..5325ea52 100755 --- a/alliance_auth/urls.py +++ b/alliance_auth/urls.py @@ -186,4 +186,7 @@ urlpatterns = patterns('', url(r'^remove_optimer/(\w+)', 'optimer.views.remove_optimer', name='auth_remove_optimer'), url(r'^edit_optimer/(\w+)$', 'optimer.views.edit_optimer', name='auth_edit_optimer'), + # Notifications + url(r'^notifications/$', 'notifications.views.notification_list', name='auth_notification_list'), + url(r'^notifications/(\w+)/$', 'notifications.views.notification_view', name='auth_notification_view'), ) diff --git a/notifications/admin.py b/notifications/admin.py index 8c38f3f3..56893293 100644 --- a/notifications/admin.py +++ b/notifications/admin.py @@ -1,3 +1,4 @@ from django.contrib import admin +from.models import Notification -# Register your models here. +admin.site.register(Notification) diff --git a/notifications/context_processors.py b/notifications/context_processors.py index d5985eff..1c9a5385 100644 --- a/notifications/context_processors.py +++ b/notifications/context_processors.py @@ -1,4 +1,4 @@ from .models import Notification def user_notification_count(request): - return len(Notification.objects.filter(user=request.user).filter(viewed=False)) + return {'notifications':len(Notification.objects.filter(user__id=request.user.id).filter(viewed=False))} diff --git a/notifications/handlers.py b/notifications/handlers.py index a047e279..bdffeb33 100644 --- a/notifications/handlers.py +++ b/notifications/handlers.py @@ -2,13 +2,13 @@ import logging from django.contrib.auth.models import User from .models import Notification -def NotificationHandler(logging.Handler): +class NotificationHandler(logging.Handler): def emit(self, record): for user in User.objects.all(): if user.has_perm('auth.logging_notifications'): notif = Notification() notif.user = user notif.title = "%s [%s:%s]" % (record.levelname, record.funcName, record.lineno) - notif.level = str([item[0] for item in Notification.LEVEL_CHOICES if item[1] == record.levelname]) + notif.level = str([item[0] for item in Notification.LEVEL_CHOICES if item[1] == record.levelname][0]) notif.message = record.getMessage() notif.save() diff --git a/notifications/models.py b/notifications/models.py index f92c6852..cf0d688d 100644 --- a/notifications/models.py +++ b/notifications/models.py @@ -1,5 +1,8 @@ from django.db import models from django.contrib.auth.models import User +import logging + +logger = logging.getLogger(__name__) class Notification(models.Model): @@ -15,8 +18,8 @@ class Notification(models.Model): level = models.CharField(choices=LEVEL_CHOICES, max_length=10) title = models.CharField(max_length=254) message = models.TextField() - created = models.DateTimeField(auto_now_add=True) - viewed = models.BooleanField() + timestamp = models.DateTimeField(auto_now_add=True) + viewed = models.BooleanField(default=False) def view(self): logger.info("Marking notification as viewed: %s" % self) @@ -26,3 +29,6 @@ class Notification(models.Model): def __unicode__(self): output = "%s: %s" % (self.user, self.title) return output.encode('utf-8') + + def set_level(self, level): + self.level = [item[0] for item in self.LEVEL_CHOICES if item[1] == level][0] diff --git a/notifications/views.py b/notifications/views.py index 63076dd6..7fa53a48 100644 --- a/notifications/views.py +++ b/notifications/views.py @@ -1,11 +1,15 @@ -from django.shortcuts import render, get_object_or_404 +from django.shortcuts import render, get_object_or_404, redirect from .models import Notification +from django.contrib.auth.decorators import login_required +import logging + +logger = logging.getLogger(__name__) @login_required def notification_list(request): logger.debug("notification_list called by user %s" % request.user) - new_notifs = Notification.objects.filter(user=request.user).filter(read=False) - old_notifs = Notification.objects.filter(user=request.user).filter(read=True) + new_notifs = Notification.objects.filter(user=request.user).filter(viewed=False) + old_notifs = Notification.objects.filter(user=request.user).filter(viewed=True) logger.debug("User %s has %s unread and %s read notifications" % (request.user, len(new_notifs), len(old_notifs))) context = { 'read': old_notifs, @@ -16,11 +20,12 @@ def notification_list(request): @login_required def notification_view(request, notif_id): logger.debug("notification_view called by user %s for notif_id %s" % (request.user, notif_id)) - notif = get_object_or_404(notification, pk=notif_id) + notif = get_object_or_404(Notification, pk=notif_id) if notif.user == request.user: logger.debug("Providing notification for user %s" % request.user) - context = {'notification': notif} + context = {'notif': notif} notif.view() return render(request, 'registered/notification_view.html', context) else: logger.warn("User %s not authorized to view notif_id %s belonging to user %s" % (request.user, notif_id, notif.user)) + return redirect('auth_notification_list') diff --git a/stock/templates/public/base.html b/stock/templates/public/base.html index a1c89870..b9f81154 100755 --- a/stock/templates/public/base.html +++ b/stock/templates/public/base.html @@ -47,6 +47,15 @@