def find_no_canvas_account(): users = User.objects.all() for user in users: this_user = canvas_api.get_user_by_sis(user.username) if this_user == None: print(user.username) try: profile = user.profile canvas_api.create_canvas_user( user.username, user.profile.penn_id, user.email, user.first_name + " " + user.last_name, ) except: userdata = datawarehouse_lookup(penn_key=user.username) if userdata: Profile.objects.create(user=user, penn_id=userdata["penn_id"]) canvas_api.create_canvas_user( user.username, user.profile.penn_id, user.email, user.first_name + " " + user.last_name, )
def check_for_account(pennkey): user = canvas_api.get_user_by_sis(pennkey) if user == None: # no account lets create try: crf_account = User.objects.get(username=pennkey) pennid = crf_account.profile.pennid full_name = crf_account.get_full_name() canvas_account = canvas_api.create_user(pennkey,pennid,fullname) if canvas_account: return canvas_account else: return None except: # log error pass
def find_no_canvas_account(): users = User.objects.all() for user in users: this_user = canvas_api.get_user_by_sis(user.username) if this_user == None: print(user.username) try: profile = user.profile canvas_api.mycreate_user(user.username,user.profile.penn_id,user.email,user.first_name+' '+user.last_name) except: #profile doesnt exist yet userdata = datawarehouse_lookup(PPENN_KEY=user.username) if userdata: Profile.objects.create(user=user,penn_id=userdata['penn_id']) canvas_api.mycreate_user(user.username,user.profile.penn_id,user.email,user.first_name+' '+user.last_name)
def check_for_account(penn_key): user = get_user_by_sis(penn_key) if user is None: try: crf_account = User.objects.get(username=penn_key) email = crf_account.email penn_id = crf_account.profile.pennid full_name = crf_account.get_full_name() canvas_account = create_canvas_user(penn_key, penn_id, email, full_name) return canvas_account if canvas_account else None except Exception as error: print( f"- ERROR: Failed to create canvas account for {penn_key} ({error})." )
def create_canvas_site(): ################### STEPS ######################### # 1. set request to in process # 2. Create course in canvas ( check that is doesnt exist first ) # 2a. Crosslist # 2b. add sections # 3. enroll faculty and additional enrollments ( check that they have accounts first) # 4. Configure reserves # 5. Content Migration # 6. Create CanvasSite Object and link to Request ( set canvas_instance_id ) # 7. Set request to Complete # 8. Notify with email #################################################### _to_process = Request.objects.filter(status='APPROVED') for request_obj in _to_process: serialized = RequestSerializer(request_obj) additional_sections=[] # {'course_section':'','instructors':''} list of Canvas course section objects and instructors listed in CRF to use later when adding enrollments ######## Step 1. Set request to IN_PROCESS ######## request_obj.status = 'IN_PROCESS' request_obj.save() course_requested = request_obj.course_requested #input("STEP 1 DONE...\n") ######## Step 2. Create course in canvas ######## account = canvas_api.find_account(course_requested.course_schools.canvas_subaccount) if account: # account exists # check if this is not the prmary if course_requested.course_primary_subject.abbreviation != course_requested.course_subject.abbreviation: # we parse the primary! pc = course_requested.primary_crosslist if course_requested.primary_crosslist: term =pc[-5:] section = pc[:-5][-3:] number = pc[:-5][:-3][-3:] subj = pc[:-5][:-6] section_name_code ="%s %s-%s %s" % (subj,number,section,term) else: # it seems that we have a problem .primary_crosslist must be filled out request_obj.process_notes += "primary_crosslist not set," request_obj.save() return else: section_name_code ="%s %s-%s %s" % (course_requested.course_subject.abbreviation, course_requested.course_number,course_requested.course_section, course_requested.year+course_requested.course_term) name_code = section_name_code # check if there is a title override if request_obj.title_override: name = name_code + " " +request_obj.title_override[:45] section_name = section_name_code + request_obj.title_override[:45] else: name = name_code +" "+ course_requested.course_name section_name = section_name_code + " " + course_requested.course_name sis_course_id = 'SRS_'+ course_requested.srs_format_primary() print("sis_course_id",sis_course_id) print("section_name",section_name) term_id = canvas_api.find_term_id(96678, course_requested.year+course_requested.course_term) print("going to create",name,',',sis_course_id) course = {'name':name,'sis_course_id':sis_course_id,'course_code':sis_course_id,'term_id':term_id} try: canvas_course = account.create_course(course=course) except: # check what went wrong () !!! # canvas_course = request_obj.process_notes += "course site creation failed- check if it already exists," request_obj.save() return print("created",canvas_course) ## Raise course quota ## try: canvas_course.update(course={'storage_quota_mb':2000}) except: request_obj.process_notes += "course site quota not raised," request_obj.save() ## Add sections ## # Add main Sections try: additional_section = {'course_section':'','instructors':''} additional_section['course_section']=canvas_course.create_course_section(course_section={'name':section_name,'sis_section_id':sis_course_id},enable_sis_reactivation=True)#first_section = canvas_course.get_sections()[0] MAIN_SECTION = additional_section['course_section'] additional_section['instructors']= course_requested.instructors.all() additional_sections += [additional_section] print("1",{"additional_section":additional_section,"additional_sections":additional_sections}) except: # dont continue with the loop so just stop for now. print("failed to create main section,", canvas_course) request_obj.process_notes += "failed to create main section," request_obj.process_notes += sys.exc_info()[0] request_obj.save() return #first_section.edit(course_section={'sis_section_id':sis_course_id},enable_sis_reactivation=True) else: request_obj.process_notes += "failed to locate Canvas Account in Canvas," #error log and stop for loop pass # Add multi-sections if request_obj.title_override: namebit = request_obj.title_override else: namebit = course_requested.course_name for section in serialized.data['additional_sections']: section_course = Course.objects.get(course_code=section) if section_course.course_activity.abbr !='LEC': # dont put the name in the title, instead add the activity abbr. namebit = section_course.course_activity.abbr sis_section = 'SRS_'+section_course.srs_format_primary() #sis_sections += [sis_section] try: additional_section = {'course_section':'','instructors':''} print({'name':section_course.srs_format_primary(sis_id=False) +' '+ namebit,'sis_section_id':sis_section}) additional_section['course_section'] = canvas_course.create_course_section(course_section={'name':section_course.srs_format_primary(sis_id=False) +' '+ namebit,'sis_section_id':sis_section},enable_sis_reactivation=True) additional_section['instructors'] = section_course.instructors.all() additional_sections += [additional_section] print("2",{"additional_section":additional_section,"additional_sections":additional_sections}) except: # dont continue with the loop so just stop for now. request_obj.process_notes += "failed to create section," request_obj.save() return #check if instructors are specified for each section #check for crosslist if course_requested.crosslisted: pass print("starting step 2") #input("STEP 2 DONE...\n") ######## Step 3. enroll faculty and additional enrollments ######## enrollment_types = {'INST':'TeacherEnrollment', 'instructor':'TeacherEnrollment','TA':'TaEnrollment','ta':'TaEnrollment', 'DES':'DesignerEnrollment', 'designer':'DesignerEnrollment', 'LIB':'DesignerEnrollment','librarian':'DesignerEnrollment'} librarian_role_id = '1383' # Enroll instructors listed in SRS for section in additional_sections: for instructor in section['instructors']: # check that they have an account user = canvas_api.get_user_by_sis(instructor.username) if user == None: # user doesnt exist try: user = canvas_api.mycreate_user(instructor.username, instructor.profile.penn_id, instructor.email,instructor.first_name+ ' '+ instructor.last_name) request_obj.process_notes += "created account for user: %s," % (instructor.username) except: request_obj.process_notes += "failed to create account for user: %s," % (instructor.username) pass # fail silently # either user exists or has been created now try: canvas_course.enroll_user(user.id, 'TeacherEnrollment' ,enrollment={'enrollment_state':'active', 'course_section_id':section['course_section'].id}) except: request_obj.process_notes += "failed to add user: %s," % (instructor.username) pass #fail silently #for sect in canvas_course.get_sections():canvas_course.enroll_user(user.id, 'TeacherEnrollment' ,enrollment={'course_section_id':sect.id,'enrollment_state':'active'} ) additional_enrollments = serialized.data['additional_enrollments'] # enroll custom additional enrollments - all added to MAIN SECTION ONLY for enrollment in additional_enrollments: user = enrollment['user'] role = enrollment['role'] # check if user exists user_canvas = canvas_api.get_user_by_sis(user) if user_canvas == None: # user doesnt exist try: user_crf = User.objects.get(username=user) user_canvas = canvas_api.mycreate_user(user, user_crf.profile.penn_id, user_crf.email ,user_crf.first_name+user_crf.last_name) request_obj.process_notes += "created account for user: %s," % (instructor.username) except: request_obj.process_notes += "failed to create account for user: %s," % (instructor.username) pass # fail silently if role =='LIB' or role=='librarian': try: canvas_course.enroll_user( user_canvas.id , enrollment_types[role] ,enrollment={'course_section_id':MAIN_SECTION.id,'role_id':librarian_role_id,'enrollment_state':'active'} ) except: request_obj.process_notes += "failed to add user: %s," % (user) pass else: try: canvas_course.enroll_user(user_canvas.id ,enrollment_types[role] ,enrollment={'course_section_id':MAIN_SECTION.id,'enrollment_state':'active'} ) except: request_obj.process_notes += "failed to add user: %s," % (user) pass #enroll_user(user.id ,'DesignerEnrollment' ,enrollment={'role_id':1383,'enrollment_state':'active'}) #input("STEP 3 DONE...\n") ######## Step 4. Configure reserves/libguide ######## if serialized.data['reserves']: try: tab = canvas_api.Tab(canvas_course._requester, {"course_id":canvas_course.id, "id":'context_external_tool_139969'}) tab.update(hidden=False) if tab.visibility != 'public': request_obj.process_notes += "failed to configure ARES," except: request_obj.process_notes += "failed to try to configure ARES," #input("STEP 4 DONE...\n") ######## Step 5. Content Migration ######## if serialized.data['copy_from_course']: contentmigration = canvas_course.create_content_migration(migration_type='course_copy_importer',settings={'[source_course_id':serialized.data['copy_from_course']}) # need to add error reporting to this while contentmigration.get_progress == 'queued' or contentmigration.get_progress == 'running': #pass print("still running") time.sleep(8) # if the progress is 'failed' --> report this #input("STEP 5 DONE...\n") ######## Step 6. Create CanvasSite Object and link to Request ######## instructors = canvas_course.get_enrollments(type='TeacherEnrollment')._elements print("instructors ", instructors) _canvas_id = canvas_course.id _request_instance = request_obj _name = canvas_course.name _sis_course_id = canvas_course.sis_course_id _workflow_state = canvas_course.workflow_state site = CanvasSite.objects.create(canvas_id=_canvas_id,request_instance=_request_instance,name=_name,sis_course_id=_sis_course_id,workflow_state=_workflow_state) request_obj.canvas_instance = site for instructor in instructors: try: u = User.objects.get(username=instructor) site.owners.add(u) except: pass #input("STEP 6 DONE...\n") ######## Step 7. Set request to Complete ######## request_obj.status = 'COMPLETED' request_obj.save()
def create_canvas_sites( requested_courses=None, sections=None, test=False, verbose=True, ): if verbose: print(") Creating Canvas sites for requested courses...") if requested_courses is None: requested_courses = Request.objects.filter(status="APPROVED") if not requested_courses: if verbose: print("SUMMARY") print("- No requested courses found.") print("FINISHED") return section_already_exists = False for request in requested_courses: request.status = "IN_PROCESS" request.save() serialized = RequestSerializer(request) additional_sections = [] course_requested = request.course_requested if verbose: print(f") Creating Canvas site for {course_requested}...") account = find_account( course_requested.course_schools.canvas_subaccount, test=test) if account: if (course_requested.course_primary_subject.abbreviation != course_requested.course_subject.abbreviation): if course_requested.primary_crosslist: section_name_code = course_requested.srs_format_primary() else: add_request_process_notes("Primary crosslist not set", request) continue else: section_name_code = ( f"{course_requested.course_subject.abbreviation}" f" {course_requested.course_number}-" f"{course_requested.course_section}" f" {course_requested.year}{course_requested.course_term}") if request.title_override: name = f"{section_name_code} {request.title_override[:45]}" section_name = f"{section_name_code}{request.title_override[:45]}" else: name = f"{section_name_code} {course_requested.course_name}" section_name = f"{section_name_code} {course_requested.course_name}" sis_course_id = f"SRS_{course_requested.srs_format_primary()}" term_id = find_term_id( 96678, f"{course_requested.year}{course_requested.course_term}", test=test, ) course = { "name": name, "sis_course_id": sis_course_id, "course_code": sis_course_id, "term_id": term_id, } already_exists = False try: canvas_course = account.create_course(course=course) except Exception: try: canvas_course = get_canvas(test).get_course( sis_course_id, use_sis_id=True) canvas_course.update(course=course) already_exists = True except Exception as error: add_request_process_notes( "course site creation failed--check if it already exists", request, ) message = f"\t- ERROR: failed to create site ({error})" getLogger("error_logger").error(message) if verbose: print(message) continue try: canvas_course.update(course={"storage_quota_mb": 2000}) except Exception: add_request_process_notes("course site quota not raised", request) if not already_exists: try: additional_section = { "course_section": "", "instructors": "" } additional_section[ "course_section"] = canvas_course.create_course_section( course_section={ "name": section_name, "sis_section_id": sis_course_id, }, enable_sis_reactivation=True, ) MAIN_SECTION = additional_section["course_section"] additional_section[ "instructors"] = course_requested.instructors.all() additional_sections += [additional_section] except Exception as error: add_request_process_notes("failed to create main section", request) message = f"\t- ERROR: failed to create main section ({error})" getLogger("error_logger").error(message) if verbose: print(message) section_already_exists = True continue else: add_request_process_notes("failed to locate Canvas Account", request) message = "\t- ERROR: failed to locate Canvas Account" getLogger("error_logger").error(message) if verbose: print(message) continue if request.title_override: namebit = request.title_override else: namebit = course_requested.course_name if sections: sections = [section.course_code for section in sections] try: serialized.data["additonal_sections"] = serialized.data[ "additional_sections"].extend(sections) except Exception: serialized.data["additional_sections"] = sections for section in serialized.data["additional_sections"]: try: section_course = Course.objects.get(course_code=section) if section_course.course_activity.abbr != "LEC": namebit = section_course.course_activity.abbr sis_section = f"SRS_{section_course.srs_format_primary()}" additional_section = {"course_section": "", "instructors": ""} additional_section[ "course_section"] = canvas_course.create_course_section( course_section={ "name": section_course.srs_format_primary(sis_id=False) + " " + namebit, "sis_section_id": sis_section, }, enable_sis_reactivation=True, ) additional_section[ "instructors"] = section_course.instructors.all() additional_sections += [additional_section] except Exception as error: add_request_process_notes("failed to create section", request) message = f"\t- ERROR: failed to create section ({error})" getLogger("error_logger").error(message) if verbose: print(message) enrollment_types = { "INST": "TeacherEnrollment", "instructor": "TeacherEnrollment", "TA": "TaEnrollment", "ta": "TaEnrollment", "DES": "DesignerEnrollment", "designer": "DesignerEnrollment", "LIB": "DesignerEnrollment", "librarian": "DesignerEnrollment", } librarian_role_id = "1383" for section in additional_sections: for instructor in section["instructors"]: user = get_user_by_sis(instructor.username, test=test) if user is None: try: user = create_canvas_user( instructor.username, instructor.profile.penn_id, instructor.email, f"{instructor.first_name} {instructor.last_name}", test=test, ) add_request_process_notes( f"created account for user: {instructor.username}", request) except Exception: add_request_process_notes( f"failed to create account for user: {instructor.username}", request, ) try: canvas_course.enroll_user( user.id, "TeacherEnrollment", enrollment={ "enrollment_state": "active", "course_section_id": section["course_section"].id, }, ) except Exception: add_request_process_notes( f"failed to add user: {instructor.username}", request) additional_enrollments = serialized.data["additional_enrollments"] for enrollment in additional_enrollments: user = enrollment["user"] role = enrollment["role"] user_canvas = get_user_by_sis(user) if user_canvas is None: try: user_crf = User.objects.get(username=user) user_canvas = create_canvas_user( user, user_crf.profile.penn_id, user_crf.email, user_crf.first_name + user_crf.last_name, ) add_request_process_notes( f"created account for user: {instructor.username}", request) except Exception: add_request_process_notes( f"failed to create account for user: {instructor.username}", request, ) if role == "LIB" or role == "librarian": try: canvas_course.enroll_user( user_canvas.id, enrollment_types[role], enrollment={ "course_section_id": MAIN_SECTION.id, "role_id": librarian_role_id, "enrollment_state": "active", }, ) except Exception: add_request_process_notes(f"failed to add user: {user}", request) else: try: canvas_course.enroll_user( user_canvas.id, enrollment_types[role], enrollment={ "course_section_id": MAIN_SECTION.id, "enrollment_state": "active", }, ) except Exception: add_request_process_notes(f"failed to add user: {user}", request) if serialized.data["reserves"]: try: tab = Tab( canvas_course._requester, { "course_id": canvas_course.id, "id": "context_external_tool_139969", "label": "Course Materials @ Penn Libraries", }, ) tab.update(hidden=False) if tab.visibility != "public": add_request_process_notes("failed to configure ARES", request) except Exception as error: message = f"\t- ERROR: {error}" getLogger("error_logger").error(message) if verbose: print(message) add_request_process_notes("failed to try to configure ARES", request) if serialized.data["copy_from_course"]: try: if verbose: print("\t* Copying course data from course id" f" {serialized.data['copy_from_course']}...") source_course_id = serialized.data["copy_from_course"] content_migration = canvas_course.create_content_migration( migration_type="course_copy_importer", settings={"source_course_id": source_course_id}, ) while (content_migration.get_progress().workflow_state == "queued" or content_migration.get_progress().workflow_state == "running"): if verbose: print("\t* Migration running...") time.sleep(8) if verbose: print("\t- MIGRATION COMPLETE") print("\t* Deleting Zoom events...") canvas = get_canvas(test) course_string = f"course_{canvas_course.id}" events = canvas.get_calendar_events( context_codes=[course_string], all_events=True) zoom_events = list() for event in events: if ((event.location_name and "zoom" in event.location_name.lower()) or (event.description and "zoom" in event.description.lower()) or (event.title and "zoom" in event.title.lower())): zoom_events.append(event.id) for event_id in zoom_events: event = canvas.get_calendar_event(event_id) deleted = event.delete(cancel_reason=( "Zoom event was copied from a previous term and is no" " longer relevant")) if verbose: print(f"\t- Event '{deleted}' deleted.") except Exception as error: message = f"\t- ERROR: {error}" getLogger("error_logger").error(message) if verbose: print(message) instructors = canvas_course.get_enrollments( type="TeacherEnrollment")._elements canvas_id = canvas_course.id request_instance = request name = canvas_course.name sis_course_id = canvas_course.sis_course_id workflow_state = canvas_course.workflow_state site = CanvasSite.objects.update_or_create( canvas_id=canvas_id, defaults={ "request_instance": request_instance, "name": name, "sis_course_id": sis_course_id, "workflow_state": workflow_state, }, )[0] request.canvas_instance = site for instructor in instructors: try: user = User.objects.get(username=instructor) site.owners.add(user) except Exception: pass request.status = "COMPLETED" request.save() if verbose: print(f"- Canvas site successfully created: {site}.") if verbose: print("FINISHED") if section_already_exists: return "section already exists"