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 = 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)
Example #3
0
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 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 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)
Example #6
0
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)
Example #7
0
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 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 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)
Example #10
0
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)
Example #11
0
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)
Example #12
0
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)
Example #13
0
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)
Example #15
0
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)
Example #17
0
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_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)