Skip to content

Commit

Permalink
Merge pull request #500 from tamuhack-org/taskqueue
Browse files Browse the repository at this point in the history
task queue code
  • Loading branch information
skandrigi authored Nov 29, 2024
2 parents ffdb5d8 + fa9a0a0 commit c7b1f9a
Show file tree
Hide file tree
Showing 11 changed files with 29 additions and 118 deletions.
2 changes: 2 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
web: gunicorn hiss.wsgi:application --log-file -
worker: celery -A hiss.celery worker --loglevel=info
2 changes: 0 additions & 2 deletions hiss/Procfile

This file was deleted.

5 changes: 1 addition & 4 deletions hiss/application/emails.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ def send_creation_email(app: Application) -> None:
"organizer_email": settings.ORGANIZER_EMAIL,
}

# send_html_email is threaded from the User class
# see user/models.py

app.user.send_html_email.delay(template_name, context, subject)
app.user.send_html_email(template_name, context, subject)

@shared_task
def send_confirmation_email(app_id: int) -> None:
Expand Down
4 changes: 2 additions & 2 deletions hiss/application/fixtures/schools.json
Original file line number Diff line number Diff line change
Expand Up @@ -10984,7 +10984,7 @@
},
{
"model": "application.school",
"pk": 2074,
"pk": 2075,
"fields": {
"name": "Texas A&M University - San Antonio"
}
Expand Down Expand Up @@ -14519,7 +14519,7 @@
},
{
"model": "application.school",
"pk": 2075,
"pk": 2074,
"fields": {
"name": "Other"
}
Expand Down
87 changes: 1 addition & 86 deletions hiss/application/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,92 +401,7 @@ class Application(models.Model):
user = models.ForeignKey("user.User", on_delete=models.CASCADE, null=False)
status = models.CharField(
choices=STATUS_OPTIONS, max_length=1, default=STATUS_PENDING
)

# def get_next_meal_group(self):
# """
# Determines the next meal group considering frontloading for restricted groups
# using the RESTRICTED_FRONTLOAD_FACTOR.
# """
# RESTRICTED_FRONTLOAD_FACTOR = 1.3

# meal_groups = ['A', 'B', 'C', 'D']
# group_distribution = {group: 0 for group in meal_groups}
# restricted_distribution = {group: 0 for group in meal_groups}
# total_confirmed = Application.objects.filter(status='C').exclude(meal_group__isnull=True)

# for group in meal_groups:
# group_distribution[group] = total_confirmed.filter(meal_group=group).count()
# restricted_distribution[group] = total_confirmed.filter(
# meal_group=group,
# dietary_restrictions__icontains="Vegetarian"
# ).count() + total_confirmed.filter(
# meal_group=group,
# dietary_restrictions__icontains="No-Beef"
# ).count() + total_confirmed.filter(
# meal_group=group,
# dietary_restrictions__icontains="No-Pork"
# ).count() + total_confirmed.filter(
# meal_group=group,
# dietary_restrictions__icontains="Food-Allergy"
# ).count()

# total_apps = sum(group_distribution.values())
# total_restricted = sum(restricted_distribution.values())
# if total_apps == 0:
# return meal_groups[0]

# base_restricted_percent = total_restricted / total_apps if total_apps else 0
# target_restricted_percent = {
# group: base_restricted_percent * (RESTRICTED_FRONTLOAD_FACTOR if i < len(meal_groups) // 2 else 1.0)
# for i, group in enumerate(meal_groups)
# }
# target_restricted_count = {
# group: target_restricted_percent[group] * group_distribution[group] if group_distribution[group] > 0 else 0
# for group in meal_groups
# }

# restricted_gap = {
# group: target_restricted_count[group] - restricted_distribution[group]
# for group in meal_groups
# }
# prioritized_group = max(restricted_gap, key=restricted_gap.get)

# last_assigned_group = (
# total_confirmed.order_by('-datetime_submitted')
# .values_list('meal_group', flat=True)
# .first()
# )
# if last_assigned_group:
# next_index = (meal_groups.index(last_assigned_group) + 1) % len(meal_groups)
# else:
# next_index = 0

# # use frontloaded group if it aligns with round-robin or is significantly better
# if prioritized_group == meal_groups[next_index]:
# return meal_groups[next_index]
# elif restricted_gap[prioritized_group] > restricted_gap[meal_groups[next_index]]:
# return prioritized_group
# else:
# return meal_groups[next_index]

# def assign_meal_group(self):
# """
# Assigns a meal group based on the current status and dietary restrictions.
# """
# if self.status == 'C': # Confirmed
# self.meal_group = self.get_next_meal_group()
# elif self.status == 'E': # Waitlisted
# self.meal_group = 'E'
# else:
# self.meal_group = None

# def save(self, *args, **kwargs):
# """
# Overrides save to ensure meal group assignment logic is applied.
# """
# self.assign_meal_group()
# super().save(*args, **kwargs)
)

# ABOUT YOU
first_name = models.CharField(
Expand Down
9 changes: 4 additions & 5 deletions hiss/application/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.views import generic
from django.db import transaction

from application.emails import send_confirmation_email, send_creation_email
from application.forms import ApplicationModelForm
from application.models import (
Expand Down Expand Up @@ -103,10 +103,9 @@ def post(self, request: HttpRequest, *args, **kwargs):
raise PermissionDenied(
"You can't confirm your application if it hasn't been approved."
)
with transaction.atomic():
app.status = STATUS_CONFIRMED
app.save()
send_confirmation_email(app)
app.status = STATUS_CONFIRMED
app.save()
send_confirmation_email(app)
return redirect(reverse_lazy("status"))


Expand Down
6 changes: 3 additions & 3 deletions hiss/customauth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.http import HttpResponse
from django.shortcuts import redirect, render, get_object_or_404
from django.urls import reverse_lazy
from django.utils.encoding import force_bytes, force_str
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.views import generic

Expand All @@ -26,7 +26,7 @@ def send_confirmation_email(curr_domain: RequestSite, user: User) -> None:
"event_name": settings.EVENT_NAME,
"organizer_name": settings.ORGANIZER_NAME,
}
user.send_html_email.delay(template_name, context, subject)
user.send_html_email(template_name, context, subject)


# Create your views here.
Expand Down Expand Up @@ -58,7 +58,7 @@ class ActivateView(views.View):
def get(self, request, *_args, **kwargs):
user = None
try:
uid = force_str(urlsafe_base64_decode(kwargs["uidb64"]))
uid = force_text(urlsafe_base64_decode(kwargs["uidb64"]))
user = get_user_model().objects.get(id=int(uid))
except (
TypeError,
Expand Down
15 changes: 11 additions & 4 deletions hiss/hiss/celery.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
from __future__ import absolute_import, unicode_literals
import os

import ssl
from celery import Celery

# Set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hiss.settings.dev')

app = Celery('hiss')
app = Celery('hiss',
broker_use_ssl={
'ssl_cert_reqs': ssl.CERT_NONE,
},
redis_backend_use_ssl = {
'ssl_cert_reqs': ssl.CERT_NONE,
}
)

# Using a string here so the worker doesn't have to serialize the object to child processes.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

# Celery configuration for Redis as the broker and result backend
app.conf.broker_url = os.environ.get('REDIS_URL', 'redis://localhost:6379/0')
app.conf.result_backend = os.environ.get('REDIS_URL', 'redis://localhost:6379/0')
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

@app.task(bind=True)
def debug_task(self):
Expand Down
2 changes: 1 addition & 1 deletion hiss/hiss/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY")
AWS_S3_BUCKET_NAME = "2025-th-resumes"
AWS_S3_KEY_PREFIX = "prod"

ALLOWED_HOSTS = ['*',"https://register.tamuhack.com/","http://register.tamuhack.com/","register.tamuhack.com/","register.tamuhack.com", 'localhost', '127.0.0.1']
STATIC_URL = "/" + BASE_PATHNAME + "static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "..", "static/")]
STATIC_ROOT = "public/"
Expand Down
2 changes: 1 addition & 1 deletion hiss/hiss/settings/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ["register.tamuhack.com", 'localhost', '127.0.0.1']
ALLOWED_HOSTS = ['*',"https://register.tamuhack.com/","http://register.tamuhack.com/","register.tamuhack.com/","register.tamuhack.com", 'localhost', '127.0.0.1']
SESSION_COOKIE_SECURE = False
SECURE_BROWSER_XSS_FILTER = False
CSRF_COOKIE_SECURE = False
Expand Down
13 changes: 3 additions & 10 deletions hiss/user/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,11 @@ class User(auth_models.AbstractUser):
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []

@shared_task
def send_html_email(template_name, context, subject, recipient_email):
"""Celery task to send an HTML email."""
def send_html_email(self, template_name, context, subject):
"""Send an HTML email to the user."""
html_msg = render_to_string(template_name, context)
plain_msg = strip_tags(html_msg)
send_mail(
subject=subject,
message=plain_msg,
from_email=settings.ORGANIZER_EMAIL,
recipient_list=[recipient_email],
html_message=html_msg,
)
self.email_user(subject, plain_msg, from_email=None, html_message=html_msg)


@receiver(post_save, sender=settings.AUTH_USER_MODEL)
Expand Down

0 comments on commit c7b1f9a

Please sign in to comment.