UNPKG

@byu-oit/canvas-sdk

Version:

A wrapper around Instructure's Canvas API

192 lines (169 loc) 7.63 kB
'use strict'; const logger = require('./utils/logger'); const uuid = require('uuid'); const PromiseArray = require('promise-subarrays'); module.exports = function(canvas) { const sections = {}; sections.exists = async function(sisSectionId) { const res = await canvas.request('GET', `sections/sis_section_id:${sisSectionId}`); if(res) { return true; } else { return false; } }; sections.add = async function(sisCourseId, sisSectionId, sectionName) { const options = { 'course_section': { 'name': sectionName, 'sis_section_id': sisSectionId, 'enable_sis_reactivation': true } }; const res = await canvas.request('POST', `courses/sis_course_id:${sisCourseId}/sections`, options); if(res) { logger.info(`Successfully added section ${sisSectionId} to course ${sisCourseId}`); return res; } else { logger.info(`Failed to add section ${sisSectionId} to course ${sisCourseId}`); } }; sections.get = async function(sisSectionId) { return await canvas.request('GET', `sections/sis_section_id:${sisSectionId}?include=students`); }; sections.getAllByTerm = async function(sisTermId) { const courses = await canvas.courses.getAllByTerm(sisTermId); const sections = []; const promiseArray = PromiseArray(); for(let course of courses) { promiseArray.push(async function(course) { logger.info(`Getting sections for course ${course.sis_course_id}`); const courseSections = await canvas.requestAll(`courses/${course.id}/sections`); // include[]=enrollments results in a 504 on large courses. Work around below. for(let courseSection of courseSections) { // Now pull down just the section but include the students and enrollments courseSection = await canvas.request('GET', `courses/${course.id}/sections/${courseSection.id}?include[]=students&include[]=enrollments`); courseSection.account_id = course.account_id; courseSection.workflow_state = course.workflow_state; sections.push(courseSection); } }, [course]); } await promiseArray.awaitAll(canvas.maxSimultaneousRequests); return sections; }; sections.enrollUser = async function(sisSectionId, sisUserId, enrollmentType, limitPriviledges) { const options = { 'enrollment': { 'user_id': `sis_user_id:${sisUserId}`, 'type': enrollmentType, 'enrollment_state': 'active', 'limit_privileges_to_course_section': limitPriviledges } }; logger.debug(`enroll user options = ${JSON.stringify(options)}`); const res = await canvas.request('POST', `sections/sis_section_id:${sisSectionId}/enrollments`, options); if(res) { logger.info(`Successfully enrolled user with sisUserId = ${sisUserId} in section with sisSectionId = ${sisSectionId}`); return res; } else { logger.error(`Failed to enroll user with sisUserId = ${sisUserId} in section with sisSectionId = ${sisSectionId}`); } }; sections.isEnrolled = async function(sisSectionId, sisUserId) { const enrollment = await sections.getEnrollment(sisSectionId, sisUserId); if(enrollment) { return true; } else { return false; } }; sections.getEnrollment = async function(sisSectionId, sisUserId, type) { if(!sisSectionId) { logger.error("Must provide sisSectionId to sections.getEnrollment"); } let url = `users/sis_user_id:${sisUserId}/enrollments?sis_section_id=${sisSectionId}&state[]=active&state[]=invited&state[]=inactive&state[]=completed`; if(type) { url = `${url}&type[]=${type}`; } const res = await canvas.request('GET', url.toString()); if(res) { if(res.length > 1) { logger.error('Too many enrollments returned in sections.getEnrollment'); return false; } else { return res[0]; } } else { return false; } }; sections.changeEnrollment = async function(sisSectionId, sisUserId, task, type) { const enrollment = await sections.getEnrollment(sisSectionId, sisUserId, type); if(enrollment) { const options = { task: task }; const res = await canvas.request('DELETE', `courses/${enrollment.course_id}/enrollments/${enrollment.id}`, options); if(res) { logger.info(`Successfully applied task = ${task} to the enrollment of user with sisUserId = ${sisUserId} to section with sisSectionId = ${sisSectionId}`); return true; } else { logger.error(`Failed to apply task = ${task} to the enrollment of user with sisUserId = ${sisUserId} to section with sisSectionId = ${sisSectionId}`); return false; } } else { const msg = `Enrollment not found while trying to apply task = ${task} to the enrollment of user with sisUserId = ${sisUserId} to section with sisSectionId = ${sisSectionId}`; if(task === "delete") { logger.info(msg); return true; } else { logger.error(msg); return false; } } }; sections.getAllEnrollments = async function(sisSectionId) { return await canvas.requestAll(`sections/sis_section_id:${sisSectionId}/enrollments`); }; sections.updName = async function(sisSectionId,name) { const options = { course_section: { name:name } }; const res = await canvas.request('PUT', `sections/sis_section_id:${sisSectionId}`, options); if(res) { logger.info(`Successfully updated section name to ${name} for ${sisSectionId}`); } else { logger.error(`Failed to update section name to ${name} for ${sisSectionId}`); } }; sections.delete = async function(sisSectionId) { // Delete all enrollments prior to deleting section const enrollments = await sections.getAllEnrollments(sisSectionId); const promiseArray = PromiseArray(); for(let enrollment of enrollments) { promiseArray.push(sections.changeEnrollment, [sisSectionId, enrollment.sis_user_id, "delete", enrollment.type]); } await promiseArray.awaitAll(canvas.maxSimultaneousRequests); const newId = uuid(); const options = { course_section: { sis_section_id: newId } }; let res; res = await canvas.request('PUT', `sections/sis_section_id:${sisSectionId}`, options); if(!res) { logger.error(`Failed to scramble sisSectionId prior to deleting account with sisSectionId = ${sisSectionId}`); } else { res = await canvas.request('DELETE', `sections/${res.id}`); if(res) { logger.info(`Successfully deleted section with sisSectionId = ${sisSectionId}`); } else { logger.error(`Failed to delete section with sisSectionId = ${sisSectionId}`); } } }; return sections; };