From 5ccf69b740dd8738d4779bfc77d01c51f1e8e9ac Mon Sep 17 00:00:00 2001 From: Coding with Peter Date: Sun, 1 Oct 2023 11:45:43 -0700 Subject: [PATCH] sept 2023 updates --- courses.py | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ docs.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++ stats.py | 24 +++++++++++ tasks.py | 32 ++++++++++++++- 4 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 docs.py diff --git a/courses.py b/courses.py index 3c0fab5..8a8c8c7 100644 --- a/courses.py +++ b/courses.py @@ -1685,6 +1685,116 @@ def remove_n_analytics(section=0): +def fetch_rubric_scores(course_id=16528, assignment_id=1): + api_url = f'{url}/api/v1/courses/{course_id}' + course_info = fetch(api_url) + + out = codecs.open('cache/rubric_scores.txt','w','utf-8') + + #print(course_info) + + # Extract course details + course_name = course_info['name'] + course_short_name = course_info['course_code'] + course_semester = course_info['enrollment_term_id'] + + # Print course information + out.write(f"Course Name: {course_name}\n") + out.write(f"Short Name: {course_short_name}\n") + out.write(f"Semester: {course_semester}\n") + + api_url = f'{url}/api/v1/courses/{course_id}/assignments' + assignments_list = fetch(api_url) + + #print(assignments_list) + + assignments_dict = {} + ratings_dict = {} + + # Iterate through the list of assignments and populate the dictionary + for assignment in assignments_list: + assignment_id = assignment['id'] + assignment_name = assignment['name'] + rubric = assignment.get('rubric', []) # Get the rubric field (default to an empty list if not present) + + has_rubric = 'no' + if rubric: has_rubric = 'yes' + + out.write(f" Asmt Name: {assignment_name} ID: {assignment_id} Rubric: {has_rubric}\n") + + # Save assignment details including rubric + assignments_dict[assignment_id] = { + 'name': assignment_name, + 'rubric': rubric + # Add more assignment details if needed + } + + if rubric: + print("RUBRIC:") + print(json.dumps(rubric,indent=2)) + for r in rubric: + for rat in r.get('ratings',[]): + ratings_dict[rat['id']] = { 'rub_description': r['description'], 'rat_description': rat['description'], 'points': rat['points']} + + + # Print the assignments dictionary + out.write(json.dumps(assignments_dict,indent=2)+'\n\n\n') + out.write(json.dumps(ratings_dict,indent=2)+'\n\n\n') + + # Loop thru assignments with rubrics and report on grades + for assignment in assignments_list: + + if not assignment.get('rubric', []): + continue + + assignment_id = assignment['id'] + out.write(f" Asmt Name: {assignment_name} ID: {assignment_id}\n") + + api_url = f'{url}/api/v1/courses/{course_id}/assignments/{assignment_id}/submissions?include[]=rubric_assessment' + + # Include the 'include[]=rubric_assessment' parameter to request rubric assessments + # params = {'include[]': 'rubric_assessment'} + + # Make the API request with the parameters + #response = requests.get(api_url, params=params) + + # Check if the request was successful (status code 200) + #if response.status_code != 200: + # print(f"Request failed with status code {response.status_code}") + # continue + + submissions_data = fetch(api_url) + + + # Iterate through the list of submissions and retrieve rubric scores and comments + for submission in submissions_data: + user_id = submission['user_id'] + rubric = submission.get('rubric_assessment', []) # Get the rubric assessment (empty list if not present) + comments = submission.get('submission_comments', '') # Get submission comments (empty string if not present) + score = submission.get('score', -1) + + + # Process and use rubric scores and comments as needed + # Example: Print user information, rubric scores, and comments + if rubric: + print(json.dumps(submission,indent=2)) + + out.write(f"\nSubmission User ID/Assignment ID: {user_id}/{assignment_id}\n") + out.write(f"Score: {score}\n") + out.write(f"Submission Comments: {comments}\n") + out.write(f"Rubric:\n") + for k,v in rubric.items(): + rub_desc = '?' + rat_desc = '?' + if v['rating_id'] in ratings_dict: + rub_rating = ratings_dict[v['rating_id']] + rub_desc = rub_rating['rub_description'] + rat_desc = rub_rating['rat_description'] + out.write(f" {rub_desc} - {rat_desc} ({v['rating_id']}): {v['points']}/{rub_rating['points']} points: {v['comments']}\n") + out.write("---") # Separator between submissions + out.flush() + + @@ -1801,6 +1911,8 @@ if __name__ == "__main__": # 21: ['Add announcements to homepage', change_course_ann_homepage], # TODO wanted: group shell for each GP (guided pathway) as a basic student services gateway.... # + + 45: ['Fetch rubric scores and comments', fetch_rubric_scores], } print ('') diff --git a/docs.py b/docs.py new file mode 100644 index 0000000..48384b7 --- /dev/null +++ b/docs.py @@ -0,0 +1,118 @@ + +import codecs, os,regex, subprocess + + +def html_to_markdown(infile,out): + cmd = f"pandoc -o \"./{out}\" -f html -t markdown \"./{infile}\"" + print(cmd) + result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + if result.returncode != 0: + print(f"Error occurred: {result.stderr.decode('utf-8')}") + else: + print(f"Successfully converted '{infile}' to '{out}'") + + +def pdf_to_html(infile,out): + import PyPDF2 + + pdf_file = open(infile, 'rb') + pdf_reader = PyPDF2.PdfReader(pdf_file) + + text = '' + for page_num in range(len(pdf_reader.pages)): + page = pdf_reader.pages[page_num] + text += page.extract_text() + + pdf_file.close() + ofile = codecs.open(out,'w','utf-8') + ofile.write(text) + ofile.close() + + +def pdf_to_html2(infile,out): + from pdfminer.high_level import extract_pages + from pdfminer.layout import LTTextContainer + import html + + ofile = codecs.open(out,'w','utf-8') + + print(infile) + for page_layout in extract_pages(infile): + for element in page_layout: + if isinstance(element, LTTextContainer): + text = html.escape(element.get_text()) # sanitize the text for HTML + ofile.write(f"

{text}

") # wraps in HTML paragraph tags + + + +def convert(filename=""): + + target_dir = 'cache/docs' + ff = os.listdir(target_dir) + + if filename: + parts = filename.split('.') + OUTFILE = f"{parts[0]}.html" + pdf_to_html(target_dir + "/" + filename, target_dir + "/" + OUTFILE) + html_to_markdown( target_dir + "/" + OUTFILE, target_dir + "/" + parts[0] + ".md" ) + + + else: + for INFILE in ff: + if INFILE.endswith(".pdf"): + parts = INFILE.split('.') + OUTFILE = f"{parts[0]}.html" + + pdf_to_html(target_dir + "/" + INFILE, target_dir + "/" + OUTFILE) + + html_to_markdown( target_dir + "/" + OUTFILE, target_dir + "/" + parts[0] + ".md" ) + + +def clean(fn): +# Open file and read contents + with open(fn, 'r', encoding='utf-8') as myfile: + data = myfile.read() + + # Replace unicode non-breaking space with a regular space + data = data.replace('\u00A0', ' ') + data = data.replace('\u00AD', '') + data = data.replace('\u200B', '') + + # Write cleaned data back to file + with open(fn, 'w', encoding='utf-8') as myfile: + myfile.write(data) + + +def fix_line_breaks(fn): + with codecs.open(fn, 'r', 'utf-8') as file: + lines = file.readlines() + + new_lines = [] + paragraph = '' + + for line in lines: + if line.strip() == '': + # If the line is blank, it's the end of a paragraph + new_lines.append(paragraph.strip()) + paragraph = '' + else: + # If the line is not blank, add it to the paragraph (extra space included for word separation) + paragraph += line.strip() + ' ' + + # Handle the last paragraph + if paragraph != '': + new_lines.append(paragraph.strip()) + + fout = codecs.open(fn, 'w','utf-8') + fout.write('\n'.join(new_lines)) + + +fix_file = 'hyflex.md' +convert('hyflex.pdf') + +clean(f'cache/docs/{fix_file}') + +fix_line_breaks(f'cache/docs/{fix_file}') + + + diff --git a/stats.py b/stats.py index b7d86f8..159cecb 100644 --- a/stats.py +++ b/stats.py @@ -880,9 +880,32 @@ def cluster_student_histories(): df = pd.read_csv(infile) +def dept(s): + parts = s.split(' ') + return parts[0] + +def try_make_sched(): + term = "fa23" + sched = requests.get(f"http://gavilan.cc/schedule/{term}_sched.json").json() + #print(json.dumps(sched,indent=2)) + + d = "CSIS" + courses = [ [x['code'], x['crn']] for x in sched if dept(x['code'])==d ] + teachers = { x['teacher'] for x in sched if dept(x['code'])==d } + + print(courses) + print(teachers) +def section_stats(): + pass + # for each course, (ENG1A) how many are enrolled in each all sections? + # (and break down by mode,time,location,etc) + # + # for each course, how many are first semester gav students? + # + # if __name__ == "__main__": options = { 1: ['get all historical grades from ilearn',get_all] , @@ -896,6 +919,7 @@ if __name__ == "__main__": 9: ['semester startdates list', semester_dates], 10: ['normalize course histories', normalize_course_histories], 11: ['cluster student histories', cluster_student_histories], + 12: ['try to make a schedule', try_make_sched], } print ('') diff --git a/tasks.py b/tasks.py index 7ddf86f..b7bd455 100644 --- a/tasks.py +++ b/tasks.py @@ -1412,7 +1412,36 @@ def print_a_calendar(): +def word_calendar(): + from docx import Document + from docx.shared import Inches + import datetime + # Define the start date + start_date = datetime.date(2023, 8, 28) + + # Prepare a list of 18 weeks beginning from the start date + dates = [start_date + datetime.timedelta(weeks=x) for x in range(18)] + + # Initialize an instance of a word document + doc = Document() + table = doc.add_table(rows=1, cols=3) + + # Set the headers + hdr_cells = table.rows[0].cells + hdr_cells[0].text = 'Week' + hdr_cells[1].text = 'Date' + hdr_cells[2].text = 'Events/Notes' + + # Iterate through the list of dates + for i, date in enumerate(dates): + cells = table.add_row().cells + cells[0].text = str(i+1) + cells[1].text = date.strftime("%B %d") + cells[2].text = '' + + # Save the document + doc.save('cache/tasks_schedule.docx') @@ -1430,7 +1459,8 @@ if __name__ == "__main__": 10: ['dumb rename images mistake',file_renamer] , 11: ['list auth', list_auth], 12: ['update auth', update_auth], - 13: ['print a calendar', print_a_calendar] + 13: ['print a calendar', print_a_calendar], + 14: ['create a week calendar in word', word_calendar], } if len(sys.argv) > 1 and re.search(r'^\d+',sys.argv[1]):