Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW-FEATURE: Announcement messages #200

Merged
merged 5 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion daiquiri/contact/admin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
from django import forms
from django.contrib import admin

from .models import ContactMessage
from .models import ContactMessage, AnnouncementMessage, MessageFilter


class AnnouncementMessageAdminForm(forms.ModelForm):
visibility_filter = forms.ChoiceField(choices=MessageFilter().CHOICES)


@admin.action(description="Make selected messages visible")
def make_visible(modeladmin, request, queryset):
queryset.update(visible=True)


@admin.action(description="Make selected messages invisible")
def make_invisible(modeladmin, request, queryset):
queryset.update(visible=False)


class ContactMessageAdmin(admin.ModelAdmin):
search_fields = ("subject", "email", "author", "status", "user__username")
list_display = ("subject", "email", "author", "status")


class AnnouncementMessageAdmin(admin.ModelAdmin):
form = AnnouncementMessageAdminForm

search_fields = ("title", "announcement")
list_display = ("title", "visible", "announcement", "announcement_type", "updated")
actions = [make_visible, make_invisible]

admin.site.register(ContactMessage, ContactMessageAdmin)
admin.site.register(AnnouncementMessage, AnnouncementMessageAdmin)
41 changes: 39 additions & 2 deletions daiquiri/contact/filters.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from django.core.exceptions import ValidationError
from rest_framework import filters

from .models import ContactMessage
from daiquiri.auth.validators import DaiquiriUsernameValidator


class SpamBackend(filters.BaseFilterBackend):


def filter_queryset(self, request, queryset, view):

from daiquiri.contact.models import ContactMessage

spam = request.GET.get('spam')

if spam is not None:
Expand All @@ -15,3 +19,36 @@ def filter_queryset(self, request, queryset, view):
queryset = queryset.exclude(status=ContactMessage.STATUS_SPAM)

return queryset



class DefaultMessageFilter(object):

CHOICES = (
("no_filter", "Show to all users"),
("logged_in_users", "Show to the logged in users only"),
("user_has_not_consented", "Show to user who has not consented yet"),
("user_has_invalid_username", "Show to user with an invalid username"),
)

def no_filter(request):
return True

def logged_in_users(request):
if request.user.is_authenticated:
return True
return False

def user_has_not_consented(request):
if request.user.is_authenticated:
if not request.user.profile.consent:
return True
return False

def user_has_invalid_username(request):
if request.user.is_authenticated:
try:
DaiquiriUsernameValidator()(request.user.username)
except ValidationError:
return True
return False
30 changes: 30 additions & 0 deletions daiquiri/contact/migrations/0007_announcementmessage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 4.2.5 on 2023-09-20 07:37

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('daiquiri_contact', '0006_alter_contactmessage_id'),
]

operations = [
migrations.CreateModel(
name='AnnouncementMessage',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=100, null=True, verbose_name='Title')),
('announcement', models.TextField(verbose_name='Announcement')),
('announcement_type', models.CharField(choices=[('info', 'info'), ('warning', 'warning'), ('danger', 'urgent')], default='info', max_length=8, verbose_name='Announcement type')),
('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')),
('visible', models.BooleanField(default=False, verbose_name='Visible')),
('visibility_filter', models.CharField(default='no_filter', max_length=50, verbose_name='Visibility filter')),
],
options={
'verbose_name': 'Announcement message',
'verbose_name_plural': 'Announcement messages',
'ordering': ('-updated', 'title'),
},
),
]
61 changes: 61 additions & 0 deletions daiquiri/contact/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import gettext_lazy as _

from daiquiri.core.utils import import_class


class ContactMessage(models.Model):


STATUS_ACTIVE = 'ACTIVE'
STATUS_CLOSED = 'CLOSED'
STATUS_SPAM = 'SPAM'
Expand Down Expand Up @@ -44,3 +48,60 @@ def set_status_active(self):
def set_status_spam(self):
self.status = self.STATUS_SPAM
self.save()



def MessageFilter():
return import_class(settings.ANNOUNCEMENT_MESSAGE_FILTER)

class AnnouncementMessage(models.Model):

# alert types must correspond to the bootstrap alert types
ALERT_TYPE_INFO = "info"
ALERT_TYPE_WARNING = "warning"
ALERT_TYPE_URGENT = "danger"

ANNOUNCEMENT_TYPE_CHOICES = (
(ALERT_TYPE_INFO, "info"),
(ALERT_TYPE_WARNING, "warning"),
(ALERT_TYPE_URGENT, "urgent"),
)

title = models.CharField(
max_length=100, blank=True, null=True,
verbose_name=_("Title")
)
announcement = models.TextField(
verbose_name=_("Announcement")
)
announcement_type = models.CharField(
max_length=8,
choices=ANNOUNCEMENT_TYPE_CHOICES,
default=ALERT_TYPE_INFO,
verbose_name=_("Announcement type")
)
updated = models.DateTimeField(
auto_now=True,
verbose_name=_("Updated")
)
visible = models.BooleanField(
default=False,
verbose_name=_("Visible")
)
visibility_filter = models.CharField(
max_length=50, default="no_filter",
verbose_name="Visibility filter"
)

class Meta:
ordering = ('-updated', 'title')

verbose_name = _('Announcement message')
verbose_name_plural = _('Announcement messages')

def __str__(self):
return f"{self.title}: '{self.announcement}'"

def get_filter(self):
return getattr(MessageFilter(), str(self.visibility_filter))

1 change: 1 addition & 0 deletions daiquiri/contact/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ANNOUNCEMENT_MESSAGE_FILTER = 'daiquiri.contact.filters.DefaultMessageFilter'
8 changes: 8 additions & 0 deletions daiquiri/contact/templates/contact/announcements.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{% if announcements %}
{% for msg in announcements %}
<div class="alert alert-{{ msg.announcement_type }}"
role="alert">
{{ msg.announcement | safe }}
</div>
{% endfor %}
{% endif %}
Empty file.
14 changes: 14 additions & 0 deletions daiquiri/contact/templatetags/announcement_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django import template
from daiquiri.contact.models import AnnouncementMessage

register = template.Library()


@register.inclusion_tag("contact/announcements.html", takes_context=True)
def show_announcements(context):
request = context["request"]
announcements = AnnouncementMessage.objects.filter(visible=True)
announcements = [msg for msg in announcements if msg.get_filter()(request) is True]
return {
"announcements": announcements,
}
1 change: 0 additions & 1 deletion daiquiri/core/templates/core/wide.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{% extends 'core/base.html' %}

{% block content %}

<main class="container">
Expand Down
1 change: 1 addition & 0 deletions testing/config/settings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from daiquiri.auth.settings import *
from daiquiri.conesearch.settings import *
from daiquiri.contact.settings import *
from daiquiri.cutout.settings import *
from daiquiri.datalink.settings import *
from daiquiri.files.settings import *
Expand Down
Loading