Example #1
0
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,
                    )
Example #2
0
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
Example #3
0
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)
Example #4
0
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})."
            )
Example #5
0
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()
Example #6
0
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"