-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
177eff6
commit a7254ab
Showing
2 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import json | ||
import logging | ||
|
||
from django.core.management.base import BaseCommand | ||
from tqdm import tqdm | ||
|
||
from alert.models import Course, Section | ||
from courses import registrar | ||
from courses.util import get_course_and_section, get_current_semester, translate_semester_inv | ||
|
||
|
||
class Command(BaseCommand): | ||
help = """ | ||
Generate an audit report that demonstrates the differences between our | ||
database and the course statuses received from using the OpenData | ||
endpoint directly. | ||
Note that this script DOES NOT make any changes to the database, just | ||
generates a textfile report | ||
""" | ||
|
||
def handle(self, *args, **options): | ||
root_logger = logging.getLogger("") | ||
root_logger.setLevel(logging.DEBUG) | ||
|
||
semester = get_current_semester() | ||
statuses = registrar.get_all_course_status(semester) | ||
stats = { | ||
"missing_data": 0, | ||
"section_not_found": 0, | ||
"duplicate_updates": 0, | ||
"unsynced_updates": 0, | ||
} | ||
unsynced_courses = [] | ||
for status in tqdm(statuses): | ||
data = status | ||
section_code = data.get("section_id_normalized") | ||
if section_code is None: | ||
stats["missing_data"] += 1 | ||
continue | ||
|
||
course_status = data.get("status") | ||
if course_status is None: | ||
stats["missing_data"] += 1 | ||
continue | ||
|
||
course_term = data.get("term") | ||
if course_term is None: | ||
stats["missing_data"] += 1 | ||
continue | ||
if any(course_term.endswith(s) for s in ["10", "20", "30"]): | ||
course_term = translate_semester_inv(course_term) | ||
|
||
# Ignore sections not in db | ||
try: | ||
_, section = get_course_and_section(section_code, semester) | ||
except (Section.DoesNotExist, Course.DoesNotExist): | ||
stats["section_not_found"] += 1 | ||
continue | ||
|
||
# Ignore duplicate updates | ||
last_status_update = section.last_status_update | ||
current_status = section.status | ||
if current_status == course_status: | ||
stats["duplicate_updates"] += 1 | ||
continue | ||
|
||
stats["unsynced_updates"] += 1 | ||
unsynced_courses.append( | ||
(section_code, last_status_update.new_status, current_status, course_status) | ||
) | ||
|
||
# Write out statistics and missing courses to an output file. | ||
with open("./status_audit.txt", "w") as f: | ||
f.write("Summary Statistics\n") | ||
f.write(json.dumps(stats) + "\n\n") | ||
|
||
f.write( | ||
"""Courses Out of Sync\nCourse Code / Last Update Status / | ||
Our Stored Status / Actual Status\n""" | ||
) | ||
f.write("Our Status Matches Last Update\n") | ||
f.writelines( | ||
[ | ||
f"{course[0]} / {course[1]} / {course[2]} / {course[3]}\n" | ||
for course in unsynced_courses | ||
if course[1] == course[2] | ||
] | ||
) | ||
|
||
f.write("\nOur Status Does Not Match Last Update\n") | ||
f.writelines( | ||
[ | ||
f"{course[0]} / {course[1]} / {course[2]} / {course[3]}\n" | ||
for course in unsynced_courses | ||
if course[1] != course[2] | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
Summary Statistics | ||
{"missing_data": 0, "section_not_found": 0, "duplicate_updates": 5711, "unsynced_updates": 49} | ||
|
||
Courses Out of Sync | ||
Course Code / Last Update Status /Our Stored Status / Actual Status | ||
Our Status Matches Last Update | ||
ANTH-2550-401 / C / C / O | ||
BE-2000-201 / O / O / C | ||
BE-5650-001 / C / C / O | ||
BEPP-2020-402 / C / C / O | ||
BEPP-2030-001 / C / C / O | ||
CHEM-2412-142 / C / C / O | ||
CHEM-2510-220 / O / O / C | ||
COMM-6030-401 / O / O / C | ||
EDUC-5256-001 / C / C / O | ||
ESE-2040-001 / O / O / X | ||
ESE-2040-201 / O / O / X | ||
ESE-2180-001 / C / C / O | ||
ESE-2180-101 / C / C / O | ||
FNAR-1070-402 / C / C / O | ||
FNAR-5011-402 / C / C / O | ||
FNCE-2020-402 / C / C / O | ||
GRMN-1800-001 / O / O / C | ||
HSOC-2002-403 / C / C / O | ||
LGST-2190-001 / O / O / C | ||
LGST-2920-402 / O / O / C | ||
MGMT-2920-402 / O / O / C | ||
MGMT-3010-001 / C / C / O | ||
MGMT-3010-005 / C / C / O | ||
NURS-1640-110 / C / C / O | ||
OIDD-2920-402 / O / O / C | ||
PSCI-1800-204 / C / C / O | ||
PSYC-1777-001 / C / C / O | ||
SAST-2550-401 / C / C / O | ||
SOCI-2000-403 / C / C / O | ||
SPAN-1800-303 / C / C / O | ||
SSPP-6030-401 / O / O / C | ||
SWRK-6020-001 / C / C / O | ||
SWRK-6030-003 / C / C / O | ||
SWRK-7770-001 / O / O / C | ||
|
||
Our Status Does Not Match Last Update | ||
ANTH-0120-404 / C / O / C | ||
BIOL-1101-102 / O / C / O | ||
CHEM-1102-185 / O / C / O | ||
CIS-1210-214 / C / O / C | ||
EALC-0730-406 / C / O / C | ||
HIST-0550-406 / C / O / C | ||
LALS-4240-401 / C / O / C | ||
MEAM-2100-202 / O / C / O | ||
MEAM-2470-101 / O / C / O | ||
MSSP-6340-001 / C / O / C | ||
PHIL-1380-301 / C / O / C | ||
PSCI-0200-202 / O / C / O | ||
SOCI-2910-404 / C / O / C | ||
SOCI-2931-401 / C / O / C | ||
SWRK-6020-005 / O / C / O |