Compare commits

..

2 commits

8 changed files with 44 additions and 31 deletions

View file

@ -2,5 +2,12 @@ firefox/
chrome/
dumps/
media/
TODO.md
.env
static/
documentation/
.env
.venv/
.vscode/
.git/
.gitignore
.woodpecker/
**/__pycache__/

View file

@ -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

View file

@ -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,

View file

@ -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:

View file

@ -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"

View file

@ -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)

View file

@ -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)

View file

@ -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
}