def initialize(options): global canvas_baseUrl, canvas_header, canvas_payload if options.config_filename: config_file=options.config_filename else: config_file='config.json' try: with open(config_file) as json_data_file: configuration = json.load(json_data_file) # set up Canvas access canvas_access_token=configuration["canvas"]["access_token"] if options.containers: canvas_baseUrl="http://"+configuration["canvas"]["host"]+"/api/v1" print("using HTTP for the container environment") else: canvas_baseUrl="https://"+configuration["canvas"]["host"]+"/api/v1" canvas_header = {'Authorization' : 'Bearer ' + canvas_access_token} canvas_payload = {} # set up Ladok access username=configuration["ladok"]["username"] password=configuration["ladok"].get("password", []) except: print("Unable to open configuration file named {}".format(config_file)) print("Please create a suitable configuration file, the default name is config.json") sys.exit() if not password: password=getpass.getpass(prompt='Password (for Ladok access): ') ls=ladok3.LadokSessionKTH(username, password, options.testenvironment) return ls
import ladok3 import os ladok = ladok3.LadokSessionKTH(os.environ["KTH_LOGIN"], os.environ["KTH_PASSWD"], test_environment=True) # for experiments me = ladok.get_student("8506097891") me2 = ladok.get_student("de709f81-a867-11e7-8dbf-78e86dc2470c") print(f"{me.personnummer} {me.last_name}, {me.first_name}") print(f"{me2.personnummer} {me2.last_name}, {me2.first_name}") print(f"{me.ladok_id} == {me2.ladok_id}") print() for course in me.courses(): print(f"{course.code} {course.name}") course = me.courses(code="DD2395")[0] print(f"{course.code} results:") for result in course.results(): s = f"{course.code}" if result.component: s += f" {result.component}" s += f" {result.grade}" if result.attested: s += f" ({result.date})" print(s) print()
def main(argv): global Verbose_Flag global testing global course_id argp = argparse.ArgumentParser(description="JSON_to_LADOK.py: to enter titles for a thesis") argp.add_argument('-v', '--verbose', required=False, default=False, action="store_true", help="Print lots of output to stdout") argp.add_argument("--config", type=str, default='config.json', help="read configuration from file") argp.add_argument("-c", "--canvas_course_id", type=int, # required=True, help="canvas course_id") argp.add_argument('-t', '--testing', default=False, action="store_true", help="execute test code" ) argp.add_argument('-j', '--json', type=str, default="event.json", help="JSON file for extracted data" ) argp.add_argument('--which', type=int, # 1, 2, or 3 default=0, help="if more than one author, which should be processed" ) argp.add_argument('--code', type=str, required=True, help="course code" ) argp.add_argument('--date', type=str, help="date of the requirement being completed" ) argp.add_argument('--grade', type=str, default="P", help="grade to be assigned" ) argp.add_argument('--gradeScale', type=str, default="PF", help="grading scale" ) args = vars(argp.parse_args(argv)) Verbose_Flag=args["verbose"] initialize(args) if Verbose_Flag: print("baseUrl={}".format(baseUrl)) # If there is a course number argument, then initializae in prepartion for Canvas API calls course_id=args["canvas_course_id"] if course_id: if Verbose_Flag: print("course_id={}".format(course_id)) print("baseUrl={}".format(baseUrl)) testing=args["testing"] print("testing={}".format(testing)) d=None json_filename=args["json"] if json_filename: with open(json_filename, 'r', encoding='utf-8') as json_FH: try: json_string=json_FH.read() d=json.loads(json_string) except: print("Error in reading={}".format(event_string)) return if Verbose_Flag: print("read JSON: {}".format(d)) if d: print("d={}".format(d)) # get title and alternative title #"Title": {"Main title": "HoneyRAN", "Subtitle": "A Radio Access Network Honeypot", "Language": "eng"}, "Alternative title": {"Main title": "HoneyRAN", "Subtitle": "En honeypot för radioaccessnät", "Language": "swe"} title_info=d.get('Title', None) if title_info: main_title=title_info.get('Main title', None) alternative_main_title=title_info.get('Alternative title', None) else: print("Missing title") return if not main_title: print("Missing title") return course_code=d.get('Course code') if not course_code: print("Missing course code") return print("course_code={}".format(course_code)) date_of_exam=args["date"] if date_of_exam: result_date = validate_date(ladok, date_of_exam) else: # datetime object containing current date and time now = datetime.now() print("now =", now) dt_string = now.strftime("%Y-%m-%d") print("date =", dt_string) result_date = dt_string grade=args['grade'] if not grade: grade = 'P' grade_scale=args['gradeScale'] if not grade_scale: grade_scale="PF" ladok = ladok3.LadokSessionKTH( # establish as session with LADOK os.environ["KTH_LOGIN"], os.environ["KTH_PASSWD"], test_environment=True) # for experiments author_names=list() for i in range(1, 10): which=args['which'] # which author should be processed if (which == 0) or (which == i) or (which == 3): which_author="Author{}".format(i) author=d.get(which_author, None) if author: print("author={}".format(author)) integration_id=get_integration_id_from_email_address(author['E-mail']) print("integration_id={}".format(integration_id)) courses=get_student_courses(ladok, integration_id) ladok_course_info=instance_id_given_course_code(courses, course_code) print("ladok_course_info={}".format(ladok_course_info)) ladok_course_moments_info=get_student_course_moments_JSON(ladok, ladok_course_info['round_id'], integration_id) if ladok_course_moments_info: for mom in ladok_course_moments_info['IngaendeMoment']: print("moment code={0}, requires title={1}".format(mom['Utbildningskod'], mom['KravPaProjekttitel'])) if mom['KravPaProjekttitel']: print("trying to store a passing grade for moment={0}".format(mom['Utbildningskod'])) status=save_result_degree_project3(ladok, integration_id, course_code, mom['Utbildningskod'], result_date, grade, grade_scale, main_title, alternative_main_title) print("status={}".format(status)) #returned: Exception: Couldn't register PRO3=P 2021-07-14: Hinder mot skapa resultat påträffat: Rapporteringsrättighet saknas # to logout and close the session status=ladok_session.logout() else: print("Unknown source for the JSON: {}".format(json_filename)) return
def main(argv): global Verbose_Flag global testing global course_id argp = argparse.ArgumentParser( description="courses_grades_by_school.py: to collect course round data" ) argp.add_argument('-v', '--verbose', required=False, default=False, action="store_true", help="Print lots of output to stdout") argp.add_argument("--config", type=str, default='config.json', help="read configuration from file") argp.add_argument('-t', '--testing', default=False, action="store_true", help="execute test code") argp.add_argument('-s', '--school', type=str, default='EECS', help="acronyms for a school within KTH") argp.add_argument('-y', '--year', type=int, default='2020', help="starting year") args = vars(argp.parse_args(argv)) Verbose_Flag = args["verbose"] initialize(args) if Verbose_Flag: print("canvas_baseUrl={}".format(canvas_baseUrl)) starting_year_int = args['year'] starting_year = datetime.date(starting_year_int, 1, 1) print("starting_year={}".format(starting_year)) ending_year = datetime.date(starting_year_int + 1, 1, 1) school_acronym = args["school"] if Verbose_Flag: print("school_acronym={}".format(school_acronym)) # compute the list of degree project course codes all_dept_codes = get_dept_codes(Swedish_language_code) if Verbose_Flag: print("all_dept_codes={}".format(all_dept_codes)) dept_codes = dept_codes_in_a_school(school_acronym, all_dept_codes) if Verbose_Flag: print("dept_codes={}".format(dept_codes)) courses_English = all_non_cancelled_courses(dept_codes, English_language_code) courses_Swedish = all_non_cancelled_courses(dept_codes, Swedish_language_code) if Verbose_Flag: print("courses English={0} and Swedish={1}".format( courses_English, courses_Swedish)) collected_course_codes = set() for c in courses_English: collected_course_codes.add(c['code']) if Verbose_Flag: print("collected_course_codes={}".format(collected_course_codes)) print("total number of course codes={0}".format( len(collected_course_codes))) ladok = ladok3.LadokSessionKTH( # establish as session with LADOK os.environ["KTH_LOGIN"], os.environ["KTH_PASSWD"], test_environment=True) # for experiments list_of_student_info = list() students_already_processed = set() course_rounds_already_processed = set() number_found = 0 course_round_info_list = [] if args['testing']: collected_course_codes = ['IK1552'] for course_code in collected_course_codes: course_rounds = None # set it to None so that if the LADOK search fails it has a value print("course_code={}".format(course_code)) try: course_rounds = ladok.search_course_rounds(code=course_code) except: print("Error for course code={}".format(course_code)) if Verbose_Flag: print("course_rounds={}".format(course_rounds)) if not course_rounds: # if there is no course round information, skip to the next course code continue for course_round in course_rounds: course_start = course_round.start if course_start < starting_year: # skip courses rounds that started prior to the indicated starting year continue if course_start > ending_year: # skip courses rounds that started after the indicated starting year continue course_length = course_round.end - course_start print("course_round.round_id={}".format(course_round.round_id)) collected_components = {} for j, comp in enumerate(course_round.components()): #print("comp={}".format(comp)) desc = comp.__dict__['_CourseComponent__description'] en_name = '' sv_name = '' for d in desc: if d.get('Sprakkod') == 'en': en_name = d['Text'] if d.get('Sprakkod') == 'sv': sv_name = d['Text'] #print("gradescale={}".format(comp.__dict__['_CourseComponent__grade_scale'])) gs = comp.__dict__['_CourseComponent__grade_scale'] #print("gs={0} name={1}".format(gs, gs.name)) key = 'component{}_code'.format(j) collected_components[key] = comp.__dict__[ '_CourseComponent__code'] key = 'component{}_description_en'.format(j) collected_components[key] = en_name key = 'component{}_description_sv'.format(j) collected_components[key] = sv_name key = 'component{}_grade_scale'.format(j) collected_components[key] = gs.name key = 'component{}_credits'.format(j) collected_components[key] = comp.__dict__[ '_CourseComponent__credits'] number_of_students = 0 for student in ladok.participants_JSON(course_round.round_id): number_of_students = number_of_students + 1 di = lookup_dept_info(course_code, courses_English) di_sv = lookup_dept_info(course_code, courses_Swedish) course_round_info_list.append({ 'code': course_round.code, 'name': course_round.name, 'instance_id': course_round.instance_id, 'version': course_round.version, 'credits': course_round.credits, 'grade_scale_name': course_round.grade_scale[0].name, 'start': course_round.start, 'end': course_round.end, 'dept_code': di['dept_code'], 'department_en': di['department'], 'department_sv': di_sv['department'], 'components': collected_components, 'number_of_students': number_of_students }) if course_round.round_id in course_rounds_already_processed: continue course_rounds_already_processed.add(course_round.round_id) print( "Total number of course codes={0}, total number of course rounds={1}". format(len(collected_course_codes), len(course_round_info_list))) #users_info_df=pd.json_normalize(list_of_student_info) output_filename = "courses-in-{0}-{1}.xlsx".format(school_acronym, starting_year_int) writer = pd.ExcelWriter(output_filename, engine='xlsxwriter') # We need to drop duplicate rows since a student can have been registered in more than one course round for their degree project # If so, they will appear in the list as many times as there were course rounds. #users_info_df.drop_duplicates(ignore_index=True, inplace=True, keep='last') #users_info_df.to_excel(writer, sheet_name='Results') course_code_info = [] for c in collected_course_codes: di = lookup_dept_info(c, courses_English) di_sv = lookup_dept_info(c, courses_Swedish) course_code_info.append({ 'course_code': c, 'dept_code': di['dept_code'], 'department_en': di['department'], 'department_sv': di_sv['department'] }) course_codes_df = pd.json_normalize(course_code_info) course_codes_df.to_excel(writer, sheet_name='course codes used') course_round_info_df = pd.json_normalize(course_round_info_list) course_round_info_df.to_excel(writer, sheet_name='Rounds') # Close the Pandas Excel writer and output the Excel file. writer.save() # to logout and close the session status = ladok.logout()
import ladok3 ladok = ladok3.LadokSessionKTH("dbosk", "my secret password", test_environment=True) # for experiments
def main(argv): global Verbose_Flag global testing global course_id argp = argparse.ArgumentParser( description="thesis_titles.py: to collect thesis titles") argp.add_argument('-v', '--verbose', required=False, default=False, action="store_true", help="Print lots of output to stdout") argp.add_argument("--config", type=str, default='config.json', help="read configuration from file") argp.add_argument( "-c", "--canvas_course_id", type=int, # required=True, help="canvas course_id") argp.add_argument('-t', '--testing', default=False, action="store_true", help="execute test code") args = vars(argp.parse_args(argv)) Verbose_Flag = args["verbose"] initialize(args) if Verbose_Flag: print("canvas_baseUrl={}".format(canvas_baseUrl)) # If there is a course number argument, then initializae in prepartion for Canvas API calls course_id = args["canvas_course_id"] if Verbose_Flag: print("course_id={}".format(course_id)) print("baseUrl={}".format(baseUrl)) if not course_id: print("No course_id was specified, therefore quitting") return # get the list of students in the course students = students_in_course(course_id) set_of_student_canvas_ids = set() for s in students: set_of_student_canvas_ids.add(s['user_id']) print("Number of students={}".format(len(set_of_student_canvas_ids))) list_of_student_info = list() testing = args["testing"] print("testing={}".format(testing)) ladok = ladok3.LadokSessionKTH( # establish as session with LADOK os.environ["KTH_LOGIN"], os.environ["KTH_PASSWD"], test_environment=False) # for experiments number_found = 0 for id in set_of_student_canvas_ids: print("Canvas user_id={}".format(id)) user_profile = user_profile_info(id) integration_id = user_profile.get('integration_id', None) if Verbose_Flag: print("integration_id={}".format(integration_id)) theses = get_titles_of_all_thesis(ladok, integration_id) if theses: for info in theses: student_info = dict() student_info['user_id'] = id student_info['sname'] = user_profile['sortable_name'] date = info.get('Examinationsdatum') if date: student_info['date'] = date course_code = info.get('course_code') if course_code: student_info['course_code'] = course_code title = info['titles'].get('Titel') if title: student_info['title'] = title alt_title = info['titles'].get('AlternativTitel') if alt_title: student_info['alt_title'] = alt_title examiner = info.get('Examiner') if examiner: student_info['Examiner'] = examiner moment = info.get('moment') if moment: student_info['moment'] = moment grade = info.get('Grade') if grade: student_info['Grade'] = grade list_of_student_info.append(student_info) number_found = number_found + 1 if testing and number_found > 10: print("list_of_student_info={}".format(list_of_student_info)) break users_info_df = pd.json_normalize(list_of_student_info) output_filename = "titles-{}.xlsx".format(course_id) writer = pd.ExcelWriter(output_filename, engine='xlsxwriter') users_info_df.to_excel(writer, sheet_name='Titles') # Close the Pandas Excel writer and output the Excel file. writer.save() # to logout and close the session status = ladok.logout()
def main(argv): global Verbose_Flag global testing global course_id argp = argparse.ArgumentParser( description="thesis_titles_by_school.py: to collect thesis titles") argp.add_argument('-v', '--verbose', required=False, default=False, action="store_true", help="Print lots of output to stdout") argp.add_argument("--config", type=str, default='config.json', help="read configuration from file") argp.add_argument('-t', '--testing', default=False, action="store_true", help="execute test code") argp.add_argument('-s', '--school', type=str, default='EECS', help="acronyms for a school within KTH") args = vars(argp.parse_args(argv)) Verbose_Flag = args["verbose"] initialize(args) if Verbose_Flag: print("canvas_baseUrl={}".format(canvas_baseUrl)) school_acronym = args["school"] if Verbose_Flag: print("school_acronym={}".format(school_acronym)) # compute the list of degree project course codes all_dept_codes = get_dept_codes(Swedish_language_code) if Verbose_Flag: print("all_dept_codes={}".format(all_dept_codes)) dept_codes = dept_codes_in_a_school(school_acronym, all_dept_codes) if Verbose_Flag: print("dept_codes={}".format(dept_codes)) courses_English = degree_project_courses(dept_codes, English_language_code) courses_Swedish = degree_project_courses(dept_codes, Swedish_language_code) if Verbose_Flag: print("courses English={0} and Swedish={1}".format( courses_English, courses_Swedish)) degree_project_course_codes = set() for c in courses_English: degree_project_course_codes.add(c['code']) if args['testing']: degree_project_course_codes = ['DA231X'] print("degree_project_course_codes={}".format(degree_project_course_codes)) ladok = ladok3.LadokSessionKTH( # establish as session with LADOK os.environ["KTH_LOGIN"], os.environ["KTH_PASSWD"], test_environment=True) # for experiments list_of_student_info = list() students_already_processed = set() course_rounds_already_processed = set() number_found = 0 for course_code in degree_project_course_codes: print("course_code={}".format(course_code)) course_rounds = ladok.search_course_rounds(code=course_code) if Verbose_Flag: print("course_rounds={}".format(course_rounds)) for course_round in course_rounds: course_start = course_round.start course_length = course_round.end - course_start print("course_round.round_id={}".format(course_round.round_id)) if course_round.round_id in course_rounds_already_processed: continue course_rounds_already_processed.add(course_round.round_id) for student in ladok.participants_JSON(course_round.round_id): if student[ 'Avklarad']: # if the student completed the course, then look for the titles if Verbose_Flag: print("student={}".format(student)) integration_id = student['Student']['Uid'] # since we later check for only the matching course_code, we need to consider the author again # if integration_id in students_already_processed: # skip students that have already been processed # continue first_name = student['Student'].get('Fornamn') last_name = student['Student'].get('Efternamn') theses = get_titles_of_all_thesis(ladok, integration_id) if Verbose_Flag: print("theses={}".format(theses)) if theses: for info in theses: student_info = dict() student_info['integration_id'] = integration_id if first_name: student_info['first_name'] = first_name if last_name: student_info['last_name'] = last_name date = info.get('Examinationsdatum') if date: student_info['date'] = date thesis_course_code = info.get('course_code') if thesis_course_code != course_code: # if this is not the degree project course code we are looking for, skip it. continue if thesis_course_code: student_info[ 'course_code'] = thesis_course_code # The following code was put in to test for th case of EECS when students with other degree projects were getting include # since the get_titles_of_all_thesis() code collected _all_ degree projects of a given student and not just those of the # specific ourse-code we are looking for in this school. # if thesis_course_code[0] in ['M', 'S']: # print("should not see such a course code: course_round.round_id={0}, info={1}".format(course_round.round_id, info)) title = info['titles'].get('Titel') if title: student_info['title'] = title alt_title = info['titles'].get('AlternativTitel') if alt_title: student_info['alt_title'] = alt_title examiner = info.get('Examiner') if examiner: student_info['Examiner'] = examiner moment = info.get('moment') if moment: student_info['moment'] = moment grade = info.get('Grade') if grade: student_info['Grade'] = grade list_of_student_info.append(student_info) number_found = number_found + 1 students_already_processed.add(integration_id) if args['testing'] and number_found > 10: print("list_of_student_info={}".format( list_of_student_info)) break print("Total number of items of thesis information={}".format( len(list_of_student_info))) users_info_df = pd.json_normalize(list_of_student_info) output_filename = "titles-all-{}.xlsx".format(school_acronym) writer = pd.ExcelWriter(output_filename, engine='xlsxwriter') # We need to drop duplicate rows since a student can have been registered in more than one course round for their degree project # If so, they will appear in the list as many times as there were course rounds. users_info_df.drop_duplicates(ignore_index=True, inplace=True, keep='last') users_info_df.to_excel(writer, sheet_name='Titles') # Close the Pandas Excel writer and output the Excel file. writer.save() # to logout and close the session status = ladok.logout()