Example #1
0
def log_coach_report_view(request):
    """Record coach report view by teacher"""
    if "facility_user" in request.session:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update Teacher userlog activity login: %s" % e)
Example #2
0
def log_coach_report_view(request):
    """Record coach report view by teacher"""
    if "facility_user" in request.session:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update Teacher userlog activity login: %s" % e)
Example #3
0
def account_management(request):

    # Only log 'coachreport' activity for students,
    #   (otherwise it's hard to compare teachers)
    if "facility_user" in request.session and not request.session["facility_user"].is_teacher and reverse("login") not in request.META.get("HTTP_REFERER", ""):
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update student userlog activity: %s" % e)

    return student_view_context(request)
Example #4
0
def account_management(request):

    # Only log 'coachreport' activity for students,
    #   (otherwise it's hard to compare teachers)
    if "facility_user" in request.session and not request.session["facility_user"].is_teacher and reverse("login") not in request.META.get("HTTP_REFERER", ""):
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update student userlog activity: %s" % e)

    return student_view_context(request)
Example #5
0
def account_management(request):

    # Only log 'coachreport' activity for students,
    #   (otherwise it's hard to compare teachers)
    if "facility_user" in request.session and not request.session["facility_user"].is_teacher:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update student userlog activity: %s" % e)

    c = student_view_context(request)
    c["restricted"] = settings.DISABLE_SELF_ADMIN
    return c
Example #6
0
def account_management(request):

    # Only log 'coachreport' activity for students,
    #   (otherwise it's hard to compare teachers)
    if "facility_user" in request.session and not request.session["facility_user"].is_teacher:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update student userlog activity: %s" % e)

    c = student_view_context(request)
    c['restricted'] = settings.DISABLE_SELF_ADMIN
    return c
Example #7
0
def tabular_view(request, facility, report_type="exercise"):
    """Tabular view also gets data server-side."""
    # Define how students are ordered--used to be as efficient as possible.
    student_ordering = ["last_name", "first_name", "username"]

    # Get a list of topics (sorted) and groups
    topics = [get_node_cache("Topic").get(tid) for tid in get_knowledgemap_topics()]
    (groups, facilities) = get_accessible_objects_from_logged_in_user(request, facility=facility)
    context = plotting_metadata_context(request, facility=facility)
    context.update(
        {
            # For translators: the following two translations are nouns
            "report_types": (_("exercise"), _("video")),
            "request_report_type": report_type,
            "topics": [{"id": t[0]["id"], "title": t[0]["title"]} for t in topics if t],
        }
    )

    # get querystring info
    topic_id = request.GET.get("topic", "")
    # No valid data; just show generic
    if not topic_id or not re.match("^[\w\-]+$", topic_id):
        return context

    group_id = request.GET.get("group", "")
    if group_id:
        # Narrow by group
        users = FacilityUser.objects.filter(group=group_id, is_teacher=False).order_by(*student_ordering)

    elif facility:
        # Narrow by facility
        search_groups = [groups_dict["groups"] for groups_dict in groups if groups_dict["facility"] == facility.id]
        assert len(search_groups) <= 1, "Should only have one or zero matches."

        # Return groups and ungrouped
        search_groups = search_groups[0]  # make sure to include ungrouped students
        users = FacilityUser.objects.filter(
            Q(group__in=search_groups) | Q(group=None, facility=facility), is_teacher=False
        ).order_by(*student_ordering)

    else:
        # Show all (including ungrouped)
        for groups_dict in groups:
            search_groups += groups_dict["groups"]
        users = FacilityUser.objects.filter(Q(group__in=search_groups) | Q(group=None), is_teacher=False).order_by(
            *student_ordering
        )

    # We have enough data to render over a group of students
    # Get type-specific information
    if report_type == "exercise":
        # Fill in exercises
        exercises = get_topic_exercises(topic_id=topic_id)
        exercises = sorted(exercises, key=lambda e: (e["h_position"], e["v_position"]))
        context["exercises"] = exercises

        # More code, but much faster
        exercise_names = [ex["name"] for ex in context["exercises"]]
        # Get students
        context["students"] = []
        exlogs = (
            ExerciseLog.objects.filter(user__in=users, exercise_id__in=exercise_names)
            .order_by(*["user__%s" % field for field in student_ordering])
            .values("user__id", "struggling", "complete", "exercise_id")
        )
        exlogs = list(exlogs)  # force the query to be evaluated

        exlog_idx = 0
        for user in users:
            log_table = {}
            while exlog_idx < len(exlogs) and exlogs[exlog_idx]["user__id"] == user.id:
                log_table[exlogs[exlog_idx]["exercise_id"]] = exlogs[exlog_idx]
                exlog_idx += 1

            context["students"].append(
                {  # this could be DRYer
                    "first_name": user.first_name,
                    "last_name": user.last_name,
                    "username": user.username,
                    "name": user.get_name(),
                    "id": user.id,
                    "exercise_logs": log_table,
                }
            )

    elif report_type == "video":
        # Fill in videos
        context["videos"] = get_topic_videos(topic_id=topic_id)

        # More code, but much faster
        video_ids = [vid["id"] for vid in context["videos"]]
        # Get students
        context["students"] = []
        vidlogs = (
            VideoLog.objects.filter(user__in=users, video_id__in=video_ids)
            .order_by(*["user__%s" % field for field in student_ordering])
            .values("user__id", "complete", "video_id", "total_seconds_watched", "points")
        )
        vidlogs = list(vidlogs)  # force the query to be executed now

        vidlog_idx = 0
        for user in users:
            log_table = {}
            while vidlog_idx < len(vidlogs) and vidlogs[vidlog_idx]["user__id"] == user.id:
                log_table[vidlogs[vidlog_idx]["video_id"]] = vidlogs[vidlog_idx]
                vidlog_idx += 1

            context["students"].append(
                {  # this could be DRYer
                    "first_name": user.first_name,
                    "last_name": user.last_name,
                    "username": user.username,
                    "name": user.get_name(),
                    "id": user.id,
                    "video_logs": log_table,
                }
            )

    else:
        raise Http404(_("Unknown report_type: %(report_type)s") % {"report_type": report_type})

    if "facility_user" in request.session:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update Teacher userlog activity login: %s" % e)

    return context
Example #8
0
    def login(self, request, **kwargs):
        self.method_check(request, allowed=['post'])

        logout(request)

        data = self.deserialize(request,
                                request.body,
                                format=request.META.get(
                                    'CONTENT_TYPE', 'application/json'))

        username = data.get('username', '')
        password = data.get('password', '')
        facility = data.get('facility', '')

        # first try logging in as a Django user
        if not settings.CENTRAL_SERVER:
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)
                return self.create_response(
                    request, {
                        'success': True,
                        'redirect': reverse("zone_redirect")
                    })

        # Find all matching users
        users = FacilityUser.objects.filter(username=username,
                                            facility=facility)

        if users.count() == 0:
            if Facility.objects.count() > 1:
                error_message = _(
                    "Username and password do not match. Make sure you choose the right facility."
                )
            else:
                error_message = _("Username and password do not match.")
            return self.create_response(
                request, {
                    'messages': {
                        'error': error_message
                    },
                    'error_highlight': "password"
                }, HttpUnauthorized)

        for user in users:
            if settings.SIMPLIFIED_LOGIN and not user.is_teacher:
                # For simplified login, as long as it is a student account just take the first one!
                break
            # if we find a user whose password matches, stop looking
            if user.check_password(password):
                break
            else:
                user = None

        if not user:
            if Facility.objects.count() > 1:
                error_message = _(
                    "Username and password do not match. Make sure you choose the right facility."
                )
            else:
                error_message = _("Username and password do not match.")
            return self.create_response(
                request, {
                    'messages': {
                        'error': error_message
                    },
                    'error_highlight': "password"
                }, HttpUnauthorized)
        else:
            try:
                UserLog.begin_user_activity(
                    user,
                    activity_type="login",
                    language=lcode_to_django_lang(request.language)
                )  # Success! Log the event (ignoring validation failures)
            except ValidationError as e:
                logging.error("Failed to begin_user_activity upon login: %s" %
                              e)

            request.session["facility_user"] = user
            messages.success(
                request,
                _("You've been logged in! We hope you enjoy your time with KA Lite "
                  ) + _("-- be sure to log out when you finish."))

            extras = {'success': True}
            if user.is_teacher:
                extras.update({
                    "redirect":
                    reverse("coach_reports",
                            kwargs={
                                "zone_id":
                                getattr(Device.get_own_device().get_zone(),
                                        "id", "None")
                            })
                })
            return self.create_response(request, extras)
Example #9
0
def api_data(request, xaxis="", yaxis=""):
    """Request contains information about what data are requested (who, what, and how).

    Response should be a JSON object
    * data contains the data, structred by user and then datatype
    * the rest of the data is metadata, useful for displaying detailed info about data.
    """

    # Get the request form
    try:
        form = get_data_form(request, xaxis=xaxis, yaxis=yaxis)  # (data=request.REQUEST)
    except Exception as e:
        # In investigating #1509: we can catch SQL errors here and communicate clearer error
        #   messages with the user here.  For now, we have no such error to catch, so just
        #   pass the errors on to the user (via the @api_handle_error_with_json decorator).
        raise e

    # Query out the data: who?
    if form.data.get("user"):
        facility = []
        groups = []
        users = [get_object_or_404(FacilityUser, id=form.data.get("user"))]
    elif form.data.get("group"):
        facility = []
        groups = [get_object_or_404(FacilityGroup, id=form.data.get("group"))]
        users = FacilityUser.objects.filter(group=form.data.get("group"), is_teacher=False).order_by("last_name", "first_name")
    elif form.data.get("facility"):
        facility = get_object_or_404(Facility, id=form.data.get("facility"))
        groups = FacilityGroup.objects.filter(facility__in=[form.data.get("facility")])
        users = FacilityUser.objects.filter(facility__in=[form.data.get("facility")], is_teacher=False).order_by("last_name", "first_name")
    else:
        return HttpResponseNotFound(_("Did not specify facility, group, nor user."))

    # Query out the data: where?
    if not form.data.get("topic_path"):
        return HttpResponseNotFound(_("Must specify a topic path"))

    # Query out the data: what?
    computed_data = compute_data(data_types=[form.data.get("xaxis"), form.data.get("yaxis")], who=users, where=form.data.get("topic_path"))

    # Quickly add back in exercise meta-data (could potentially be used in future for other data too!)
    ex_nodes = get_node_cache()["Exercise"]
    exercises = []
    for e in computed_data["exercises"]:
        exercises.append({
            "slug": e,
            "full_name": ex_nodes[e][0]["display_name"],
            "url": ex_nodes[e][0]["path"],
        })  

    json_data = {
        "data": computed_data["data"],
        "exercises": exercises,
        "videos": computed_data["videos"],
        "users": dict(zip([u.id for u in users],
                          ["%s, %s" % (u.last_name, u.first_name) for u in users]
                     )),
        "groups": dict(zip([g.id for g in groups],
                           dict(zip(["id", "name"], [(g.id, g.name) for g in groups])),
                     )),
        "facility": None if not facility else {
            "name": facility.name,
            "id": facility.id,
        }
    }

    if "facility_user" in request.session:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update Teacher userlog activity login: %s" % e)

    # Now we have data, stream it back with a handler for date-times
    return JsonResponse(json_data)
Example #10
0
def tabular_view(request, facility, report_type="exercise"):
    """Tabular view also gets data server-side."""
    # Define how students are ordered--used to be as efficient as possible.
    student_ordering = ["last_name", "first_name", "username"]

    # Get a list of topics (sorted) and groups
    topics = [
        get_node_cache("Topic").get(tid) for tid in get_knowledgemap_topics()
    ]
    (groups, facilities) = get_accessible_objects_from_logged_in_user(
        request, facility=facility)
    context = plotting_metadata_context(request, facility=facility)
    context.update({
        # For translators: the following two translations are nouns
        "report_types": (_("exercise"), _("video")),
        "request_report_type":
        report_type,
        "topics": [{
            "id": t[0]["id"],
            "title": t[0]["title"]
        } for t in topics if t],
    })

    # get querystring info
    topic_id = request.GET.get("topic", "")
    # No valid data; just show generic
    if not topic_id or not re.match("^[\w\-]+$", topic_id):
        return context

    group_id = request.GET.get("group", "")
    if group_id:
        # Narrow by group
        users = FacilityUser.objects.filter(
            group=group_id, is_teacher=False).order_by(*student_ordering)

    elif facility:
        # Narrow by facility
        search_groups = [
            groups_dict["groups"] for groups_dict in groups
            if groups_dict["facility"] == facility.id
        ]
        assert len(search_groups) <= 1, "Should only have one or zero matches."

        # Return groups and ungrouped
        search_groups = search_groups[
            0]  # make sure to include ungrouped students
        users = FacilityUser.objects.filter(
            Q(group__in=search_groups) | Q(group=None, facility=facility),
            is_teacher=False).order_by(*student_ordering)

    else:
        # Show all (including ungrouped)
        for groups_dict in groups:
            search_groups += groups_dict["groups"]
        users = FacilityUser.objects.filter(
            Q(group__in=search_groups) | Q(group=None),
            is_teacher=False).order_by(*student_ordering)

    # We have enough data to render over a group of students
    # Get type-specific information
    if report_type == "exercise":
        # Fill in exercises
        exercises = get_topic_exercises(topic_id=topic_id)
        exercises = sorted(exercises,
                           key=lambda e: (e["h_position"], e["v_position"]))
        context["exercises"] = exercises

        # More code, but much faster
        exercise_names = [ex["name"] for ex in context["exercises"]]
        # Get students
        context["students"] = []
        exlogs = ExerciseLog.objects \
            .filter(user__in=users, exercise_id__in=exercise_names) \
            .order_by(*["user__%s" % field for field in student_ordering]) \
            .values("user__id", "struggling", "complete", "exercise_id")
        exlogs = list(exlogs)  # force the query to be evaluated

        exlog_idx = 0
        for user in users:
            log_table = {}
            while exlog_idx < len(
                    exlogs) and exlogs[exlog_idx]["user__id"] == user.id:
                log_table[exlogs[exlog_idx]["exercise_id"]] = exlogs[exlog_idx]
                exlog_idx += 1

            context["students"].append({  # this could be DRYer
                "first_name": user.first_name,
                "last_name": user.last_name,
                "username": user.username,
                "name": user.get_name(),
                "id": user.id,
                "exercise_logs": log_table,
            })

    elif report_type == "video":
        # Fill in videos
        context["videos"] = get_topic_videos(topic_id=topic_id)

        # More code, but much faster
        video_ids = [vid["id"] for vid in context["videos"]]
        # Get students
        context["students"] = []
        vidlogs = VideoLog.objects \
            .filter(user__in=users, video_id__in=video_ids) \
            .order_by(*["user__%s" % field for field in student_ordering])\
            .values("user__id", "complete", "video_id", "total_seconds_watched", "points")
        vidlogs = list(vidlogs)  # force the query to be executed now

        vidlog_idx = 0
        for user in users:
            log_table = {}
            while vidlog_idx < len(
                    vidlogs) and vidlogs[vidlog_idx]["user__id"] == user.id:
                log_table[vidlogs[vidlog_idx]
                          ["video_id"]] = vidlogs[vidlog_idx]
                vidlog_idx += 1

            context["students"].append({  # this could be DRYer
                "first_name": user.first_name,
                "last_name": user.last_name,
                "username": user.username,
                "name": user.get_name(),
                "id": user.id,
                "video_logs": log_table,
            })

    else:
        raise Http404(
            _("Unknown report_type: %(report_type)s") %
            {"report_type": report_type})

    if "facility_user" in request.session:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(
                user, activity_type="login"
            )  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error(
                "Failed to update Teacher userlog activity login: %s" % e)

    return context
Example #11
0
def login(request, facility):
    facility_id = (facility and facility.id) or None
    facilities = list(Facility.objects.all())

    #Fix for #2047: prompt user to create an admin account if none exists
    if not User.objects.exists():
        messages.warning(request, _("No administrator account detected. Please run 'python manage.py createsuperuser' from the terminal to create one."))

    # Fix for #1211: refresh cached facility info when it's free and relevant
    refresh_session_facility_info(request, facility_count=len(facilities))

    if request.method != 'POST':  # render the unbound login form
        referer = urlparse.urlparse(request.META["HTTP_REFERER"]).path if request.META.get("HTTP_REFERER") else None
        # never use the homepage as the referer
        if referer in [reverse("homepage"), reverse("add_facility_student")]:
            referer = None
        form = LoginForm(initial={"facility": facility_id, "callback_url": referer})

    else:  # process the login form
        # log out any Django user or facility user
        logout(request)

        username = request.POST.get("username", "")
        password = request.POST.get("password", "")

        # first try logging in as a Django user
        if not settings.CENTRAL_SERVER:
            user = authenticate(username=username, password=password)
            if user:
                auth_login(request, user)
                return HttpResponseRedirect(request.next or reverse("zone_redirect"))

        # try logging in as a facility user
        form = LoginForm(data=request.POST, request=request, initial={"facility": facility_id})
        if not form.is_valid():
            messages.error(
                request,
                _("There was an error logging you in. Please correct any errors listed below, and try again."),
            )

        else:
            user = form.get_user()

            try:
                UserLog.begin_user_activity(user, activity_type="login", language=request.language)  # Success! Log the event (ignoring validation failures)
            except ValidationError as e:
                logging.error("Failed to begin_user_activity upon login: %s" % e)

            request.session["facility_user"] = user
            messages.success(request, _("You've been logged in! We hope you enjoy your time with KA Lite ") +
                                        _("-- be sure to log out when you finish."))

            # Send them back from whence they came
            landing_page = form.cleaned_data["callback_url"]
            if not landing_page:
                # Just going back to the homepage?  We can do better than that.
                landing_page = reverse("coach_reports") if form.get_user().is_teacher else None
                landing_page = landing_page or (reverse("account_management") if False else reverse("homepage"))  # TODO: pass the redirect as a parameter.

            return HttpResponseRedirect(form.non_field_errors() or request.next or landing_page)

    return {
        "form": form,
        "facilities": facilities,
        "sign_up_url": reverse("add_facility_student"),
    }
Example #12
0
    def login(self, request, **kwargs):
        self.method_check(request, allowed=['post'])

        logout(request)

        data = self.deserialize(request, request.body, format=request.META.get('CONTENT_TYPE', 'application/json'))

        username = data.get('username', '')
        password = data.get('password', '')
        facility = data.get('facility', '')

        # first try logging in as a Django user
        if not settings.CENTRAL_SERVER:
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)
                return self.create_response(request, {
                    'success': True,
                    'redirect': reverse("zone_redirect")
                    })

        # Find all matching users
        users = FacilityUser.objects.filter(username=username, facility=facility)

        if users.count() == 0:
            if Facility.objects.count() > 1:
                error_message = _("Username and password do not match. Make sure you choose the right facility.")
            else:
                error_message = _("Username and password do not match.")
            return self.create_response(request, {
                'messages': {'error': error_message},
                'error_highlight': "password"
                }, HttpUnauthorized )

        for user in users:
            if settings.SIMPLIFIED_LOGIN and not user.is_teacher:
                # For simplified login, as long as it is a student account just take the first one!
                break
            # if we find a user whose password matches, stop looking
            if user.check_password(password):
                break
            else:
                user = None

        if not user:
            if Facility.objects.count() > 1:
                error_message = _("Username and password do not match. Make sure you choose the right facility.")
            else:
                error_message = _("Username and password do not match.")
            return self.create_response(request, {
                'messages': {'error': error_message},
                'error_highlight': "password"
                }, HttpUnauthorized )
        else:
            try:
                UserLog.begin_user_activity(user, activity_type="login", language=lcode_to_django_lang(request.language))  # Success! Log the event (ignoring validation failures)
            except ValidationError as e:
                logging.error("Failed to begin_user_activity upon login: %s" % e)

            request.session["facility_user"] = user
            messages.success(request, _("You've been logged in! We hope you enjoy your time with KA Lite ")
                + _("-- be sure to log out when you finish."))

            extras = {'success': True}
            if user.is_teacher:
                extras.update({
                    "redirect": reverse("coach_reports", kwargs={"zone_id": getattr(Device.get_own_device().get_zone(), "id", "None")})
                })
            return self.create_response(request, extras)
Example #13
0
def login(request, facility):
    facility_id = (facility and facility.id) or None
    facilities = list(Facility.objects.all())

    # Fix for #1211: refresh cached facility info when it's free and relevant
    refresh_session_facility_info(request, facility_count=len(facilities))

    if request.method != 'POST':  # render the unbound login form
        referer = urlparse.urlparse(
            request.META["HTTP_REFERER"]).path if request.META.get(
                "HTTP_REFERER") else None
        # never use the homepage as the referer
        if referer in [reverse("homepage"), reverse("add_facility_student")]:
            referer = None
        form = LoginForm(initial={
            "facility": facility_id,
            "callback_url": referer
        })

    else:  # process the login form
        # log out any Django user or facility user
        logout(request)

        username = request.POST.get("username", "")
        password = request.POST.get("password", "")

        # first try logging in as a Django user
        if not settings.CENTRAL_SERVER:
            user = authenticate(username=username, password=password)
            if user:
                auth_login(request, user)
                return HttpResponseRedirect(request.next
                                            or reverse("zone_redirect"))

        # try logging in as a facility user
        form = LoginForm(data=request.POST,
                         request=request,
                         initial={"facility": facility_id})
        if not form.is_valid():
            messages.error(
                request,
                _("There was an error logging you in. Please correct any errors listed below, and try again."
                  ),
            )

        else:
            user = form.get_user()

            try:
                UserLog.begin_user_activity(
                    user, activity_type="login", language=request.language
                )  # Success! Log the event (ignoring validation failures)
            except ValidationError as e:
                logging.error("Failed to begin_user_activity upon login: %s" %
                              e)

            request.session["facility_user"] = user
            messages.success(
                request,
                _("You've been logged in! We hope you enjoy your time with KA Lite "
                  ) + _("-- be sure to log out when you finish."))

            # Send them back from whence they came
            landing_page = form.cleaned_data["callback_url"]
            if not landing_page:
                # Just going back to the homepage?  We can do better than that.
                landing_page = reverse(
                    "coach_reports") if form.get_user().is_teacher else None
                landing_page = landing_page or (
                    reverse("account_management")
                    if False else reverse("homepage")
                )  # TODO: pass the redirect as a parameter.

            return HttpResponseRedirect(form.non_field_errors() or request.next
                                        or landing_page)

    return {
        "form": form,
        "facilities": facilities,
        "sign_up_url": reverse("add_facility_student"),
    }
Example #14
0
def api_data(request, xaxis="", yaxis=""):
    """Request contains information about what data are requested (who, what, and how).

    Response should be a JSON object
    * data contains the data, structred by user and then datatype
    * the rest of the data is metadata, useful for displaying detailed info about data.
    """

    # Get the request form
    try:
        form = get_data_form(request, xaxis=xaxis, yaxis=yaxis)  # (data=request.REQUEST)
    except Exception as e:
        # In investigating #1509: we can catch SQL errors here and communicate clearer error
        #   messages with the user here.  For now, we have no such error to catch, so just
        #   pass the errors on to the user (via the @api_handle_error_with_json decorator).
        raise e

    # Query out the data: who?
    if form.data.get("user"):
        facility = []
        groups = []
        users = [get_object_or_404(FacilityUser, id=form.data.get("user"))]
    elif form.data.get("group"):
        facility = []
        groups = [get_object_or_404(FacilityGroup, id=form.data.get("group"))]
        users = FacilityUser.objects.filter(group=form.data.get("group"), is_teacher=False).order_by("last_name", "first_name")
    elif form.data.get("facility"):
        facility = get_object_or_404(Facility, id=form.data.get("facility"))
        groups = FacilityGroup.objects.filter(facility__in=[form.data.get("facility")])
        users = FacilityUser.objects.filter(facility__in=[form.data.get("facility")], is_teacher=False).order_by("last_name", "first_name")
    else:
        return HttpResponseNotFound(_("Did not specify facility, group, nor user."))

    # Query out the data: where?
    if not form.data.get("topic_path"):
        return HttpResponseNotFound(_("Must specify a topic path"))

    # Query out the data: what?
    computed_data = compute_data(data_types=[form.data.get("xaxis"), form.data.get("yaxis")], who=users, where=form.data.get("topic_path"))

    # Quickly add back in exercise meta-data (could potentially be used in future for other data too!)
    ex_nodes = get_node_cache()["Exercise"]
    exercises = []
    for e in computed_data["exercises"]:
        exercises.append({
            "slug": e,
            "full_name": ex_nodes[e][0]["display_name"],
            "url": ex_nodes[e][0]["path"],
        })

    json_data = {
        "data": computed_data["data"],
        "exercises": exercises,
        "videos": computed_data["videos"],
        "users": dict(zip([u.id for u in users],
                          ["%s, %s" % (u.last_name, u.first_name) for u in users]
                     )),
        "groups": dict(zip([g.id for g in groups],
                           dict(zip(["id", "name"], [(g.id, g.name) for g in groups])),
                     )),
        "facility": None if not facility else {
            "name": facility.name,
            "id": facility.id,
        }
    }

    if "facility_user" in request.session:
        try:
            # Log a "begin" and end here
            user = request.session["facility_user"]
            UserLog.begin_user_activity(user, activity_type="coachreport")
            UserLog.update_user_activity(user, activity_type="login")  # to track active login time for teachers
            UserLog.end_user_activity(user, activity_type="coachreport")
        except ValidationError as e:
            # Never report this error; don't want this logging to block other functionality.
            logging.error("Failed to update Teacher userlog activity login: %s" % e)

    # Now we have data, stream it back with a handler for date-times
    return JsonResponse(json_data)