示例#1
0
def general_times_overview_course(request):
    """
    Return total of seconds viewed on a course
    """
    roles = recoverUserCourseRoles(request)
    allowed_list = [r['course_id'].replace(
        "course", "block") for r in roles['roles'] if r['role'] in settings.BACKEND_ALLOWED_ROLES]

    try:
        course, time__gte, time__lte = verify_time_range_course_params(request)
    except Exception as e:
        return Response(status=status.HTTP_400_BAD_REQUEST, data=str(e))

    # Check that user has permissions
    if course not in allowed_list:
        return Response(status=status.HTTP_403_FORBIDDEN, data="No tiene permisos para ver los datos en los cursos solicitados")

    total_course_time = TimeOnPage.objects.filter(
        vertical__is_active=True,
        vertical__course__icontains=course,
        time__lte=time__lte,
        time__gte=time__gte,
    )
    
    total_course_time = total_course_time.values("vertical__course").annotate(total=Sum("delta_time_float"))
    if total_course_time.count() != 0:
        total_course_time= total_course_time[0]['total']
    else:
        total_course_time = 0
    
    return JsonResponse({
        'total_time': total_course_time,
    })
示例#2
0
def detailed_visits_overview_course(request):
    """
    Compact visits on a course for date, chapter and sequential
    within a date period.
    """
    roles = recoverUserCourseRoles(request)
    allowed_list = [
        r['course_id'].replace("course", "block") for r in roles['roles']
        if r['role'] in settings.BACKEND_ALLOWED_ROLES
    ]

    try:
        course, time__gte, time__lte = verify_time_range_course_params(request)
    except Exception as e:
        return Response(status=status.HTTP_400_BAD_REQUEST, data=str(e))

    # Check that user has permissions
    if course not in allowed_list:
        return Response(
            status=status.HTTP_403_FORBIDDEN,
            data=
            "No tiene permisos para ver los datos en los cursos solicitados")

    total_visits = VisitOnPage.objects.filter(
        vertical__is_active=True,
        vertical__course__icontains=course,
        time__lte=time__lte,
        time__gte=time__gte,
    )
    detailed_visits = {}
    #groupedBy fecha
    date_visits = total_visits.values("time").annotate(total=Sum("count"))
    detailed_visits['date'] = list(date_visits)

    #groupedBy modulo
    module_visits = total_visits.values("vertical__chapter").annotate(
        total=Sum("count"), name=F("vertical__chapter_name"))
    detailed_visits['module'] = list(module_visits)

    #groupedBy unidad
    seq_visits = total_visits.values("vertical__sequential").annotate(
        total=Sum("count"),
        name=F("vertical__sequential_name"),
        chap_number=F("vertical__chapter_number"),
        seq_number=F("vertical__sequential_number"),
    )
    detailed_visits['seq'] = list(seq_visits)

    total_visits = detailed_visits

    return JsonResponse({'total_visits': total_visits})
示例#3
0
def general_visits_overview_course(request):
    """
    Recover general visits overview for course.

    Recover total visits on period and total students
    """
    roles = recoverUserCourseRoles(request)
    allowed_list = [
        r['course_id'].replace("course", "block") for r in roles['roles']
        if r['role'] in settings.BACKEND_ALLOWED_ROLES
    ]

    try:
        course, time__gte, time__lte = verify_time_range_course_params(request)
    except Exception as e:
        return Response(status=status.HTTP_400_BAD_REQUEST, data=str(e))

    # Check that user has permissions
    if course not in allowed_list:
        return Response(
            status=status.HTTP_403_FORBIDDEN,
            data=
            "No tiene permisos para ver los datos en los cursos solicitados")

    total_visits = VisitOnPage.objects.filter(
        vertical__is_active=True,
        vertical__course__icontains=course,
        time__lte=time__lte,
        time__gte=time__gte,
    )
    total_visits = total_visits.values("vertical__course").annotate(
        total=Sum("count"))
    if total_visits.count() != 0:
        total_visits = total_visits[0]['total']
    else:
        total_visits = 0

    total_users = VisitOnPage.objects.filter(
        vertical__is_active=True,
        vertical__course__icontains=course,
        time__lte=time__lte,
        time__gte=time__gte,
    ).values("username").distinct("username").count()

    return JsonResponse({
        'total_visits': total_visits,
        'total_users': total_users,
    })
示例#4
0
def manage_standard_request(request, query):
    roles = recoverUserCourseRoles(request)
    allowed_list = [r['course_id'].replace(
        "course", "block") for r in roles['roles'] if r['role'] in settings.BACKEND_ALLOWED_ROLES]

    try:
        course, time__gte, time__lte = verify_time_range_course_params(request)
    except Exception as e:
        return Response(status=status.HTTP_400_BAD_REQUEST, data=str(e))

    # Check that user has permissions
    if course not in allowed_list:
        return Response(status=status.HTTP_403_FORBIDDEN, data="No tiene permisos para ver los datos en los cursos solicitados")

    visits = query(course, time__lte, time__gte)
    if len(visits) == 0:
        return Response(status=status.HTTP_204_NO_CONTENT)
    return Response(visits)
示例#5
0
def get_course_structure(request):
    """
    Map a course structure using the recovered Verticals from the Edx API
    """
    roles = recoverUserCourseRoles(request)
    allowed_list = [r['course_id'].replace(
        "course", "block") for r in roles['roles'] if r['role'] in settings.BACKEND_ALLOWED_ROLES]

    if "search" not in request.query_params:
        return Response(status=status.HTTP_400_BAD_REQUEST, data="Search field required")
    # Look on course name and course code
    verticals = CourseVertical.objects.filter(
        Q(course_name__icontains=request.query_params["search"]) |
        Q(course__icontains=request.query_params["search"].replace("course-v1", "block-v1")))
    if len(verticals) == 0:
        return Response(status=status.HTTP_204_NO_CONTENT)

    courses = dict()
    # Gather unique keys
    for v in verticals:
        if v.course not in courses:
            # Correct course id name
            course_id = v.course.split("+type@")[0]
            courses[v.course] = dict(
                {"name": v.course_name, "course_id": course_id, "chapters": {}})
        chapter = courses[v.course]["chapters"]
        # Check that sections exists
        if v.chapter_number not in chapter:
            chapter[v.chapter_number] = dict(
                {"name": v.chapter_name, "id": v.chapter})
        if v.sequential_number not in chapter[v.chapter_number]:
            chapter[v.chapter_number][v.sequential_number] = dict(
                {"name": v.sequential_name})
        if v.vertical_number not in chapter[v.chapter_number][v.sequential_number]:
            chapter[v.chapter_number][v.sequential_number][v.vertical_number] = dict(
                {"name": v.vertical_name, "block_id": v.block_id, "block_type": v.block_type, "block_url": v.student_view_url, "vertical_id": v.vertical})
    # Parse keys as arrays
    courses_names = courses.keys()
    mapped_courses = []
    for course in courses_names:
        current_course = courses[course]
        # Remove courses that are not on the allowed list
        if current_course["course_id"] not in allowed_list:
            continue
        chapter_list = []
        chapter_indexes = [int(k) for k in current_course["chapters"].keys()]
        chapter_indexes.sort()
        for chapter in chapter_indexes:
            current_chapter = current_course["chapters"][chapter]
            sequential_list = []
            sequential_indexes = [
                int(k) for k in current_chapter.keys() if k != 'name' and k != 'id']
            sequential_indexes.sort()
            for seq in sequential_indexes:
                current_seq = current_chapter[seq]
                vertical_list = []
                vertical_indexes = [int(k)
                                    for k in current_seq.keys() if k != 'name']
                vertical_indexes.sort()
                for vert in vertical_indexes:
                    # Add vertical object
                    vertical_list.append(current_seq[vert])
                # Save sequential with verticals
                sequential_list.append(
                    {"name": current_seq["name"], "verticals": vertical_list})
            # Save chapter with sequentials
            chapter_list.append(
                {"name": current_chapter["name"], "sequentials": sequential_list, "id": current_chapter["id"]})
        mapped_courses.append(
            {"name": current_course["name"], "id": current_course["course_id"], "chapters": chapter_list})
    # If values where filtered then the user has no permissions
    if len(mapped_courses) == 0:
        return Response(status=status.HTTP_403_FORBIDDEN, data="No tiene permisos para ver los cursos solicitados")
    return Response({"courses": mapped_courses})
示例#6
0
def times_on_course(request):
    """
    Compact user time sessions for verticals

    Expects 3 query parameters
    - search: course id in course-block format
    - llimit (lower limit): a string datetime in isoformat 
    - rlimit (upper limit): a string datetime in isoformat
    both timestamps are included on the query.

    Timezone is added on runtime
    """
    roles = recoverUserCourseRoles(request)
    allowed_list = [
        r['course_id'].replace("course", "block") for r in roles['roles']
        if r['role'] in settings.BACKEND_ALLOWED_ROLES
    ]

    if "search" not in request.query_params:
        return Response(status=status.HTTP_400_BAD_REQUEST,
                        data="Search field required")

    if "llimit" not in request.query_params:
        return Response(status=status.HTTP_400_BAD_REQUEST,
                        data="Lower limit field required")

    if "ulimit" not in request.query_params:
        return Response(status=status.HTTP_400_BAD_REQUEST,
                        data="Upper limit field required")

    tz = pytz.timezone(settings.TIME_ZONE)
    try:
        llimit = tz.localize(
            datetime.fromisoformat(request.query_params["llimit"].replace(
                "Z", "")))
        ulimit = tz.localize(
            datetime.fromisoformat(request.query_params["ulimit"].replace(
                "Z", "")))
    except Exception as time_error:
        return Response(
            status=status.HTTP_400_BAD_REQUEST,
            data="Error while formating time limits. Expects isoformat.")

    if llimit > ulimit:
        return Response(status=status.HTTP_400_BAD_REQUEST,
                        data="lower limit does not preceed upper limit")

    # Check that user has permissions
    if request.query_params["search"] not in allowed_list:
        return Response(
            status=status.HTTP_403_FORBIDDEN,
            data=
            "No tiene permisos para ver los datos en los cursos solicitados")

    # Course will arrive in format block-v1:COURSE without +type@course-block@course
    # hence we do a icontains query
    times = TimeOnPage.objects.filter(
        course__icontains=request.query_params["search"],
        time__lte=ulimit,
        time__gte=llimit).values("username", "event_type_vertical").order_by(
            "username",
            "event_type_vertical").annotate(total=Sum("delta_time_float"))
    if len(times) == 0:
        return Response(status=status.HTTP_204_NO_CONTENT)
    return Response(times)