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

Dev #65

Merged
merged 28 commits into from
Mar 27, 2024
Merged

Dev #65

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
81f0c49
Added course information mappings (#46)
KarenAJ Jul 22, 2022
34db4af
updated mysql-connector-python version
sammy-sandhu Jul 28, 2022
5f81497
Bugfix/searching fields (#49)
KarenAJ Aug 17, 2022
992705c
Bugfix/xis_pagination (#48)
JDTobin Aug 18, 2022
f450351
Bugfix/searching fields (#51)
KarenAJ Aug 18, 2022
496ff4f
Fixed views for new xis api's (#52)
KarenAJ Aug 18, 2022
46d9545
fix accepting dicts into metadata_to_target (#54)
JDTobin Aug 22, 2022
f27100b
resolves various p1 issues (#55)
JDTobin Mar 21, 2023
9b8cdd6
add derived from (#56)
JDTobin Aug 7, 2023
5919606
updated workflow
sammy-sandhu Nov 9, 2023
3a6a5df
updated workflow
sammy-sandhu Nov 9, 2023
a955eec
Merge pull request #59 from OpenLXP/ecr-actions
RyanKingDeloitte Nov 14, 2023
dd8b4f9
increase test coverage (#60)
JDTobin Nov 22, 2023
e10a47d
Django admin UI overhaul (#61)
schittlur Feb 22, 2024
bed061f
Update cd-workflow.yml
sammy-sandhu Feb 27, 2024
c2642be
adding bleach (#57)
KarenAJ Mar 7, 2024
4450f08
Merge branch 'main' into dev
KarenAJ Mar 7, 2024
c732532
Update admin.py
KarenAJ Mar 7, 2024
6de43e1
Update docker-compose.yml
KarenAJ Mar 7, 2024
ed64ec0
Fixed Images
KarenAJ Mar 7, 2024
5018757
Update Images
KarenAJ Mar 7, 2024
72feb0b
add api notifications support
JDTobin Mar 14, 2024
2e8d216
add list name to notifications data
JDTobin Mar 15, 2024
b9f1cc9
add notification commands
JDTobin Mar 22, 2024
522f651
fix file format
JDTobin Mar 22, 2024
ce3e94a
add tests for commands
JDTobin Mar 22, 2024
a5e0734
Merge pull request #64 from OpenLXP/api-notifications
JDTobin Mar 26, 2024
61e06cd
Merge branch 'main' into dev
JDTobin Mar 27, 2024
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
5 changes: 5 additions & 0 deletions app/core/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,8 @@

class CoreConfig(AppConfig):
name = 'core'

def ready(self):
super(CoreConfig, self).ready()
import core.signals
core.signals.interest_list_notify
Empty file.
35 changes: 35 additions & 0 deletions app/core/management/commands/clear_old_notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from datetime import timedelta

from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils import timezone
from notifications.base.models import is_soft_delete
from notifications.models import Notification


class Command(BaseCommand):
"""This command deletes notifications that are older than some limit"""

def handle(self, *args, **options):
expiration_delta = settings.NOTIFICATIONS_EXPIRE_AFTER
if expiration_delta and isinstance(expiration_delta, timedelta):
curr = timezone.now()
limit = curr - expiration_delta
bad_notifications = Notification.objects.all().\
filter(timestamp__date__lt=limit)
if is_soft_delete():
bad_notifications.mark_all_as_deleted()
self.stdout.write(
self.style.SUCCESS(f"{bad_notifications.count()} old"
" notifications marked deleted"))
else:
count, _ = bad_notifications.delete()
self.stdout.write(
self.style.SUCCESS(f"{count} old notifications deleted"))
else:
self.stdout.write(
self.style.WARNING(
"NOTIFICATIONS_EXPIRE_AFTER must be set to "
"a timedelta in settings.py "
)
)
19 changes: 19 additions & 0 deletions app/core/management/commands/clear_read_notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.core.management.base import BaseCommand
from notifications.base.models import is_soft_delete
from notifications.models import Notification


class Command(BaseCommand):
"""This command deletes notifications that have already been read"""

def handle(self, *args, **options):
bad_notifications = Notification.objects.all().read()
if is_soft_delete():
bad_notifications.mark_all_as_deleted()
self.stdout.write(
self.style.SUCCESS(f"{bad_notifications.count()} read"
" notifications marked deleted"))
else:
count, _ = bad_notifications.delete()
self.stdout.write(
self.style.SUCCESS(f"{count} read notifications deleted"))
13 changes: 13 additions & 0 deletions app/core/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from notifications.signals import notify

from .models import InterestList


@receiver(m2m_changed, sender=InterestList.experiences.through)
def interest_list_notify(sender, instance, action, reverse, pk_set, **kwargs):
if action == 'post_add' and not reverse:
notify.send(instance, recipient=instance.subscribers.all(),
verb='experiences added', added=pk_set,
list_name=instance.name)
73 changes: 73 additions & 0 deletions app/core/tests/test_commands_unit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from django.conf import settings
from django.core.management import call_command
from django.test import tag

from core.models import Experience, InterestList
from users.models import XDSUser

from .test_setup import TestSetUp


@tag('unit')
class CommandTests(TestSetUp):
"""Test cases for notification commands """

def test_clear_old_notifications(self):
"""Test that only old notifications are cleared"""
id = '12345'
course = Experience(metadata_key_hash=id)
course.save()
id_2 = '54321'
course_2 = Experience(metadata_key_hash=id_2)
course_2.save()
user = XDSUser.objects.create_user(self.email,
self.password,
first_name=self.first_name,
last_name=self.last_name)
list = InterestList(owner=user,
name="test list",
description="test desc")
list.save()
list.subscribers.add(user)
list.experiences.add(course)
self.assertEqual(user.notifications.count(), 1)

expiration_delta = settings.NOTIFICATIONS_EXPIRE_AFTER

notification_old = user.notifications.first()
notification_old.timestamp = notification_old.timestamp - \
expiration_delta - expiration_delta
notification_old.mark_as_read()

list.experiences.add(course_2)
self.assertEqual(user.notifications.count(), 2)

call_command('clear_old_notifications')
self.assertEqual(user.notifications.count(), 1)

def test_clear_read_notifications(self):
"""Test that only read notifications are cleared"""
id = '12345'
course = Experience(metadata_key_hash=id)
course.save()
id_2 = '54321'
course_2 = Experience(metadata_key_hash=id_2)
course_2.save()
user = XDSUser.objects.create_user(self.email,
self.password,
first_name=self.first_name,
last_name=self.last_name)
list = InterestList(owner=user,
name="test list",
description="test desc")
list.save()
list.subscribers.add(user)
list.experiences.add(course)
self.assertEqual(user.notifications.count(), 1)

user.notifications.first().mark_as_read()
list.experiences.add(course_2)
self.assertEqual(user.notifications.count(), 2)

call_command('clear_read_notifications')
self.assertEqual(user.notifications.count(), 1)
11 changes: 11 additions & 0 deletions app/openlxp_xds_project/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
https://docs.djangoproject.com/en/3.1/ref/settings/
"""

import datetime
import mimetypes
import os
import sys
Expand Down Expand Up @@ -53,6 +54,7 @@
'es_api',
'users',
'configurations',
'notifications',
]

MIDDLEWARE = [
Expand Down Expand Up @@ -269,4 +271,13 @@

EMAIL_BACKEND = 'django_ses.SESBackend'


# Django-notifications package settings
DJANGO_NOTIFICATIONS_CONFIG = {
'USE_JSONFIELD': True,
}

# when notifications should be automatically deleted, should be days or greater
NOTIFICATIONS_EXPIRE_AFTER = datetime.timedelta(days=30)

DATA_UPLOAD_MAX_MEMORY_SIZE = 5242880
3 changes: 3 additions & 0 deletions app/openlxp_xds_project/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
import notifications.urls
from django.conf import settings
from django.conf.urls import url
from django.conf.urls.static import static
Expand All @@ -29,4 +30,6 @@
path('api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
url('', include('openlxp_authentication.urls')),
url('^inbox/notifications/',
include(notifications.urls, namespace='notifications')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Django>=3.2.3,<4.0

djangorestframework>=3.12.2,<3.13.0

django-notifications-hq>=1.8.3, <2.0

flake8>=3.8.4,<3.9.0

gunicorn>=20.0.4,<20.1.0
Expand Down
Loading