Beispiel #1
0
    def page(self, course, username):
        """ Get all data and display the page """
        data = list(self.database.user_tasks.find({"username": username, "courseid": course.get_id()}))

        tasks = course.get_tasks()
        result = dict([(taskid, {"taskid": taskid, "name": tasks[taskid].get_name(self.user_manager.session_language()),
                                 "tried": 0, "status": "notviewed", "grade": 0,
                                 "url": self.submission_url_generator(username, taskid)}) for taskid in tasks])

        for taskdata in data:
            if taskdata["taskid"] in result:
                result[taskdata["taskid"]]["tried"] = taskdata["tried"]
                if taskdata["tried"] == 0:
                    result[taskdata["taskid"]]["status"] = "notattempted"
                elif taskdata["succeeded"]:
                    result[taskdata["taskid"]]["status"] = "succeeded"
                else:
                    result[taskdata["taskid"]]["status"] = "failed"
                result[taskdata["taskid"]]["grade"] = taskdata["grade"]
                result[taskdata["taskid"]]["submissionid"] = str(taskdata["submissionid"])

        if "csv" in web.input():
            return make_csv(result)

        results = sorted(list(result.values()), key=lambda result: (tasks[result["taskid"]].get_order(), result["taskid"]))
        return self.template_helper.get_renderer().course_admin.student_info(course, username, results)
Beispiel #2
0
    def page(self, course):
        """ Get all data and display the page """
        data = list(self.database.user_tasks.aggregate(
            [
                {
                    "$match":
                        {
                            "courseid": course.get_id(),
                            "username": {"$in": self.user_manager.get_course_registered_users(course, False)}
                        }
                },
                {
                    "$group":
                        {
                            "_id": "$taskid",
                            "viewed": {"$sum": 1},
                            "attempted": {"$sum": {"$cond": [{"$ne": ["$tried", 0]}, 1, 0]}},
                            "attempts": {"$sum": "$tried"},
                            "succeeded": {"$sum": {"$cond": ["$succeeded", 1, 0]}}
                        }
                }
            ]))

        # Load tasks and verify exceptions
        files = self.task_factory.get_readable_tasks(course)
        output = {}
        errors = []
        for task in files:
            try:
                output[task] = course.get_task(task)
            except Exception as inst:
                errors.append({"taskid": task, "error": str(inst)})
        tasks = OrderedDict(sorted(list(output.items()), key=lambda t: (t[1].get_order(), t[1].get_id())))

        # Now load additional informations
        result = OrderedDict()
        for taskid in tasks:
            result[taskid] = {"name": tasks[taskid].get_name(self.user_manager.session_language()), "viewed": 0, "attempted": 0, "attempts": 0, "succeeded": 0,
                              "url": self.submission_url_generator(taskid)}
        for entry in data:
            if entry["_id"] in result:
                result[entry["_id"]]["viewed"] = entry["viewed"]
                result[entry["_id"]]["attempted"] = entry["attempted"]
                result[entry["_id"]]["attempts"] = entry["attempts"]
                result[entry["_id"]]["succeeded"] = entry["succeeded"]
        if "csv" in web.input():
            return make_csv(result)
        return self.template_helper.get_renderer().course_admin.task_list(course, result, errors)
Beispiel #3
0
    def page(self, course, msg="", error=False):
        """ Get all data and display the page """
        aggregations = OrderedDict()
        taskids = list(course.get_tasks().keys())

        for aggregation in self.user_manager.get_course_aggregations(course):
            aggregations[aggregation['_id']] = dict(list(aggregation.items()) +
                                                [("tried", 0),
                                                 ("done", 0),
                                                 ("url", self.submission_url_generator(aggregation['_id']))
                                                 ])

            data = list(self.database.submissions.aggregate(
                [
                    {
                        "$match":
                            {
                                "courseid": course.get_id(),
                                "taskid": {"$in": taskids},
                                "username": {"$in": aggregation["students"]}
                            }
                    },
                    {
                        "$group":
                            {
                                "_id": "$taskid",
                                "tried": {"$sum": 1},
                                "done": {"$sum": {"$cond": [{"$eq": ["$result", "success"]}, 1, 0]}}
                            }
                    },

                ]))

            for c in data:
                aggregations[aggregation['_id']]["tried"] += 1 if c["tried"] else 0
                aggregations[aggregation['_id']]["done"] += 1 if c["done"] else 0

        my_aggregations, other_aggregations = [], []
        for aggregation in aggregations.values():
            if self.user_manager.session_username() in aggregation["tutors"]:
                my_aggregations.append(aggregation)
            else:
                other_aggregations.append(aggregation)

        if "csv" in web.input():
            return make_csv(data)

        return self.template_helper.get_renderer().course_admin.aggregation_list(course, [my_aggregations, other_aggregations], msg, error)
Beispiel #4
0
    def page(self, course, aggregationid):
        """ Get all data and display the page """
        aggregation = self.database.aggregations.find_one({"_id": ObjectId(aggregationid)})

        data = list(self.database.submissions.aggregate(
            [
                {
                    "$match":
                        {
                            "courseid": course.get_id(),
                            "username": {"$in": aggregation["students"]}
                        }
                },
                {
                    "$group":
                        {
                            "_id": "$taskid",
                            "tried": {"$sum": 1},
                            "succeeded": {"$sum": {"$cond": [{"$eq": ["$result", "success"]}, 1, 0]}},
                            "grade": {"$max": "$grade"}
                        }
                }
            ]))

        tasks = course.get_tasks()
        result = dict([(taskid, {"taskid": taskid, "name": tasks[taskid].get_name(self.user_manager.session_language()), "tried": 0, "status": "notviewed",
                                 "grade": 0, "url": self.submission_url_generator(aggregationid, taskid)}) for taskid in tasks])

        for taskdata in data:
            if taskdata["_id"] in result:
                result[taskdata["_id"]]["tried"] = taskdata["tried"]
                if taskdata["tried"] == 0:
                    result[taskdata["_id"]]["status"] = "notattempted"
                elif taskdata["succeeded"]:
                    result[taskdata["_id"]]["status"] = "succeeded"
                else:
                    result[taskdata["_id"]]["status"] = "failed"
                result[taskdata["_id"]]["grade"] = taskdata["grade"]

        if "csv" in web.input():
            return make_csv(result)

        results = sorted(list(result.values()), key=lambda result: (tasks[result["taskid"]].get_order(), result["taskid"]))
        return self.template_helper.get_renderer().course_admin.aggregation_info(course, aggregation, results)
Beispiel #5
0
    def page(self, course, msgs=None):
        """ Get all data and display the page """
        msgs = msgs if msgs else []
        
        user_input = self.get_input()
        data, classroom = self.get_submissions(course, user_input)  # ONLY classrooms user wants to query
        if len(data) == 0 and not self.show_collapse(user_input):
            msgs.append(_("No submissions found"))

        classrooms = self.user_manager.get_course_aggregations(course)  # ALL classrooms of the course
        users = self.get_users(course)  # All users of the course
        tasks = course.get_tasks()  # All tasks of the course

        statistics = None
        if user_input.stat != "no_stat":
            statistics = compute_statistics(tasks, data, True if "with_pond_stat" == user_input.stat else False)

        if "csv" in web.input():
            return make_csv(data)
                        
        if "download" in web.input():
            # self._logger.info("Downloading %d submissions from course %s", len(data), course.get_id())
            web.header('Content-Type', 'application/x-gzip', unique=True)
            web.header('Content-Disposition', 'attachment; filename="submissions.tgz"', unique=True)

            # Tweak if not using classrooms : classroom['students'] may content ungrouped users
            aggregations = dict([(username,
                                  aggregation if course.use_classrooms() or (
                                  username in aggregation['groups'][0]["students"]) else None
                                  ) for aggregation in classroom for username in aggregation["students"]])

            download_type = web.input(download_type=self._valid_formats[0]).download_type
            if download_type not in self._valid_formats:
                download_type = self._valid_formats[0]
            return self.submission_manager.get_submission_archive(data, list(reversed(download_type.split('/'))), aggregations)

        if user_input.limit != '' and user_input.limit.isdigit():
            data = data[:int(user_input.limit)]
            
        if len(data) > self._trunc_limit:
            msgs.append(_("The result contains more than {0} submissions. The displayed submissions are truncated.\n").format(self._trunc_limit))
            data = data[:self._trunc_limit]
        return self.template_helper.get_renderer().course_admin.submissions(course, tasks, users, classrooms, data, statistics, user_input, self._allowed_sort, self._allowed_sort_name, self._valid_formats, msgs, self.show_collapse(user_input))
Beispiel #6
0
    def page(self, course, msgs=None):
        """ Get all data and display the page """
        msgs = msgs if msgs else []

        user_input = self.get_input()
        # Retrieve submissions data required for display the table
        fields_for_table = [
            "username", "best", "result", "submitted_on", "grade", "status",
            "taskid"
        ]
        data_table, classroom = self.get_submissions(course, user_input,
                                                     fields_for_table)
        if len(data_table) == 0 and not self.show_collapse(user_input):
            msgs.append(_("No submissions found"))

        classrooms = self.user_manager.get_course_aggregations(
            course)  # ALL classrooms of the course
        users = self.get_users(course)  # All users of the course
        tasks = course.get_tasks()  # All tasks of the course

        statistics = None
        if user_input.stat != "no_stat":
            # Retrieve submissions data required for display stats
            fields_for_stats = [
                "taskid", "username", "tests", "best", "result"
            ]
            data_stats, classroom = self.get_submissions(
                course, user_input, fields_for_stats)
            statistics = compute_statistics(
                tasks, data_stats,
                True if "with_pond_stat" == user_input.stat else False)

        #Get csv with all the submissions info in the query
        if "csv" in web.input():
            #We get the all info of that submissions
            data, classroom = self.get_submissions(course, user_input)
            return make_csv(data)

        #Download all the submissions in the query
        if "download" in web.input():
            #We get the all info of that submissions
            data, classroom = self.get_submissions(course, user_input)
            # self._logger.info("Downloading %d submissions from course %s", len(data), course.get_id())
            web.header('Content-Type', 'application/x-gzip', unique=True)
            web.header('Content-Disposition',
                       'attachment; filename="submissions.tgz"',
                       unique=True)

            # Tweak if not using classrooms : classroom['students'] may content ungrouped users
            aggregations = dict([
                (username, aggregation if course.use_classrooms() or
                 (username in aggregation['groups'][0]["students"]) else None)
                for aggregation in classroom
                for username in aggregation["students"]
            ])

            download_type = web.input(
                download_type=self._valid_formats[0]).download_type
            if download_type not in self._valid_formats:
                download_type = self._valid_formats[0]
            return self.submission_manager.get_submission_archive(
                data, list(reversed(download_type.split('/'))), aggregations)

        if user_input.limit != '' and user_input.limit.isdigit():
            data_table = data_table[:int(user_input.limit)]

        if len(data_table) > self._trunc_limit:
            msgs.append(
                _("The result contains more than ") +
                "{0}".format(self._trunc_limit) +
                _(" submissions. The displayed submissions are truncated.\n"))
            data_table = data_table[:self._trunc_limit]
        return self.template_helper.get_renderer().course_admin.submissions(
            course, tasks, users, classrooms, data_table, statistics,
            user_input, self._allowed_sort, self._allowed_sort_name,
            self._valid_formats, msgs, self.show_collapse(user_input))
Beispiel #7
0
    def page(self, course, task):
        """ Get all data and display the page """
        user_list = self.user_manager.get_course_registered_users(course, False)
        users = OrderedDict(sorted(list(self.user_manager.get_users_info(user_list).items()),
                                   key=lambda k: k[1][0] if k[1] is not None else ""))

        individual_results = list(self.database.user_tasks.find({"courseid": course.get_id(), "taskid": task.get_id(),
                                                                 "username": {"$in": user_list}}))

        individual_data = OrderedDict([(username, {"username": username, "realname": user[0] if user is not None else "",
                                                   "email": user[1] if user is not None else "",
                                                   "url": self.individual_submission_url_generator(task, username),
                                                   "tried": 0, "grade": 0, "status": "notviewed"})
                                       for username, user in users.items()])

        for user in individual_results:
            individual_data[user["username"]]["tried"] = user["tried"]
            if user["tried"] == 0:
                individual_data[user["username"]]["status"] = "notattempted"
            elif user["succeeded"]:
                individual_data[user["username"]]["status"] = "succeeded"
            else:
                individual_data[user["username"]]["status"] = "failed"
            individual_data[user["username"]]["grade"] = user["grade"]

        aggregation_data = OrderedDict()
        for aggregation in self.user_manager.get_course_aggregations(course):
            aggregation_data[aggregation['_id']] = {"_id": aggregation['_id'], "description": aggregation['description'],
                                                "url": self.aggregation_submission_url_generator(task, aggregation),
                                                "tried": 0, "grade": 0, "status": "notviewed",
                                                "tutors": aggregation["tutors"], "groups": aggregation["groups"]}

            aggregation_results = list(self.database.submissions.aggregate(
                [
                    {
                        "$match":
                            {
                                "courseid": course.get_id(),
                                "taskid": task.get_id(),
                                "username": {"$in": aggregation["students"]}
                            }
                    },
                    {
                        "$group":
                            {
                                "_id": "$taskid",
                                "tried": {"$sum": 1},
                                "succeeded": {"$sum": {"$cond": [{"$eq": ["$result", "success"]}, 1, 0]}},
                                "grade": {"$max": "$grade"}
                            }
                    }
                ]))

            for g in aggregation_results:
                aggregation_data[aggregation['_id']]["tried"] = g["tried"]
                if g["tried"] == 0:
                    aggregation_data[aggregation['_id']]["status"] = "notattempted"
                elif g["succeeded"]:
                    aggregation_data[aggregation['_id']]["status"] = "succeeded"
                else:
                    aggregation_data[aggregation['_id']]["status"] = "failed"
                aggregation_data[aggregation['_id']]["grade"] = g["grade"]

        my_aggregations, other_aggregations = [], []
        for aggregation in aggregation_data.values():
            if self.user_manager.session_username() in aggregation["tutors"]:
                my_aggregations.append(aggregation)
            else:
                other_aggregations.append(aggregation)

        if "csv" in web.input() and web.input()["csv"] == "students":
            return make_csv(list(individual_data.values()))
        elif "csv" in web.input() and web.input()["csv"] == "aggregations":
            return make_csv(list(aggregation_data.values()))

        return self.template_helper.get_renderer().course_admin.task_info(course, task, individual_data.values(), [my_aggregations, other_aggregations])
Beispiel #8
0
    def page(self, course, msg="", error=False):
        """ Get all data and display the page """
        aggregations = OrderedDict()
        taskids = list(course.get_tasks().keys())

        for aggregation in self.user_manager.get_course_aggregations(course):
            aggregations[aggregation['_id']] = dict(
                list(aggregation.items()) +
                [("tried", 0), ("done", 0),
                 ("url", self.submission_url_generator(aggregation['_id']))])

            data = list(
                self.database.submissions.aggregate([
                    {
                        "$match": {
                            "courseid": course.get_id(),
                            "taskid": {
                                "$in": taskids
                            },
                            "username": {
                                "$in": aggregation["students"]
                            }
                        }
                    },
                    {
                        "$group": {
                            "_id": "$taskid",
                            "tried": {
                                "$sum": 1
                            },
                            "done": {
                                "$sum": {
                                    "$cond": [{
                                        "$eq": ["$result", "success"]
                                    }, 1, 0]
                                }
                            }
                        }
                    },
                ]))

            for c in data:
                aggregations[
                    aggregation['_id']]["tried"] += 1 if c["tried"] else 0
                aggregations[
                    aggregation['_id']]["done"] += 1 if c["done"] else 0

        my_aggregations, other_aggregations = [], []
        for aggregation in aggregations.values():
            if self.user_manager.session_username() in aggregation["tutors"]:
                my_aggregations.append(aggregation)
            else:
                other_aggregations.append(aggregation)

        if "csv" in web.input():
            return make_csv(data)

        return self.template_helper.get_renderer(
        ).course_admin.aggregation_list(course,
                                        [my_aggregations, other_aggregations],
                                        msg, error)
Beispiel #9
0
    def page(self, course, msgs=None):
        """ Get all data and display the page """
        msgs = msgs if msgs else []

        user_input = self.get_input()
        data, audience = self.get_submissions(
            course, user_input)  # ONLY audiences user wants to query
        if len(data) == 0 and not self.show_collapse(user_input):
            msgs.append(_("No submissions found"))

        course_audiences = self.user_manager.get_course_audiences(
            course)  # ALL audiences of the course
        audiences_id = [audience["_id"] for audience in course_audiences]
        audiences_list = list(
            self.database.audiences.aggregate([{
                "$match": {
                    "_id": {
                        "$in": audiences_id
                    }
                }
            }, {
                "$unwind": "$students"
            }, {
                "$project": {
                    "audience": "$_id",
                    "students": 1
                }
            }]))
        audiences = {
            audience["_id"]: audience
            for audience in course_audiences
        }
        audiences = {
            d["students"]: audiences[d["audience"]]
            for d in audiences_list
        }

        users = self.get_users(course)  # All users of the course
        tasks = course.get_tasks()  # All tasks of the course

        statistics = None
        if user_input.stat != "no_stat":
            statistics = compute_statistics(
                tasks, data,
                True if "with_pond_stat" == user_input.stat else False)

        if "csv" in web.input():
            return make_csv(data)

        if "download" in web.input():
            download_type = web.input(
                download_type=self._valid_formats[0]).download_type
            if download_type not in self._valid_formats:
                download_type = self._valid_formats[0]

            archive, error = self.submission_manager.get_submission_archive(
                data, list(reversed(download_type.split('/'))), audiences)
            if not error:
                # self._logger.info("Downloading %d submissions from course %s", len(data), course.get_id())
                web.header('Content-Type', 'application/x-gzip', unique=True)
                web.header('Content-Disposition',
                           'attachment; filename="submissions.tgz"',
                           unique=True)
                return archive
            else:
                msgs.append(
                    _("The following submission could not be prepared for download: {}"
                      ).format(error))

        if user_input.limit != '' and user_input.limit.isdigit():
            data = data[:int(user_input.limit)]

        if len(data) > self._trunc_limit:
            msgs.append(
                _("The result contains more than {0} submissions. The displayed submissions are truncated.\n"
                  ).format(self._trunc_limit))
            data = data[:self._trunc_limit]
        return self.template_helper.get_renderer().course_admin.submissions(
            course, tasks, users, course_audiences, data, statistics,
            user_input, self._allowed_sort, self._allowed_sort_name,
            self._valid_formats, msgs, self.show_collapse(user_input))
Beispiel #10
0
    def POST_AUTH(self, courseid):  # pylint: disable=arguments-differ
        """ POST request """
        course, __ = self.get_course_and_check_rights(courseid)
        msgs = []

        user_input = web.input(users=[], audiences=[], tasks=[], org_tags=[])

        if "replay_submission" in user_input:
            # Replay a unique submission
            submission = self.database.submissions.find_one(
                {"_id": ObjectId(user_input["replay_submission"])})
            if submission is None:
                raise web.notfound()

            web.header('Content-Type', 'application/json')
            self.submission_manager.replay_job(
                course.get_task(submission["taskid"]), submission)
            return json.dumps({"status": "waiting"})

        elif "csv" in user_input or "download" in user_input or "replay" in user_input:
            best_only = "eval_dl" in user_input and "download" in user_input
            params = self.get_input_params(
                json.loads(user_input.get("displayed_selection", "")), course)
            data = self.submissions_from_user_input(course,
                                                    params,
                                                    msgs,
                                                    best_only=best_only)

            if "csv" in user_input:
                return make_csv(data)

            elif "download" in user_input:
                download_type = user_input.get("download_type", "")
                if download_type not in [
                        "taskid/username", "taskid/audience",
                        "username/taskid", "audience/taskid"
                ]:
                    download_type = "taskid/username"
                if (best_only
                        or "eval" in params) and "simplify" in user_input:
                    sub_folders = list(download_type.split('/'))
                else:
                    sub_folders = list(
                        download_type.split('/')) + ["submissiondateid"]
                archive, error = self.submission_manager.get_submission_archive(
                    course,
                    data,
                    sub_folders,
                    simplify="simplify" in user_input)
                if not error:
                    # self._logger.info("Downloading %d submissions from course %s", len(data), course.get_id())
                    web.header('Content-Type',
                               'application/x-gzip',
                               unique=True)
                    web.header('Content-Disposition',
                               'attachment; filename="submissions.tgz"',
                               unique=True)
                    return archive
                else:
                    msgs.append(
                        _("The following submission could not be prepared for download: {}"
                          ).format(error))
                    return self.page(course, params, msgs=msgs)

            elif "replay" in user_input:
                if not self.user_manager.has_admin_rights_on_course(course):
                    raise web.notfound()

                tasks = course.get_tasks()
                for submission in data:
                    self.submission_manager.replay_job(
                        tasks[submission["taskid"]], submission)
                msgs.append(
                    _("{0} selected submissions were set for replay.").format(
                        str(len(data))))
                return self.page(course, params, msgs=msgs)

        elif "page" in user_input:
            params = self.get_input_params(
                json.loads(user_input["displayed_selection"]), course)
            try:
                page = int(user_input["page"])
            except TypeError:
                page = 1
            return self.page(course, params, page=page, msgs=msgs)
        else:
            params = self.get_input_params(user_input, course)
            return self.page(course, params, msgs=msgs)
Beispiel #11
0
    def POST_AUTH(self, courseid):  # pylint: disable=arguments-differ
        """ POST request """
        course, __ = self.get_course_and_check_rights(courseid)
        msgs = []

        user_input = flask.request.form.copy()
        user_input["users"] = flask.request.form.getlist("users")
        user_input["audiences"] = flask.request.form.getlist("audiences")
        user_input["tasks"] = flask.request.form.getlist("tasks")
        user_input["org_tags"] = flask.request.form.getlist("org_tasks")

        if "replay_submission" in user_input:
            # Replay a unique submission
            submission = self.database.submissions.find_one(
                {"_id": ObjectId(user_input["replay_submission"])})
            if submission is None:
                raise NotFound(description=_("This submission doesn't exist."))

            self.submission_manager.replay_job(
                course.get_task(submission["taskid"]), submission)
            return Response(response=json.dumps({"status": "waiting"}),
                            content_type='application/json')

        elif "csv" in user_input or "download" in user_input or "replay" in user_input:
            best_only = "eval_dl" in user_input and "download" in user_input
            params = self.get_input_params(
                json.loads(user_input.get("displayed_selection", "")), course)
            data = self.submissions_from_user_input(course,
                                                    params,
                                                    msgs,
                                                    best_only=best_only)

            if "csv" in user_input:
                return make_csv(data)

            elif "download" in user_input:
                download_type = user_input.get("download_type", "")
                if download_type not in [
                        "taskid/username", "taskid/audience",
                        "username/taskid", "audience/taskid"
                ]:
                    download_type = "taskid/username"
                if (best_only
                        or "eval" in params) and "simplify" in user_input:
                    sub_folders = list(download_type.split('/'))
                else:
                    sub_folders = list(
                        download_type.split('/')) + ["submissiondateid"]
                archive, error = self.submission_manager.get_submission_archive(
                    course,
                    data,
                    sub_folders,
                    simplify="simplify" in user_input)
                if not error:
                    response = Response(response=archive,
                                        content_type='application/x-gzip')
                    response.headers[
                        'Content-Disposition'] = 'attachment; filename="submissions.tgz"'
                    return response
                else:
                    msgs.append(
                        _("The following submission could not be prepared for download: {}"
                          ).format(error))
                    return self.page(course, params, msgs=msgs)

            elif "replay" in user_input:
                if not self.user_manager.has_admin_rights_on_course(course):
                    raise Forbidden(description=_(
                        "You don't have admin rights on this course."))

                tasks = course.get_tasks()
                for submission in data:
                    self.submission_manager.replay_job(
                        tasks[submission["taskid"]], submission)
                msgs.append(
                    _("{0} selected submissions were set for replay.").format(
                        str(len(data))))
                return self.page(course, params, msgs=msgs)

        elif "page" in user_input:
            params = self.get_input_params(
                json.loads(user_input["displayed_selection"]), course)
            try:
                page = int(user_input["page"])
            except TypeError:
                page = 1
            return self.page(course, params, page=page, msgs=msgs)
        else:
            params = self.get_input_params(user_input, course)
            return self.page(course, params, msgs=msgs)
    def page(self, course, params):
        msgs = []
        daterange = [None, None]
        try:
            if params.get('date_before', ''):
                daterange[1] = datetime.strptime(params["date_before"],
                                                 "%Y-%m-%d %H:%M:%S")
            if params.get('date_after', ''):
                daterange[0] = datetime.strptime(params["date_after"],
                                                 "%Y-%m-%d %H:%M:%S")
        except ValueError:  # If match of datetime.strptime() fails
            msgs.append(_("Invalid dates"))

        if daterange[0] is None or daterange[1] is None:
            now = datetime.now().replace(minute=0, second=0, microsecond=0)
            daterange = [now - timedelta(days=14), now]

        params["date_before"] = daterange[1].strftime("%Y-%m-%d %H:%M:%S")
        params["date_after"] = daterange[0].strftime("%Y-%m-%d %H:%M:%S")
        display_hours = (daterange[1] - daterange[0]).days < 4

        users, tutored_users, audiences, tutored_audiences, tasks, limit = self.get_course_params(
            course, params)

        filter, best_submissions_list = self.get_submissions_filter(
            course,
            only_tasks=params["tasks"],
            only_tasks_with_categories=params["org_tags"],
            only_users=params["users"],
            only_audiences=params["audiences"],
            grade_between=[
                float(params["grade_min"])
                if params.get('grade_min', '') else None,
                float(params["grade_max"])
                if params.get('grade_max', '') else None
            ],
            submit_time_between=[
                x.strftime("%Y-%m-%d %H:%M:%S") for x in daterange
            ],
            keep_only_crashes="crashes_only" in params)

        stats_tasks = self._tasks_stats(tasks, filter, limit)
        stats_users = self._users_stats(filter, limit)
        stats_graph = self._graph_stats(daterange, filter, limit)
        stats_progress = self._progress_stats(course)
        stats_global = self._global_stats(
            tasks, filter, limit, best_submissions_list,
            params.get('stat', 'normal') == 'pond_stat')

        if "progress_csv" in flask.request.args:
            return make_csv(stats_progress)

        return self.template_helper.render("course_admin/stats.html",
                                           course=course,
                                           users=users,
                                           tutored_users=tutored_users,
                                           audiences=audiences,
                                           tutored_audiences=tutored_audiences,
                                           tasks=tasks,
                                           old_params=params,
                                           stats_graph=stats_graph,
                                           stats_tasks=stats_tasks,
                                           stats_users=stats_users,
                                           stats_progress=stats_progress,
                                           stats_global=stats_global,
                                           display_hour=display_hours,
                                           msgs=msgs)
Beispiel #13
0
    def page(self, course, aggregationid):
        """ Get all data and display the page """
        aggregation = self.database.aggregations.find_one(
            {"_id": ObjectId(aggregationid)})

        data = list(
            self.database.submissions.aggregate([{
                "$match": {
                    "courseid": course.get_id(),
                    "username": {
                        "$in": aggregation["students"]
                    }
                }
            }, {
                "$group": {
                    "_id": "$taskid",
                    "tried": {
                        "$sum": 1
                    },
                    "succeeded": {
                        "$sum": {
                            "$cond": [{
                                "$eq": ["$result", "success"]
                            }, 1, 0]
                        }
                    },
                    "grade": {
                        "$max": "$grade"
                    }
                }
            }]))

        tasks = course.get_tasks()
        result = dict([(taskid, {
            "taskid":
            taskid,
            "name":
            tasks[taskid].get_name(self.user_manager.session_language()),
            "tried":
            0,
            "status":
            "notviewed",
            "grade":
            0,
            "url":
            self.submission_url_generator(aggregationid, taskid)
        }) for taskid in tasks])

        for taskdata in data:
            if taskdata["_id"] in result:
                result[taskdata["_id"]]["tried"] = taskdata["tried"]
                if taskdata["tried"] == 0:
                    result[taskdata["_id"]]["status"] = "notattempted"
                elif taskdata["succeeded"]:
                    result[taskdata["_id"]]["status"] = "succeeded"
                else:
                    result[taskdata["_id"]]["status"] = "failed"
                result[taskdata["_id"]]["grade"] = taskdata["grade"]

        if "csv" in web.input():
            return make_csv(result)

        results = sorted(
            list(result.values()),
            key=lambda result:
            (tasks[result["taskid"]].get_order(), result["taskid"]))
        return self.template_helper.get_renderer(
        ).course_admin.aggregation_info(course, aggregation, results)
Beispiel #14
0
    def page(self, course, task):
        """ Get all data and display the page """
        user_list = self.user_manager.get_course_registered_users(
            course, False)
        users = OrderedDict(
            sorted(list(self.user_manager.get_users_info(user_list).items()),
                   key=lambda k: k[1][0] if k[1] is not None else ""))

        individual_results = list(
            self.database.user_tasks.find({
                "courseid": course.get_id(),
                "taskid": task.get_id(),
                "username": {
                    "$in": user_list
                }
            }))

        individual_data = OrderedDict([(username, {
            "username":
            username,
            "realname":
            user[0] if user is not None else "",
            "email":
            user[1] if user is not None else "",
            "url":
            self.individual_submission_url_generator(task, username),
            "tried":
            0,
            "grade":
            0,
            "status":
            "notviewed"
        }) for username, user in users.items()])

        for user in individual_results:
            individual_data[user["username"]]["tried"] = user["tried"]
            if user["tried"] == 0:
                individual_data[user["username"]]["status"] = "notattempted"
            elif user["succeeded"]:
                individual_data[user["username"]]["status"] = "succeeded"
            else:
                individual_data[user["username"]]["status"] = "failed"
            individual_data[user["username"]]["grade"] = user["grade"]

        aggregation_data = OrderedDict()
        for aggregation in self.user_manager.get_course_aggregations(course):
            aggregation_data[aggregation['_id']] = {
                "_id": aggregation['_id'],
                "description": aggregation['description'],
                "url":
                self.aggregation_submission_url_generator(task, aggregation),
                "tried": 0,
                "grade": 0,
                "status": "notviewed",
                "tutors": aggregation["tutors"],
                "groups": aggregation["groups"]
            }

            aggregation_results = list(
                self.database.submissions.aggregate([{
                    "$match": {
                        "courseid": course.get_id(),
                        "taskid": task.get_id(),
                        "username": {
                            "$in": aggregation["students"]
                        }
                    }
                }, {
                    "$group": {
                        "_id": "$taskid",
                        "tried": {
                            "$sum": 1
                        },
                        "succeeded": {
                            "$sum": {
                                "$cond": [{
                                    "$eq": ["$result", "success"]
                                }, 1, 0]
                            }
                        },
                        "grade": {
                            "$max": "$grade"
                        }
                    }
                }]))

            for g in aggregation_results:
                aggregation_data[aggregation['_id']]["tried"] = g["tried"]
                if g["tried"] == 0:
                    aggregation_data[
                        aggregation['_id']]["status"] = "notattempted"
                elif g["succeeded"]:
                    aggregation_data[
                        aggregation['_id']]["status"] = "succeeded"
                else:
                    aggregation_data[aggregation['_id']]["status"] = "failed"
                aggregation_data[aggregation['_id']]["grade"] = g["grade"]

        my_aggregations, other_aggregations = [], []
        for aggregation in aggregation_data.values():
            if self.user_manager.session_username() in aggregation["tutors"]:
                my_aggregations.append(aggregation)
            else:
                other_aggregations.append(aggregation)

        if "csv" in web.input() and web.input()["csv"] == "students":
            return make_csv(list(individual_data.values()))
        elif "csv" in web.input() and web.input()["csv"] == "aggregations":
            return make_csv(list(aggregation_data.values()))

        return self.template_helper.get_renderer().course_admin.task_info(
            course, task, individual_data.values(),
            [my_aggregations, other_aggregations])
Beispiel #15
0
    def page(self, course):
        """ Get all data and display the page """
        data = list(
            self.database.user_tasks.aggregate([{
                "$match": {
                    "courseid": course.get_id(),
                    "username": {
                        "$in":
                        self.user_manager.get_course_registered_users(
                            course, False)
                    }
                }
            }, {
                "$group": {
                    "_id": "$taskid",
                    "viewed": {
                        "$sum": 1
                    },
                    "attempted": {
                        "$sum": {
                            "$cond": [{
                                "$ne": ["$tried", 0]
                            }, 1, 0]
                        }
                    },
                    "attempts": {
                        "$sum": "$tried"
                    },
                    "succeeded": {
                        "$sum": {
                            "$cond": ["$succeeded", 1, 0]
                        }
                    }
                }
            }]))

        # Load tasks and verify exceptions
        files = self.task_factory.get_readable_tasks(course)
        output = {}
        errors = []
        for task in files:
            try:
                output[task] = course.get_task(task)
            except Exception as inst:
                errors.append({"taskid": task, "error": str(inst)})
        tasks = OrderedDict(
            sorted(list(output.items()),
                   key=lambda t: (t[1].get_order(), t[1].get_id())))

        # Now load additional informations
        result = OrderedDict()
        for taskid in tasks:
            result[taskid] = {
                "name":
                tasks[taskid].get_name_or_id(
                    self.user_manager.session_language()),
                "viewed":
                0,
                "attempted":
                0,
                "attempts":
                0,
                "succeeded":
                0,
                "url":
                self.submission_url_generator(taskid)
            }
        for entry in data:
            if entry["_id"] in result:
                result[entry["_id"]]["viewed"] = entry["viewed"]
                result[entry["_id"]]["attempted"] = entry["attempted"]
                result[entry["_id"]]["attempts"] = entry["attempts"]
                result[entry["_id"]]["succeeded"] = entry["succeeded"]
        if "csv" in web.input():
            return make_csv(result)
        return self.template_helper.get_renderer().course_admin.task_list(
            course, result, errors)