def set_access_level(request, mailing_list_id): """ Sets the access_level for the given mailing_list on the listserv service :param request: :param mailing_list_id: :return: JSON response containing the updated mailing list data """ try: logged_in_user_id = request.LTI['lis_person_sourcedid'] access_level = json.loads(request.body)['access_level'] mailing_list = MailingList.objects.get(id=mailing_list_id) mailing_list.modified_by = logged_in_user_id mailing_list.access_level = access_level mailing_list.save() cache.delete(settings.CACHE_KEY_LISTS_BY_CANVAS_COURSE_ID % mailing_list.canvas_course_id) result = { 'id': mailing_list.id, 'address': mailing_list.address, 'access_level': access_level } except Exception: message = u"Failed to activate MailingList %s with LTI params %s" % (mailing_list_id, json.dumps(request.LTI)) logger.exception(message) return create_json_500_response(message) return create_json_200_response(result)
def lists(request): """ Gets the list of mailing lists for the course in the current session context :param request: :return: JSON response containing the mailing lists for the course in this session context """ try: canvas_course_id = request.LTI['custom_canvas_course_id'] logged_in_user_id = request.LTI['lis_person_sourcedid'] mailing_lists = MailingList.objects.get_or_create_or_delete_mailing_lists_for_canvas_course_id( canvas_course_id, defaults={ 'created_by': logged_in_user_id, 'modified_by': logged_in_user_id }) except Exception: message = "Failed to get_or_create MailingLists with LTI params %s" % json.dumps( request.LTI) logger.exception(message) return create_json_500_response(message) return create_json_200_response(mailing_lists)
def lists(request): """ Gets the list of mailing lists for the course in the current session context :param request: :return: JSON response containing the mailing lists for the course in this session context """ try: canvas_course_id = request.LTI['custom_canvas_course_id'] logged_in_user_id = request.LTI['lis_person_sourcedid'] mailing_lists = MailingList.objects.get_or_create_or_delete_mailing_lists_for_canvas_course_id( canvas_course_id, defaults={ 'created_by': logged_in_user_id, 'modified_by': logged_in_user_id } ) except Exception: message = u"Failed to get_or_create MailingLists with LTI params %s" % json.dumps(request.LTI) logger.exception(message) return create_json_500_response(message) return create_json_200_response(mailing_lists)
def schools(request): """ Gets the list of schools that the current user has permission to manage :param request: :return: JSON response containing the list of schools """ try: data = get_school_data_for_user(request.LTI['custom_canvas_user_id']) return create_json_200_response(data) except Exception: message = "Failed to get schools with LTI params %s" % json.dumps(request.LTI) logger.exception(message) return create_json_500_response(message)
def departments(request, sis_account_id): """ Gets the list of departments that the current user has permission to manage :param request: :param sis_account_id: The sis_account_id for which to find departments :return: JSON response containing the list of departments """ try: data = get_department_data_for_school(sis_account_id) return create_json_200_response(data) except Exception: message = "Failed to get departments with sis_account_id %s" % sis_account_id logger.exception(message) return create_json_500_response(message)
def terms(request, sis_account_id): """ Gets the list of terms for a given school :param request: :param sis_account_id: The sis_account_id for which to find terms :return: JSON response containing the list of terms """ try: data, _ = get_term_data_for_school(sis_account_id) return create_json_200_response(data) except Exception: message = "Failed to get terms with sis_account_id %s" % sis_account_id logger.exception(message) return create_json_500_response(message)
def course_groups(request, sis_account_id): """ Gets the list of course_groups that the current user has permission to manage :param request: :param sis_account_id: The sis_account_id for which to find course_groups :return: JSON response containing the list of course_groups """ try: data = get_course_group_data_for_school(request.LTI['custom_canvas_user_id'], sis_account_id) return create_json_200_response(data) except Exception: message = "Failed to get course groups with sis_account_id %s" % sis_account_id logger.exception(message) return create_json_500_response(message)
def course_groups(request, sis_account_id): """ Gets the list of course_groups that the current user has permission to manage :param request: :param sis_account_id: The sis_account_id for which to find course_groups :return: JSON response containing the list of course_groups """ try: data = get_course_group_data_for_school( request.LTI['custom_canvas_user_id'], sis_account_id) return create_json_200_response(data) except Exception: message = "Failed to get course groups with sis_account_id %s" % sis_account_id logger.exception(message) return create_json_500_response(message)
def schools(request): """ Gets the list of schools that the current user has permission to manage :param request: :return: JSON response containing the list of schools """ try: data = get_school_data_for_sis_account_id( request.LTI['custom_canvas_account_sis_id']) return create_json_200_response(data) except Exception: message = "Failed to get schools with Canvas account_sis_id %s"\ % request.LTI['custom_canvas_account_sis_id'] logger.exception(message) return create_json_500_response(message)
def set_access_level(request, mailing_list_id): """ Sets the access_level for the given mailing_list on the listserv service :param request: :param mailing_list_id: :return: JSON response containing the updated mailing list data """ ACCESS_LEVELS = ('staff', 'members', 'readonly') access_level = json.loads(request.body)['access_level'] if access_level not in ACCESS_LEVELS: logger.warn( f"{access_level} not a valid access_level. Mailing list {mailing_list_id} not modified." ) raise PermissionDenied try: logged_in_user_id = request.LTI['lis_person_sourcedid'] mailing_list = MailingList.objects.get(id=mailing_list_id) mailing_list.modified_by = logged_in_user_id mailing_list.access_level = access_level mailing_list.save() cache.delete(settings.CACHE_KEY_LISTS_BY_CANVAS_COURSE_ID % mailing_list.canvas_course_id) result = { 'id': mailing_list.id, 'address': mailing_list.address, 'access_level': access_level } except Exception: message = "Failed to activate MailingList %s with LTI params %s" % ( mailing_list_id, json.dumps(request.LTI)) logger.exception(message) return create_json_500_response(message) return create_json_200_response(result)
def course_instance_summary(request, sis_term_id, sis_account_id): """ Return counts of course instances using the GET parameters given :param request: :param sis_term_id: The SIS term to count course instances for :param sis_account_id: The Canvas account ID for the school to count course instances for :return: JSON response containing the course instance counts """ result = {} try: query_set = get_course_instance_query_set(sis_term_id, sis_account_id) result = get_course_instance_summary_data(query_set) except Exception: logger.exception( "Failed to get course_instance_summary with LTI params %s and GET params %s", json.dumps(request.LTI), json.dumps(request.GET)) result[ 'error'] = 'There was a problem counting courses. Please try again.' return create_json_500_response(result) return create_json_200_response(result)
def course_instance_summary(request, sis_term_id, sis_account_id): """ Return counts of course instances using the GET parameters given :param request: :param sis_term_id: The SIS term to count course instances for :param sis_account_id: The Canvas account ID for the school to count course instances for :return: JSON response containing the course instance counts """ result = {} try: query_set = get_course_instance_query_set(sis_term_id, sis_account_id) result = get_course_instance_summary_data(query_set) except Exception: logger.exception( "Failed to get course_instance_summary with LTI params %s and GET params %s", json.dumps(request.LTI), json.dumps(request.GET) ) result['error'] = 'There was a problem counting courses. Please try again.' return create_json_500_response(result) return create_json_200_response(result)
def get_or_create_course_settings(request): """ method allows both GET and PUT requests. If GET is used, we will try to get the object if the object does not exist, it will be created with default values. If put is used, we will try to get the object if the object does not exist, it will be created and the put value will be used instead of the default. :param request: :return: JSON response of the course settings object """ logged_in_user_id = request.LTI['lis_person_sourcedid'] canvas_course_id = request.LTI['custom_canvas_course_id'] try: (course_settings, created) = CourseSettings.objects.get_or_create( canvas_course_id=canvas_course_id) if request.method == 'GET' and not created: pass # just return data, don't update/save record with timestamp else: if request.method == 'PUT': always_mail_staff_flag = json.loads( request.body)['always_mail_staff'] course_settings.always_mail_staff = always_mail_staff_flag course_settings.modified_by = logged_in_user_id course_settings.save() cache.delete(settings.CACHE_KEY_LISTS_BY_CANVAS_COURSE_ID % canvas_course_id) except Exception: message = "Failed to get_or_create CourseSettings for course %s" % canvas_course_id logger.exception(message) return create_json_500_response(message) result = { 'canvas_course_id': course_settings.canvas_course_id, 'always_mail_staff': course_settings.always_mail_staff, } return create_json_200_response(result)
def get_or_create_course_settings(request): """ method allows both GET and PUT requests. If GET is used, we will try to get the object if the object does not exist, it will be created with default values. If put is used, we will try to get the object if the object does not exist, it will be created and the put value will be used instead of the default. :param request: :return: JSON response of the course settings object """ logged_in_user_id = request.LTI['lis_person_sourcedid'] canvas_course_id = request.LTI['custom_canvas_course_id'] try: (course_settings, created) = CourseSettings.objects.get_or_create( canvas_course_id=canvas_course_id) if request.method == 'GET' and not created: pass # just return data, don't update/save record with timestamp else: if request.method == 'PUT': always_mail_staff_flag = json.loads(request.body)[ 'always_mail_staff'] course_settings.always_mail_staff = always_mail_staff_flag course_settings.modified_by = logged_in_user_id course_settings.save() cache.delete( settings.CACHE_KEY_LISTS_BY_CANVAS_COURSE_ID % canvas_course_id) except Exception: message = u"Failed to get_or_create CourseSettings for course %s" % canvas_course_id logger.exception(message) return create_json_500_response(message) result = { 'canvas_course_id': course_settings.canvas_course_id, 'always_mail_staff': course_settings.always_mail_staff, } return create_json_200_response(result)
def course_instances(request, sis_term_id, sis_account_id): """ Searches for course instances using the GET parameters given :param request: :param sis_term_id: The SIS term to find course instances for :param sis_account_id: The Canvas account ID for the school to find course instances for :return: JSON response containing the list of course instances """ result = {} try: (draw, start, limit, sort_index, sort_dir, search) = _unpack_datatables_params(request) query_set = get_course_instance_query_set(sis_term_id, sis_account_id) query_set = query_set.select_related('course') # Apply text search filter if search: query_set = query_set.filter( Q(course_instance_id__contains=search) | Q(course__registrar_code__icontains=search) | Q(course__registrar_code_display__icontains=search) | Q(title__icontains=search)) order_by_operator = '-' if sort_dir == 'desc' else '' query_set = query_set.order_by(order_by_operator + COURSE_INSTANCE_DATA_FIELDS[sort_index]) # fixes TLT-1570 where courses that already have a Canvas course were showing up # in the create list query_set = query_set.exclude(canvas_course_id__isnull=False) result = get_course_instance_summary_data(query_set) data = [] for ci in query_set[start:(start + limit)]: data.append({ 'id': ci.course_instance_id, 'registrar_code': ci.course.registrar_code_display or ci.course.registrar_code, 'title': ci.title, 'course_section': ci.section, 'has_canvas_site': ci.canvas_course_id is not None, }) result['data'] = data result['draw'] = draw except Exception: logger.exception( "Failed to get course_instances with LTI params %s and GET params %s", json.dumps(request.LTI), json.dumps(request.GET)) result[ 'error'] = 'There was a problem searching for courses. Please try again.' return create_json_500_response(result) return JsonResponse(result, status=200, content_type='application/json')
def course_jobs(request, bulk_job_id): """ Searches for individual course creation jobs using the GET parameters given :param request: :return: JSON response containing the list of individual course creation jobs """ result = {} try: (draw, start, limit, sort_index, sort_dir, search) = _unpack_datatables_params(request) order_by_operator = '-' if sort_dir == 'desc' else '' query_set_all = CanvasCourseGenerationJob.objects.filter(bulk_job_id=bulk_job_id).order_by( order_by_operator + COURSE_JOB_DATA_FIELDS[sort_index] ) result.update(get_course_job_summary_data(bulk_job_id)) result['draw'] = draw jobs = [] creator_ids = [] course_instance_ids = [] for course_job in query_set_all[start:(start + limit)]: jobs.append(course_job) creator_ids.append(course_job.created_by_user_id) course_instance_ids.append(course_job.sis_course_id) creators = {p.univ_id: p for p in Person.objects.filter(univ_id__in=creator_ids)} course_instances = { str(ci.course_instance_id): ci for ci in CourseInstance.objects.filter( course_instance_id__in=course_instance_ids ) } data = [] for job in jobs: try: creator = creators[job.created_by_user_id] creator_name = "%s, %s" % (creator.name_last, creator.name_first) except KeyError: # Course job creator could not be found logger.warning("Failed to find canvas course site job creator %s", job.created_by_user_id) creator_name = '' course_instance = course_instances[job.sis_course_id] data.append({ 'id': job.id, 'created_at': timezone.localtime(job.created_at).strftime('%b %d, %Y %H:%M:%S'), 'status': job.status_display_name, 'created_by': creator_name, 'sis_course_id': job.sis_course_id, 'registrar_code': course_instance.course.registrar_code_display, 'course_title': course_instance.title, 'canvas_course_id': job.canvas_course_id }) result['data'] = data except Exception: logger.exception( "Failed to get course jobs with LTI params %s and GET params %s", json.dumps(request.LTI), json.dumps(request.GET) ) result['error'] = 'There was a problem searching for course jobs. Please try again.' return create_json_500_response(result) return create_json_200_response(result)
def course_instances(request, sis_term_id, sis_account_id): """ Searches for course instances using the GET parameters given :param request: :param sis_term_id: The SIS term to find course instances for :param sis_account_id: The Canvas account ID for the school to find course instances for :return: JSON response containing the list of course instances """ result = {} try: (draw, start, limit, sort_index, sort_dir, search) = _unpack_datatables_params(request) query_set = get_course_instance_query_set(sis_term_id, sis_account_id) query_set = query_set.select_related('course') # Added prefetch_related here to reduce hitting the database again later # when we query for the associated iSites. query_set = query_set.prefetch_related('sites') # Apply text search filter if search: query_set = query_set.filter( Q(course_instance_id__contains=search) | Q(course__registrar_code__icontains=search) | Q(course__registrar_code_display__icontains=search) | Q(title__icontains=search) ) order_by_operator = '-' if sort_dir == 'desc' else '' query_set = query_set.order_by(order_by_operator + COURSE_INSTANCE_DATA_FIELDS[sort_index]) # fixes TLT-1570 where courses that already have a Canvas course were showing up # in the create list query_set = query_set.exclude(canvas_course_id__isnull=False) result = get_course_instance_summary_data(query_set) data = [] for ci in query_set[start:(start + limit)]: # Get associated iSites keywords and external URL if present(TLT-1578) sites = [site.external_id for site in ci.sites.all() if site.site_type_id in ['isite', 'external']] official = [site_map.map_type_id for site_map in ci.sitemap_set.all()] data.append({ 'id': ci.course_instance_id, 'registrar_code': ci.course.registrar_code_display or ci.course.registrar_code, 'title': ci.title, 'course_section': ci.section, 'has_canvas_site': ci.canvas_course_id is not None, 'associated_sites': ', '.join(sites), 'site_status': ', '.join(official), }) result['data'] = data result['draw'] = draw except Exception: logger.exception( "Failed to get course_instances with LTI params %s and GET params %s", json.dumps(request.LTI), json.dumps(request.GET) ) result['error'] = 'There was a problem searching for courses. Please try again.' return create_json_500_response(result) return create_json_200_response(result)
def course_jobs(request, bulk_job_id): """ Searches for individual course creation jobs using the GET parameters given :param request: :return: JSON response containing the list of individual course creation jobs """ result = {} try: (draw, start, limit, sort_index, sort_dir, search) = _unpack_datatables_params(request) order_by_operator = '-' if sort_dir == 'desc' else '' query_set_all = CanvasCourseGenerationJob.objects.filter( bulk_job_id=bulk_job_id).order_by( order_by_operator + COURSE_JOB_DATA_FIELDS[sort_index]) result.update(get_course_job_summary_data(bulk_job_id)) result['draw'] = draw jobs = [] creator_ids = [] course_instance_ids = [] for course_job in query_set_all[start:(start + limit)]: jobs.append(course_job) creator_ids.append(course_job.created_by_user_id) course_instance_ids.append(course_job.sis_course_id) creators = { p.univ_id: p for p in Person.objects.filter(univ_id__in=creator_ids) } course_instances = { str(ci.course_instance_id): ci for ci in CourseInstance.objects.filter( course_instance_id__in=course_instance_ids) } data = [] for job in jobs: try: creator = creators[job.created_by_user_id] creator_name = "%s, %s" % (creator.name_last, creator.name_first) except KeyError: # Course job creator could not be found logger.warning( "Failed to find canvas course site job creator %s", job.created_by_user_id) creator_name = '' course_instance = course_instances[job.sis_course_id] data.append({ 'id': job.id, 'created_at': timezone.localtime( job.created_at).strftime('%b %d, %Y %H:%M:%S'), 'status': job.status_display_name, 'created_by': creator_name, 'sis_course_id': job.sis_course_id, 'registrar_code': course_instance.course.registrar_code_display, 'course_title': course_instance.title, 'canvas_course_id': job.canvas_course_id }) result['data'] = data except Exception: logger.exception( "Failed to get course jobs with LTI params %s and GET params %s", json.dumps(request.LTI), json.dumps(request.GET)) result[ 'error'] = 'There was a problem searching for course jobs. Please try again.' return create_json_500_response(result) return create_json_200_response(result)