Skip to content

Commit fbafa4a

Browse files
authored
Merge pull request #998 from thecourseforum/mvp-enhanced-search
MVP for Enhanced Search
2 parents fbfb73f + 44e27a2 commit fbafa4a

File tree

15 files changed

+10248
-8724
lines changed

15 files changed

+10248
-8724
lines changed

tcf_core/context_processors.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from django.conf import settings
66

7-
from tcf_website.models import Semester
7+
from tcf_website.models import Discipline, Semester, Subdepartment
88

99

1010
def base(request):
@@ -41,3 +41,26 @@ def history_cookies(request):
4141
"previous_path_titles": previous_paths_titles,
4242
"previous_paths_and_titles": previous_paths_and_titles,
4343
}
44+
45+
46+
def searchbar_context(request):
47+
"""Provide context for the search bar."""
48+
latest_semester = Semester.latest()
49+
recent_semesters = Semester.objects.filter(
50+
number__gte=latest_semester.number - 50 # 50 = 5 years * 10 semesters
51+
).order_by("-number")
52+
53+
# Get saved filters from the session (or use defaults)
54+
saved_filters = request.session.get("search_filters", {})
55+
56+
context = {
57+
"disciplines": Discipline.objects.all().order_by("name"),
58+
"subdepartments": Subdepartment.objects.all().order_by("mnemonic"),
59+
"semesters": recent_semesters,
60+
"selected_disciplines": saved_filters.get("disciplines", []),
61+
"selected_subdepartments": saved_filters.get("subdepartments", []),
62+
"selected_weekdays": saved_filters.get("weekdays", []),
63+
"from_time": saved_filters.get("from_time", ""),
64+
"to_time": saved_filters.get("to_time", ""),
65+
}
66+
return context

tcf_core/settings/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"social_django.context_processors.login_redirect",
7171
"tcf_core.context_processors.base",
7272
"tcf_core.context_processors.history_cookies",
73+
"tcf_core.context_processors.searchbar_context",
7374
],
7475
},
7576
},

tcf_website/admin.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,38 @@ def get_queryset(self, request):
6363
return qs
6464

6565

66+
class SectionTimeAdmin(admin.ModelAdmin):
67+
list_display = ["section", "get_days_display", "start_time", "end_time"]
68+
list_filter = ["monday", "tuesday", "wednesday", "thursday", "friday", "start_time", "end_time"]
69+
search_fields = [
70+
"section__course__subdepartment__mnemonic",
71+
"section__course__number",
72+
"section__course__title",
73+
]
74+
autocomplete_fields = ["section"]
75+
76+
def get_days_display(self, obj):
77+
"""Return formatted string of meeting days."""
78+
days = []
79+
if getattr(obj, "monday", False):
80+
days.append("MON")
81+
if getattr(obj, "tuesday", False):
82+
days.append("TUE")
83+
if getattr(obj, "wednesday", False):
84+
days.append("WED")
85+
if getattr(obj, "thursday", False):
86+
days.append("THU")
87+
if getattr(obj, "friday", False):
88+
days.append("FRI")
89+
return ", ".join(days)
90+
91+
get_days_display.short_description = "Days"
92+
93+
def get_queryset(self, request):
94+
qs = super().get_queryset(request)
95+
return qs.select_related("section__course__subdepartment")
96+
97+
6698
class CourseGradeAdmin(admin.ModelAdmin):
6799
ordering = ["course__subdepartment", "course__number", "course__title"]
68100
search_fields = ["course__subdepartment", "course__number"]
@@ -83,3 +115,4 @@ class CourseInstructorGradeAdmin(admin.ModelAdmin):
83115
admin.site.register(Semester, SemesterAdmin)
84116
admin.site.register(CourseGrade, CourseGradeAdmin)
85117
admin.site.register(CourseInstructorGrade, CourseInstructorGradeAdmin)
118+
admin.site.register(SectionTime, SectionTimeAdmin)

tcf_website/management/commands/load_semester.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import re
3+
from datetime import datetime
34

45
import pandas as pd
56
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
@@ -306,4 +307,41 @@ def load_section(
306307
else:
307308
print(f"Retrieved {section}")
308309

310+
def parse_section_times(section_times_str):
311+
if not section_times_str:
312+
return []
313+
314+
times = []
315+
for time_block in section_times_str.split(","):
316+
if not time_block.strip():
317+
continue
318+
try:
319+
days_part, time_part = time_block.strip().split(" ", 1)
320+
start_time, end_time = time_part.split(" - ")
321+
322+
# Create time block with boolean fields
323+
time_data = {
324+
"monday": "Mo" in days_part,
325+
"tuesday": "Tu" in days_part,
326+
"wednesday": "We" in days_part,
327+
"thursday": "Th" in days_part,
328+
"friday": "Fr" in days_part,
329+
"start_time": datetime.strptime(start_time, "%I:%M%p").time(),
330+
"end_time": datetime.strptime(end_time, "%I:%M%p").time(),
331+
}
332+
times.append(time_data)
333+
334+
except (ValueError, IndexError):
335+
continue
336+
337+
return times
338+
339+
# Clear existing section times
340+
section.sectiontime_set.all().delete()
341+
342+
# Create new section times
343+
times = parse_section_times(section_times)
344+
for time_data in times:
345+
SectionTime.objects.create(section=section, **time_data)
346+
309347
return section

0 commit comments

Comments
 (0)