From 5e259b1d659a796142f66066bdaeaf58d87b19c4 Mon Sep 17 00:00:00 2001 From: Christopher Bohn <bohn@unl.edu> Date: Wed, 21 Jul 2021 16:43:39 -0500 Subject: [PATCH] Can retrieve students' majors from UNL directory --- common_functions.py | 20 +++++++++++++++++++- majors.py | 46 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/common_functions.py b/common_functions.py index d0dc86c..dc4cbac 100644 --- a/common_functions.py +++ b/common_functions.py @@ -1,6 +1,10 @@ import datetime +import json import re -from typing import List, Optional, TypeVar +import ssl +from typing import Dict, List, Any, Optional, TypeVar +from urllib import request +from urllib.error import HTTPError ChoiceType = TypeVar("ChoiceType") @@ -51,3 +55,17 @@ def semester_stamp() -> str: else: month = 8 return f'{year}-0{month}' + + +def finger(login: str, directory: str = 'https://directory.unl.edu/people/') -> Dict[str, Any]: + finger_url: str = f'{directory}{login}.json' + self_signed_ssl_okay: ssl.SSLContext = ssl.create_default_context() + self_signed_ssl_okay.check_hostname = False + self_signed_ssl_okay.verify_mode = ssl.CERT_NONE + data: str + try: + with request.urlopen(finger_url, context=self_signed_ssl_okay) as response: + data = str(response.read(), 'UTF=8') + except HTTPError: + data = f'{{"cn":"{login}", "unlSISClassLevel":["Unknown"], "unlSISMajor":["Unknown"]}}' + return json.loads(data) diff --git a/majors.py b/majors.py index 4df8d5c..74c391b 100644 --- a/majors.py +++ b/majors.py @@ -1,16 +1,48 @@ -from typing import Set +from typing import Dict, Set, Any, Optional + +from common_functions import finger class Major: majors: Set["Major"] = set() - def __init__(self, name: str, abbreviations: Set[str]): + def __init__(self, name: str, alternate_names: Set[str] = None, + abbreviations: Optional[Set[str]] = None, is_cse_major: bool = True): self.name: str = name - self.abbreviations: Set[str] = abbreviations + self.alternate_names: Set[str] = alternate_names if alternate_names is not None else set() + self.abbreviations: Set[str] = abbreviations if abbreviations is not None else set() + self.is_cse_major: bool = is_cse_major Major.majors.add(self) + @classmethod + def get_major(cls, name: str) -> "Major": + candidate = [major for major in cls.majors if name == major.name or name in major.alternate_names] + if candidate: + return candidate[0] + else: + return Major(name, is_cse_major=False) + + @staticmethod + def get_student_majors(login: str) -> Set["Major"]: + student_data: Dict[str, Any] = finger(login) + if student_data['unlSISClassLevel'] == 'GR': + return {Major.get_major('Graduate Student')} + else: + majors: Optional[Set[str]] = student_data['unlSISMajor'] + return {Major.get_major(major) for major in majors} if majors is not None else Major.get_major('None') + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return f'Name: "{self.name}";\tAlternate Names: {self.alternate_names if self.alternate_names else "{}"};\t' \ + f'CSE Major: {self.is_cse_major};\tAbbreviations: {self.abbreviations if self.abbreviations else "{}"}' + -Major('Computer Science', {'COMP-BS', 'COMP-BA', 'COMP-MAJ', 'COMP-BSCS', # we don't yet have BSCS - 'JECS-BS', 'JECS-BA', 'JECS-MAJ', 'JECS-BSCS'}) # but I expect we soon will -Major('Computer Engineering', {'CENG-BSCP', 'JECE-BSCP'}) -Major('Software Engineering', {'SOFT-BSSE', 'JESE-BSSE'}) +Major('Computer Science', alternate_names={'Computer Science (Raikes)'}, + abbreviations={'COMP-BS', 'COMP-BA', 'COMP-MAJ', 'COMP-BSCS', # we don't yet have BSCS + 'JECS-BS', 'JECS-BA', 'JECS-MAJ', 'JECS-BSCS'}) # but I expect we soon will +Major('Computer Engineering', alternate_names={'Computer Engineering (Raikes)'}, + abbreviations={'CENG-BSCP', 'JECE-BSCP'}) +Major('Software Engineering', alternate_names={'Software Engineering (Raikes)'}, + abbreviations={'SOFT-BSSE', 'JESE-BSSE'}) -- GitLab