From f7b949a45e448e7457ce4ff67170749800b882cd Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Wed, 13 Nov 2024 17:43:36 +0800 Subject: [PATCH 1/2] Move to using inline todos, update .dockerignore, and remove duplicate timezone records in seed data --- .dockerignore | 11 +++++++++-- backend/accounts/signals.py | 14 ++++++++------ backend/accounts/views.py | 3 ++- backend/emails/templates.py | 2 ++ backend/notifications/models.py | 8 +++++++- backend/notifications/views.py | 16 +++++++--------- seed_data.json | 15 +++++---------- 7 files changed, 40 insertions(+), 29 deletions(-) diff --git a/.dockerignore b/.dockerignore index 177581c..e51d396 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,5 +2,12 @@ firefox/ chrome/ dumps/ media/ -TODO.md -.env \ No newline at end of file +static/ +documentation/ +.env +.venv/ +.vscode/ +.git/ +.gitignore +.woodpecker/ +**/__pycache__/ diff --git a/backend/accounts/signals.py b/backend/accounts/signals.py index aabbc68..26e2a5b 100644 --- a/backend/accounts/signals.py +++ b/backend/accounts/signals.py @@ -1,7 +1,7 @@ import json import os -from config.settings import ROOT_DIR, SEED_DATA, get_secret +from config.settings import ROOT_DIR, SEED_DATA, TIME_ZONE, get_secret from django.db.models.signals import post_migrate from django.dispatch import receiver from django_celery_beat.models import CrontabSchedule, PeriodicTask @@ -64,7 +64,7 @@ def create_celery_beat_schedules(sender, **kwargs): day_of_week=schedule["day_of_week"], day_of_month=schedule["day_of_month"], month_of_year=schedule["month_of_year"], - timezone=schedule["timezone"], + timezone=TIME_ZONE, ).first() # If it does not exist, create a new Schedule if not SCHEDULE: @@ -74,14 +74,16 @@ def create_celery_beat_schedules(sender, **kwargs): day_of_week=schedule["day_of_week"], day_of_month=schedule["day_of_month"], month_of_year=schedule["month_of_year"], - timezone=schedule["timezone"], + timezone=TIME_ZONE, ) print( - f"Created Crontab Schedule for Hour:{SCHEDULE.hour},Minute:{SCHEDULE.minute}" + f"Created Crontab Schedule for Hour:{ + SCHEDULE.hour},Minute:{SCHEDULE.minute}" ) else: print( - f"Crontab Schedule for Hour:{SCHEDULE.hour},Minute:{SCHEDULE.minute} already exists" + f"Crontab Schedule for Hour:{SCHEDULE.hour},Minute:{ + SCHEDULE.minute} already exists" ) for task in seed_data["scheduled_tasks"]: TASK = PeriodicTask.objects.filter(name=task["name"]).first() @@ -93,7 +95,7 @@ def create_celery_beat_schedules(sender, **kwargs): day_of_week=task["schedule"]["day_of_week"], day_of_month=task["schedule"]["day_of_month"], month_of_year=task["schedule"]["month_of_year"], - timezone=task["schedule"]["timezone"], + timezone=TIME_ZONE, ).first() TASK = PeriodicTask.objects.create( crontab=SCHEDULE, diff --git a/backend/accounts/views.py b/backend/accounts/views.py index fa778de..7a49d5f 100644 --- a/backend/accounts/views.py +++ b/backend/accounts/views.py @@ -41,7 +41,8 @@ class CustomUserViewSet(DjoserUserViewSet): key = f"usergroup_users:{user.user_group.id}" queryset = cache.get(key) if not queryset: - queryset = CustomUser.objects.filter(user_group=user.user_group) + queryset = CustomUser.objects.filter( + user_group=user.user_group) cache.set(key, queryset, 60 * 60) return queryset else: diff --git a/backend/emails/templates.py b/backend/emails/templates.py index 056fc28..a30f20d 100644 --- a/backend/emails/templates.py +++ b/backend/emails/templates.py @@ -9,6 +9,8 @@ class ActivationEmail(email.ActivationEmail): class PasswordResetEmail(email.PasswordResetEmail): template_name = "password_change.html" +# TODO: Fix email template values not filling in properly + class SubscriptionAvailedEmail(email.BaseEmailMessage): template_name = "subscription_availed.html" diff --git a/backend/notifications/models.py b/backend/notifications/models.py index c76576e..e4fb451 100644 --- a/backend/notifications/models.py +++ b/backend/notifications/models.py @@ -1,11 +1,17 @@ +from django.core.cache import cache from django.db import models class Notification(models.Model): - recipient = models.ForeignKey("accounts.CustomUser", on_delete=models.CASCADE) + recipient = models.ForeignKey( + "accounts.CustomUser", on_delete=models.CASCADE) content = models.CharField(max_length=1000, null=True) timestamp = models.DateTimeField(auto_now_add=True, editable=False) dismissed = models.BooleanField(default=False) def __str__(self): return self.content + + def save(self, **kwargs): + cache.delete(f"notifications_user:{self.recipient.id}") + super().save(**kwargs) diff --git a/backend/notifications/views.py b/backend/notifications/views.py index 0057b6e..4f933f5 100644 --- a/backend/notifications/views.py +++ b/backend/notifications/views.py @@ -3,12 +3,14 @@ from notifications.models import Notification from notifications.serializers import NotificationSerializer from rest_framework import viewsets from rest_framework.exceptions import PermissionDenied +from rest_framework.permissions import IsAuthenticated class NotificationViewSet(viewsets.ModelViewSet): - http_method_names = ["get", "patch", "delete"] + http_method_names = ["get", "delete"] serializer_class = NotificationSerializer queryset = Notification.objects.all() + permission_classes = [IsAuthenticated] def get_queryset(self): user = self.request.user @@ -21,18 +23,14 @@ class NotificationViewSet(viewsets.ModelViewSet): cache.set(key, queryset, 60 * 60) return queryset - def update(self, request, *args, **kwargs): - instance = self.get_object() - if instance.recipient != request.user: - raise PermissionDenied( - "You do not have permission to update this notification." - ) - return super().update(request, *args, **kwargs) - def destroy(self, request, *args, **kwargs): instance = self.get_object() + user = self.request.user if instance.recipient != request.user: raise PermissionDenied( "You do not have permission to delete this notification." ) + + cache.delete(f"notifications_user:{user.id}") + return super().destroy(request, *args, **kwargs) diff --git a/seed_data.json b/seed_data.json index 0371139..41ae371 100644 --- a/seed_data.json +++ b/seed_data.json @@ -6,8 +6,7 @@ "hour": "0", "day_of_week": "*", "day_of_month": "*", - "month_of_year": "*", - "timezone": "Asia/Manila" + "month_of_year": "*" }, { "type": "crontab", @@ -15,8 +14,7 @@ "hour": "1", "day_of_week": "*", "day_of_month": "*", - "month_of_year": "*", - "timezone": "Asia/Manila" + "month_of_year": "*" }, { "type": "crontab", @@ -24,8 +22,7 @@ "hour": "12", "day_of_week": "*", "day_of_month": "*", - "month_of_year": "*", - "timezone": "Asia/Manila" + "month_of_year": "*" }, { "type": "crontab", @@ -33,8 +30,7 @@ "hour": "13", "day_of_week": "*", "day_of_month": "*", - "month_of_year": "*", - "timezone": "Asia/Manila" + "month_of_year": "*" } ], "scheduled_tasks": [ @@ -47,8 +43,7 @@ "hour": "1", "day_of_week": "*", "day_of_month": "*", - "month_of_year": "*", - "timezone": "Asia/Manila" + "month_of_year": "*" }, "enabled": true } From e79a1777c1a08d3e693c9f4f40a9496b54b3ab06 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Wed, 13 Nov 2024 18:18:05 +0800 Subject: [PATCH 2/2] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9cff4a1..5065ba4 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,13 @@ A live API demo can be found [here](https://api.template.06222001.xyz/api/v1/swa - Populate .env with values - Run `docker-compose -f docker-compose.dev.yml up` -When using `docker-compose.dev.yml`, the entire project directory is mounted onto the container allowing for hot-reloading. Make sure DEBUG is set to True for this to work! Be sure to follow through the steps shown in the `stripe-listener` container for initial setup with Stripe! +When using `docker-compose.dev.yml`, the entire project directory is mounted onto the container allowing for hot-reloading. This requires `DEBUG` to be set to `True`. + +Also make sure to follow through the steps shown in the `stripe-listener` container for initial setup with Stripe. ### Deployment -A sample `docker-compose.yml` is provided which I use in hosting the demo. DEBUG should be set to False when deploying as to not expose the URLs fro Celery Flower and the Django Silk Profiler. The local Inbucket container is not present so make sure to specify an external SMTP server to process emails properly. +A sample `docker-compose.yml` is provided which I use in hosting the demo. `DEBUG` should be set to `False` when deploying as to not expose the URLs fro Celery Flower and the Django Silk Profiler. The local Inbucket container is not present with `DEBUG` turned off so make sure to specify an external SMTP server to process emails properly. ### URLs