Front-end notification model

Context processor to count notifications for display in base template
Logging handler to generate notifications for users with permission
This commit is contained in:
Adarnof 2016-02-13 05:25:57 +00:00
parent a75391f270
commit 1d99ef69d1
10 changed files with 83 additions and 1 deletions

View File

@ -16,7 +16,7 @@ Join us in-game in the channel allianceauth for help and feature requests.
Special Thanks: Special Thanks:
Thanking [Nikdoof](https://github.com/nikdoof), without his old auth Thanking Nikdoof, without his old auth
implementation this project wouldn't be as far as it is now. implementation this project wouldn't be as far as it is now.
Thanks to Raynaldo for his original work on this system and getting it as far as it is today. Thanks to Raynaldo for his original work on this system and getting it as far as it is today.
@ -74,6 +74,7 @@ Special Permissions In Admin:
auth | user | sigtracker_view ( Allows for an individual view signitures) auth | user | sigtracker_view ( Allows for an individual view signitures)
auth | user | optimer_management ( Allows for an individual to create and remove fleet operations) auth | user | optimer_management ( Allows for an individual to create and remove fleet operations)
auth | user | optimer_view ( Allows for an individual view fleet operations) auth | user | optimer_view ( Allows for an individual view fleet operations)
auth | user | logging_notifications ( Generate notifications from logging)
Active Developers Active Developers

View File

@ -61,6 +61,7 @@ INSTALLED_APPS = (
'sigtracker', 'sigtracker',
'optimer', 'optimer',
'corputils', 'corputils',
'notifications',
) )
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
@ -126,6 +127,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'util.context_processors.domain_url', 'util.context_processors.domain_url',
'util.context_processors.member_api_mask', 'util.context_processors.member_api_mask',
'util.context_processors.blue_api_mask', 'util.context_processors.blue_api_mask',
'notifications.context_processors.user_notification_count',
) )
TEMPLATE_DIRS = ( TEMPLATE_DIRS = (

View File

3
notifications/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

@ -0,0 +1,4 @@
from .models import Notification
def user_notification_count(request):
return len(Notification.objects.filter(user=request.user).filter(viewed=False))

14
notifications/handlers.py Normal file
View File

@ -0,0 +1,14 @@
import logging
from django.contrib.auth.models import User
from .models import Notification
def 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.message = record.getMessage()
notif.save()

28
notifications/models.py Normal file
View File

@ -0,0 +1,28 @@
from django.db import models
from django.contrib.auth.models import User
class Notification(models.Model):
LEVEL_CHOICES = (
('danger', 'CRITICAL'),
('danger', 'ERROR'),
('warning', 'WARN'),
('info', 'INFO'),
('success', 'DEBUG'),
)
user = models.ForeignKey(User, on_delete=models.CASCADE)
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()
def view(self):
logger.info("Marking notification as viewed: %s" % self)
self.viewed = True
self.save()
def __unicode__(self):
output = "%s: %s" % (self.user, self.title)
return output.encode('utf-8')

3
notifications/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

26
notifications/views.py Normal file
View File

@ -0,0 +1,26 @@
from django.shortcuts import render, get_object_or_404
from .models import Notification
@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)
logger.debug("User %s has %s unread and %s read notifications" % (request.user, len(new_notifs), len(old_notifs)))
context = {
'read': old_notifs,
'unread': new_notifs,
}
return render(request, 'registered/notification_list.html', context)
@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)
if notif.user == request.user:
logger.debug("Providing notification for user %s" % request.user)
context = {'notification': 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))

View File

@ -27,6 +27,7 @@ def bootstrap_permissions():
Permission.objects.get_or_create(codename="signature_view", content_type=ct, name="signature_view") Permission.objects.get_or_create(codename="signature_view", content_type=ct, name="signature_view")
Permission.objects.get_or_create(codename="optimer_management", content_type=ct, name="optimer_management") Permission.objects.get_or_create(codename="optimer_management", content_type=ct, name="optimer_management")
Permission.objects.get_or_create(codename="optimer_view", content_type=ct, name="optimer_view") Permission.objects.get_or_create(codename="optimer_view", content_type=ct, name="optimer_view")
Permission.objects.get_or_create(codename="logging_notifications", content_type=ct, name="logging_notifications")
Group.objects.get_or_create(name=settings.DEFAULT_AUTH_GROUP) Group.objects.get_or_create(name=settings.DEFAULT_AUTH_GROUP)
Group.objects.get_or_create(name=settings.DEFAULT_BLUE_GROUP) Group.objects.get_or_create(name=settings.DEFAULT_BLUE_GROUP)
logger.info("Bootstrapped permissions for auth and created default groups.") logger.info("Bootstrapped permissions for auth and created default groups.")