Commit ec96fb8d authored by Gijs Hendriksen's avatar Gijs Hendriksen

Add sent message overview to the push notifications API

parent 90ae8734
......@@ -7,6 +7,31 @@ from pushnotifications.models import Message
from utils.translation import TranslatedModelAdmin
class MessageSentFilter(admin.SimpleListFilter):
"""Filter the push notifications on whether they are sent or not"""
title = _('sent')
parameter_name = 'is_sent'
def lookups(self, request, model_admin):
queryset = model_admin.get_queryset(request)
values = []
if queryset.filter(sent__isnull=False).exists():
values.append((1, _('Yes')))
if queryset.filter(sent__isnull=True).exists():
values.append((0, _('No')))
return values
def queryset(self, request, queryset):
if self.value() == '1':
return queryset.filter(sent__isnull=False)
elif self.value() == '0':
return queryset.filter(sent__isnull=True)
return queryset
@admin.register(models.Device)
class DeviceAdmin(admin.ModelAdmin):
"""Manage the devices"""
......@@ -37,19 +62,20 @@ class MessageAdmin(TranslatedModelAdmin):
list_display = ('title', 'body', 'category', 'url',
'sent', 'success', 'failure')
filter_horizontal = ('users',)
list_filter = ('sent', 'category')
list_filter = (MessageSentFilter, 'category')
date_hierarchy = 'sent'
def get_fields(self, request, obj=None):
if obj and obj.sent:
return ('users', 'title_nl', 'title_en', 'body_nl', 'body_en',
'url', 'category', 'success', 'failure')
'url', 'category', 'sent', 'success', 'failure')
return ('users', 'title_nl', 'title_en', 'body_nl', 'body_en',
'url', 'category')
def get_readonly_fields(self, request, obj=None):
if obj and obj.sent:
return ('users', 'title_nl', 'title_en', 'body_nl', 'body_en',
'url', 'category', 'success', 'failure')
'url', 'category', 'sent', 'success', 'failure')
return super().get_readonly_fields(request, obj)
def change_view(self, request, object_id, form_url='', **kwargs):
......@@ -65,12 +91,12 @@ class ScheduledMessageAdmin(TranslatedModelAdmin):
'failure')
date_hierarchy = 'time'
filter_horizontal = ('users',)
list_filter = ('sent', 'category')
list_filter = (MessageSentFilter, 'category')
def get_fields(self, request, obj=None):
if obj and obj.sent:
return ('users', 'title_nl', 'title_en', 'body_nl', 'body_en',
'url', 'category', 'success', 'failure', 'time',
'url', 'category', 'sent', 'success', 'failure', 'time',
'executed')
return ('users', 'title_nl', 'title_en', 'body_nl', 'body_en',
'url', 'category', 'time')
......@@ -78,6 +104,6 @@ class ScheduledMessageAdmin(TranslatedModelAdmin):
def get_readonly_fields(self, request, obj=None):
if obj and obj.sent:
return ('users', 'title_nl', 'title_en', 'body_nl', 'body_en',
'url', 'category', 'success', 'failure', 'time',
'url', 'category', 'sent', 'success', 'failure', 'time',
'executed')
return 'executed',
from rest_framework.relations import ManyRelatedField, PrimaryKeyRelatedField
from rest_framework.serializers import ModelSerializer
from pushnotifications.models import Device, Category
from pushnotifications.models import Device, Category, Message
class DeviceSerializer(ModelSerializer):
......@@ -35,3 +35,10 @@ class CategorySerializer(ModelSerializer):
model = Category
fields = ('key', 'name', 'description')
class MessageSerializer(ModelSerializer):
class Meta:
model = Message
fields = ('pk', 'title', 'body', 'url', 'category', 'sent')
......@@ -4,4 +4,5 @@ from pushnotifications.api import viewsets
router = routers.SimpleRouter()
router.register(r'devices', viewsets.DeviceViewSet)
router.register(r'notifications', viewsets.MessageViewSet)
urlpatterns = router.urls
from django.utils.translation import get_language_from_request
from rest_framework import permissions
from rest_framework import permissions, viewsets, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from pushnotifications.api.permissions import IsOwner
from pushnotifications.api.serializers import (DeviceSerializer,
CategorySerializer)
from pushnotifications.models import Device, Category
CategorySerializer,
MessageSerializer)
from pushnotifications.models import Device, Category, Message
class DeviceViewSet(ModelViewSet):
class DeviceViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticated, IsOwner)
queryset = Device.objects.all()
serializer_class = DeviceSerializer
......@@ -47,3 +47,20 @@ class DeviceViewSet(ModelViewSet):
categories = Category.objects.all()
serializer = CategorySerializer(categories, many=True)
return Response(serializer.data)
class MessageViewSet(viewsets.ReadOnlyModelViewSet):
permission_classes = (permissions.IsAuthenticated,)
queryset = Message.objects.all()
filter_backends = (filters.OrderingFilter,)
ordering_fields = ('sent',)
serializer_class = MessageSerializer
def get_queryset(self):
queryset = Message.all_objects.filter(users=self.request.user,
sent__isnull=False)
category = self.request.query_params.get('category', None)
if category is not None:
return queryset.filter(category=category)
return queryset
......@@ -35,7 +35,7 @@ class Command(BaseCommand):
before_time = timezone.now() + timedelta(seconds=interval/2)
messages = ScheduledMessage.objects.filter(
sent=False, time__lte=before_time)
sent__isnull=True, time__lte=before_time)
for message in messages:
if (timezone.now() - now).seconds < interval:
......
# Generated by Django 2.2.1 on 2019-10-16 17:51
from django.db import migrations, models
from django.utils import timezone
def forwards_func(apps, schema_editor):
message = apps.get_model('pushnotifications', 'Message')
scheduled = apps.get_model('pushnotifications', 'ScheduledMessage')
db_alias = schema_editor.connection.alias
try:
latest_pk = message.objects.using(db_alias).latest('pk').pk
except message.DoesNotExist:
latest_pk = 1
start_date = timezone.now() - timezone.timedelta(days=latest_pk + 1)
for m in message.objects.using(db_alias):
if m.sent:
m.tmp_sent = start_date + timezone.timedelta(m.pk)
m.save()
for m in scheduled.objects.using(db_alias):
if m.sent:
m.tmp_sent = m.time
m.save()
def reverse_func(apps, schema_editor):
message = apps.get_model('pushnotifications', 'Message')
db_alias = schema_editor.connection.alias
for m in message.objects.using(db_alias):
if m.tmp_sent:
m.sent = True
m.save()
class Migration(migrations.Migration):
dependencies = [
('pushnotifications', '0014_fix_typo'),
]
operations = [
migrations.AddField(
model_name='message',
name='tmp_sent',
field=models.DateTimeField(null=True, verbose_name='sent')
),
migrations.RunPython(forwards_func, reverse_func),
migrations.RemoveField(
model_name='message',
name='sent',
),
migrations.RenameField(
model_name='message',
old_name='tmp_sent',
new_name='sent',
),
]
......@@ -3,6 +3,7 @@ import datetime
from django.conf import settings
from django.db import models
from django.utils import timezone
from django.utils.translation import override
from django.utils.translation import ugettext_lazy as _
from firebase_admin import messaging, exceptions
......@@ -77,7 +78,7 @@ class Device(models.Model):
).format(user=self.user, device_type=self.type)
class MessageManager(models.Manager):
class NormalMessageManager(models.Manager):
"""Returns manual messages only"""
def get_queryset(self):
......@@ -85,10 +86,18 @@ class MessageManager(models.Manager):
.filter(scheduledmessage__scheduled=None))
class MessageManager(models.Manager):
"""Returns all messages"""
def get_queryset(self):
return super().get_queryset()
class Message(models.Model, metaclass=ModelTranslateMeta):
"""Describes a push notification"""
objects = MessageManager()
objects = NormalMessageManager()
all_objects = MessageManager()
users = models.ManyToManyField(settings.AUTH_USER_MODEL)
title = MultilingualField(
......@@ -112,9 +121,9 @@ class Message(models.Model, metaclass=ModelTranslateMeta):
verbose_name=_('category'),
default="general"
)
sent = models.BooleanField(
sent = models.DateTimeField(
verbose_name=_('sent'),
default=False
null=True,
)
failure = models.IntegerField(
verbose_name=_('failure'),
......@@ -187,7 +196,7 @@ class Message(models.Model, metaclass=ModelTranslateMeta):
except exceptions.FirebaseError:
failure_total += 1
self.sent = True
self.sent = timezone.now()
self.success = success_total
self.failure = failure_total
self.save()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment