in microservices/lms/src/services/section_service.py [0:0]
def copy_course_background_task(course_template_details,
sections_details,
cohort_details,
lms_job_id,current_course,
message=""):
"""Create section Background Task to copy course and updated database
for newly created section
Args:
course_template_details (template object): course template object which
will referenced in section
sections_details (str):Input section details provided by user in API
cohort_details(str):course template object which will
referenced in section
headers(str):Authentications headers
Raises:
HTTPException: 500 Internal Server Error if something fails
Returns:
True : (bool) on success
"""
lms_job = LmsJob.find_by_id(lms_job_id)
logs = lms_job.logs
Logger.info(current_course)
try:
# Create a new course
info_msg = f"Background Task started for the cohort id {cohort_details.id}\
course template {course_template_details.id} \
with section name{sections_details.name}"
logs["info"].append(info_msg)
Logger.info(info_msg)
new_course = classroom_crud.create_course(course_template_details.name,
sections_details.description,
sections_details.name, "me")
lms_job.classroom_id = new_course["id"]
lms_job.start_time = datetime.datetime.utcnow()
lms_job.status = "running"
lms_job.update()
# Create section with the required fields
section = Section()
section.name = course_template_details.name
section.section = sections_details.name
section.description = sections_details.description
section.max_students = sections_details.max_students
# Reference document can be get using get() method
section.course_template = course_template_details
section.cohort = cohort_details
section.classroom_id = new_course["id"]
section.classroom_code = new_course["enrollmentCode"]
section.classroom_url = new_course["alternateLink"]
section.enrolled_students_count = 0
section.status = "PROVISIONING"
section_id = section.save().id
classroom_id = new_course["id"]
lms_job.section_id = section_id
lms_job.update()
error_flag = False
target_folder_id = new_course["teacherFolder"]["id"]
logs["info"].append(
f"ID of target drive folder for section {target_folder_id}")
Logger.info(f"ID of target drive folder for section {target_folder_id}")
# Get topics of current course
topics = classroom_crud.get_topics(course_template_details.classroom_id)
# add new_course to pubsub topic for both course work and roaster changes
classroom_crud.enable_notifications(new_course["id"], "COURSE_WORK_CHANGES")
classroom_crud.enable_notifications(new_course["id"],
"COURSE_ROSTER_CHANGES")
# add instructional designer
list_course_template_enrollment_mapping = CourseTemplateEnrollmentMapping\
.fetch_all_by_course_template(course_template_details.key)
if list_course_template_enrollment_mapping:
for course_template_mapping in list_course_template_enrollment_mapping:
try:
add_instructional_designer_into_section(section,
course_template_mapping)
except Exception as error:
error = traceback.format_exc().replace("\n", " ")
Logger.error(f"Create teacher failed for \
for {course_template_details.instructional_designer}")
Logger.error(error)
#If topics are present in course create topics returns a dict
# with keys a current topicID and new topic id as values
if topics is not None:
topic_id_map = classroom_crud.create_topics(new_course["id"], topics)
# Calling function to get edit_url and view url of
# google form which returns
# a dictionary of view_links as keys and edit
# links/ and file_id as values for all drive files
# url_mapping = classroom_crud.get_edit_url_and_view_url_mapping_of_folder(
# current_course["teacherFolder"]["id"])
# Get coursework of current course and create a new course
coursework_list = classroom_crud.get_coursework_list(
course_template_details.classroom_id)
# final_coursewok=[]
for coursework in coursework_list:
coursework_lti_assignment_ids = []
try:
#Check if a coursework is linked to a topic if yes then
# replace the old topic id to new topic id using topic_id_map
lti_assignment_details = {
"section_id": section_id,
"source_context_id": course_template_details.id,
"coursework_title": coursework["title"],
"start_date": None,
"end_date": None,
"due_date": None
}
# Update the due date of the course work if exists
if coursework.get("dueDate"):
coursework_due_date = coursework.get("dueDate")
if coursework.get("dueTime"):
coursework_due_time = coursework.get("dueTime")
coursework_due_datetime = datetime.datetime(
coursework_due_date.get("year"),
coursework_due_date.get("month"),
coursework_due_date.get("day"),
coursework_due_time.get("hours", 0),
coursework_due_time.get("minutes", 0))
else:
coursework_due_datetime = datetime.datetime(
coursework_due_date.get("year"),
coursework_due_date.get("month"),
coursework_due_date.get("day"))
curr_utc_timestamp = datetime.datetime.utcnow()
lti_assignment_details["start_date"] = (
cohort_details.start_date).strftime("%Y-%m-%dT%H:%M:%S%z")
if coursework_due_datetime < curr_utc_timestamp:
# Commented for now as the due dates are supposed to be updated by the user before
# starting the copy course process
# coursework["dueDate"] = {
# "year": cohort_details.end_date.year,
# "month": cohort_details.end_date.month,
# "day": cohort_details.end_date.day
# }
# coursework["dueTime"] = {
# "hours": cohort_details.end_date.hour,
# "minutes": cohort_details.end_date.minute
# }
lti_assignment_details["end_date"] = lti_assignment_details[
"due_date"] = (
cohort_details.end_date).strftime("%Y-%m-%dT%H:%M:%S%z")
else:
lti_assignment_details["end_date"] = lti_assignment_details[
"due_date"] = coursework_due_datetime.strftime(
"%Y-%m-%dT%H:%M:%S%z")
if "topicId" in coursework.keys():
coursework["topicId"] = topic_id_map[coursework["topicId"]]
#Check if a material is present in coursework
if "materials" in coursework.keys():
coursework_update_output = update_coursework_material(
materials=coursework["materials"],
target_folder_id=target_folder_id,
error_flag=error_flag,
lti_assignment_details=lti_assignment_details,
logs=logs)
coursework["materials"] = coursework_update_output["material"]
error_flag = coursework_update_output["error_flag"]
coursework_lti_assignment_ids.extend(
coursework_update_output["lti_assignment_ids"])
# final_coursewok.append(coursework)
coursework_data = classroom_crud.create_coursework(
new_course["id"], coursework)
for assignment_id in coursework_lti_assignment_ids:
coursework_id = coursework_data.get("id")
input_json = {"course_work_id": coursework_id}
# update assignment with new coursework id
lti_assignment_req = requests.patch(
f"http://classroom-shim/classroom-shim/api/v1/lti-assignment/{assignment_id}",
headers={
"Authorization": f"Bearer {auth_client.get_id_token()}"
},
json=input_json,
timeout=60)
if lti_assignment_req.status_code != 200:
error_flag = True
error_msg = f"Failed to update assignment {assignment_id} with course work id \
{coursework_id} due to error - {lti_assignment_req.text} with \
status code - {lti_assignment_req.status_code} for course work"
logs["errors"].append(error_msg)
Logger.error(error_msg)
logs["info"].append(
f"Updated the course work id for new LTI assignment - {assignment_id}"
)
Logger.info(
f"Updated the course work id for new LTI assignment - {assignment_id}"
)
except Exception as error:
title = coursework["title"]
error_flag = True
logs["errors"].append(f"Error - {error} for '{title}'")
logs["errors"].append(f"Copy coursework failed for \
course_id {course_template_details.classroom_id} for '{title}'")
Logger.error(f"Copy coursework failed for \
course_id {course_template_details.classroom_id} for '{title}'")
error = traceback.format_exc().replace("\n", " ")
Logger.error(error)
continue
# # Create coursework in new course
# # return final_coursewok
# if final_coursewok is not None:
# classroom_crud.create_coursework(new_course["id"],final_coursewok)
# Get the list of courseworkMaterial
# final_coursewok_material = []
coursework_material_list = classroom_crud.get_coursework_material_list(
course_template_details.classroom_id)
for coursework_material in coursework_material_list:
coursework_material_lti_assignment_ids = []
try:
#Check if a coursework material is linked to a topic if yes then
# replace the old topic id to new topic id using topic_id_map
lti_assignment_details = {
"section_id": section_id,
"source_context_id": course_template_details.id,
"coursework_title": coursework_material["title"],
"start_date": None,
"end_date": None,
"due_date": None
}
if "topicId" in coursework_material.keys():
coursework_material["topicId"] = topic_id_map[
coursework_material["topicId"]]
#Check if a material is present in coursework
if "materials" in coursework_material.keys():
coursework_material_update_output = update_coursework_material(
materials=coursework_material["materials"],
target_folder_id=target_folder_id,
error_flag=error_flag,
lti_assignment_details=lti_assignment_details,
logs=logs)
coursework_material["materials"] = coursework_material_update_output[
"material"]
error_flag = coursework_update_output["error_flag"]
coursework_material_lti_assignment_ids.extend(
coursework_update_output["lti_assignment_ids"])
print("Updated coursework material attached")
coursework_material_data = classroom_crud.create_coursework_material(new_course["id"],
coursework_material)
for assignment_id in coursework_material_lti_assignment_ids:
coursework_id = coursework_material_data.get("id")
input_json = {"course_work_id": coursework_id}
# update assignment with new coursework id
lti_assignment_req = requests.patch(
f"http://classroom-shim/classroom-shim/api/v1/lti-assignment/{assignment_id}",
headers={
"Authorization": f"Bearer {auth_client.get_id_token()}"
},
json=input_json,
timeout=60)
if lti_assignment_req.status_code != 200:
error_flag = True
error_msg = f"Failed to update assignment {assignment_id} with course work id \
{coursework_id} due to error - {lti_assignment_req.text} with \
status code - {lti_assignment_req.status_code} for course work material"
logs["errors"].append(error_msg)
Logger.error(error_msg)
logs["info"].append(
f"Updated the id for course work material for new LTI assignment - {assignment_id}"
)
Logger.info(
f"Updated the id course work material for new LTI assignment - {assignment_id}"
)
# final_coursewok_material.append(coursework_material)
except Exception as error:
title = coursework_material["title"]
error_flag = True
Logger.error(f"Get coursework material failed for\
course_id {course_template_details.classroom_id} for {title}")
logs["errors"].append(f"Error - {error}")
logs["errors"].append(f"Get coursework material failed for\
course_id {course_template_details.classroom_id} for {title}")
error = traceback.format_exc().replace("\n", " ")
Logger.error(error)
continue
# # Create coursework in new course
# if final_coursewok_material is not None:
# classroom_crud.create_coursework_material(new_course["id"],
# final_coursewok_material)
# Classroom copy is successful then the section status is changed to active
if error_flag:
section.status = "FAILED_TO_PROVISION"
else:
section.status = "ACTIVE"
section.update()
rows=[{
"sectionId":section_id,\
"courseId":new_course["id"],\
"classroomUrl":new_course["alternateLink"],\
"name":new_course["section"],\
"description":new_course["description"],\
"cohortId":cohort_details.id,\
"courseTemplateId":course_template_details.id,\
"status":section.status,\
"enrollmentStatus": section.enrollment_status,
"maxStudents": section.max_students,
"timestamp":datetime.datetime.utcnow()
}]
insert_rows_to_bq(
rows=rows,
dataset=BQ_DATASET,
table_name=BQ_TABLE_DICT["BQ_COLL_SECTION_TABLE"])
Logger.info(message)
Logger.info(f"Background Task Completed for section Creation for cohort\
{cohort_details.id}")
Logger.info(f"Section Details are section id {section_id},\
classroom id {classroom_id}")
logs["info"].append(
f"Background Task Completed for section Creation for cohort\
{cohort_details.id}")
logs["info"].append(f"Section Details are section id {section_id},\
classroom id {classroom_id}")
lms_job.logs = logs
if error_flag:
lms_job.status = "failed"
else:
lms_job.status = "success"
lms_job.end_time = datetime.datetime.utcnow()
lms_job.update()
return True
except Exception as e:
error = traceback.format_exc().replace("\n", " ")
Logger.error(error)
Logger.error(e)
logs["errors"].append(str(e))
lms_job.logs = logs
lms_job.end_time = datetime.datetime.utcnow()
lms_job.status = "failed"
lms_job.update()
raise InternalServerError(str(e)) from e