Skip to content
Open
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
89 changes: 87 additions & 2 deletions hiss/application/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from address.models import AddressField
from django import forms
from django.conf import settings
from django.contrib import admin
from django.contrib import admin, messages
from django.contrib.admin.filters import RelatedOnlyFieldListFilter
from django.db import transaction
from django.db.models.query import QuerySet
Expand All @@ -25,9 +25,22 @@
Wave,
)
from shared.admin_functions import send_mass_html_mail

from django.contrib.auth import get_user_model
from django.contrib.admin.filters import RelatedOnlyFieldListFilter
from django.utils.crypto import get_random_string
from application.models import Application, Wave
from django.db import transaction
from django.core.files.base import ContentFile

class ApplicationAdminForm(forms.ModelForm):

num_to_create = forms.IntegerField(
label="Number of users to create",
help_text="If > 1, this will create multiple test users based on the data entered above.",
min_value=1,
initial=1,
required=False
)
class Meta:
model = Application
fields = "__all__" # noqa: DJ007
Expand Down Expand Up @@ -289,6 +302,13 @@
"Miscellaneous",
{"fields": ["notes", "is_adult", "accessibility_requirements"]},
),
(
"Bulk Creation (For Testing)",
{
"classes": ("collapse",),
"fields": ["num_to_create"],
},
),
]
formfield_overrides = {
AddressField: {"widget": AddressWidget(attrs={"style": "width: 300px;"})}
Expand Down Expand Up @@ -319,6 +339,71 @@
@staticmethod
def is_a_walk_in(obj: Application) -> bool:
return obj.wave.is_walk_in_wave

# save model called automatically when creating new test user
def save_model(self, request, obj, form, change):
"""

Check failure on line 345 in hiss/application/admin.py

View workflow job for this annotation

GitHub Actions / Check code quality and health with ruff

Ruff (W293)

hiss/application/admin.py:345:1: W293 Blank line contains whitespace
overrides admin save function to allow for creating many users at once

it loops that num_to_create times (if num_to_create > 1), creating a unique user and a temporary wave for each application

Check failure on line 348 in hiss/application/admin.py

View workflow job for this annotation

GitHub Actions / Check code quality and health with ruff

Ruff (W293)

hiss/application/admin.py:348:1: W293 Blank line contains whitespace
if creating many, it uses dummy resume to save time

if just editing an application, it saves it normally
"""
if not change:
num_to_create = form.cleaned_data.get('num_to_create', 1)
template_data = form.cleaned_data.copy()

template_data.pop('num_to_create', None)
original_resume = template_data.pop('resume', None)

resume_to_use = (
ContentFile(b"dummy resume", name="dummy.txt")
if num_to_create > 1
else original_resume
)

users_to_process = []
apps_to_create = []

user_model = get_user_model()
email_prefix, domain = template_data['tamu_email'].split('@')

for _ in range(num_to_create):
email_to_use = f"{email_prefix}+{get_random_string(6)}@{domain}"
user, created = user_model.objects.get_or_create(email=email_to_use)
if created:
user.set_password(get_random_string(12))
user.save()
users_to_process.append(user)

with transaction.atomic():
now = timezone.now()
instant_wave = Wave.objects.create(
start=now,
end=now,
num_days_to_rsvp=0,
is_walk_in_wave=True
)

for user in users_to_process:
app_data = template_data.copy()
app_data.update({
'user': user,
'wave': instant_wave,
'tamu_email': user.email,
'resume': resume_to_use,
'agree_to_coc': True,
'status': 'P',
'grad_year': 2027,
})
apps_to_create.append(Application(**app_data))

Application.objects.bulk_create(apps_to_create)

self.message_user(request, f"Successfully created {len(apps_to_create)} application(s).", messages.SUCCESS)
else:
super().save_model(request, obj, form, change)


class WaveAdmin(admin.ModelAdmin):
Expand Down
23 changes: 23 additions & 0 deletions hiss/hiss/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@

GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY", "")

# DJANGO_HUEY = {
# 'huey_class': 'huey.RedisHuey',
# 'name': 'default',
# 'connection': {
# 'host': 'localhost',
# 'port': 6379,
# 'db': 0,
# },
# 'consumer': {
# 'workers': 4,
# 'worker_type': 'thread',
# },
# }
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
Expand All @@ -53,9 +66,19 @@
"django_s3_storage",
"address",
"rangefilter",
# "django_huey",
# "bx_django_utils",
# "huey_monitor",
"judgesmentors.apps.JudgesmentorsConfig",
]

DJANGO_HUEY_MONITOR = {
"results_url": True,
"enable_stats": True,
"stats_url": True,
"base_url": "huey/",
}

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware",
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ dependencies = [
"django-admin-rangefilter>=0.13.2",
"django-anymail>=12.0",
"django-cors-headers>=4.7.0",
"django-huey>=1.3.0",
"django-huey-monitor>=0.10.1",
"django-multiselectfield>=0.1.13",
"django-phonenumber-field>=8.0.0",
"django-s3-storage>=0.15.0",
Expand All @@ -38,6 +40,7 @@ dependencies = [
"google-resumable-media>=2.7.2",
"googleapis-common-protos>=1.68.0",
"gunicorn>=23.0.0",
"huey>=2.5.3",
"idna>=3.10",
"phonenumbers>=8.13.55",
"protobuf>=5.29.3",
Expand All @@ -48,6 +51,7 @@ dependencies = [
"pyqrcode>=1.2.1",
"pytz>=2025.1",
"qrtools>=0.0.2",
"redis>=6.2.0",
"requests>=2.32.3",
"rsa>=4.9",
"six>=1.17.0",
Expand Down
Loading
Loading