-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[frontend/course] Additional fields for student (#832)
- Loading branch information
Showing
14 changed files
with
301 additions
and
76 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Module definition for CourseUserSettingPage class | ||
This file is part of INGInious. See the LICENSE and the COPYRIGHTS files for | ||
more information about the licensing of this file. | ||
""" | ||
|
||
import flask | ||
from inginious.frontend.user_settings.field_types import FieldTypes | ||
from inginious.frontend.pages.utils import INGIniousAuthPage | ||
|
||
|
||
class CourseUserSettingPage(INGIniousAuthPage): | ||
""" | ||
Class definition for CourseUserSettingPage | ||
""" | ||
|
||
def GET_AUTH(self, courseid): | ||
""" GET request """ | ||
username = self.user_manager.session_username() | ||
if not self._is_accessible(courseid, username): | ||
return self.template_helper.render("course_unavailable.html") | ||
current_user = self.database.users.find_one( | ||
{"username": username}) | ||
course_user_settings = current_user.get("course_settings", {}) | ||
return self.show_page(courseid, course_user_settings.get(courseid, {}), None) | ||
|
||
def POST_AUTH(self, courseid): | ||
""" POST request """ | ||
username = self.user_manager.session_username() | ||
if not self._is_accessible(courseid, username): | ||
return self.template_helper.render("course_unavailable.html") | ||
try: | ||
course_user_settings = self._sanitize_content(flask.request.form, courseid) | ||
except Exception as e: | ||
feedback = ("danger", e) | ||
current_user = self.database.users.find_one( | ||
{"username": username}) | ||
course_user_settings = current_user.get("course_settings", {}) | ||
return self.show_page(courseid, course_user_settings.get(courseid, {}), feedback) | ||
|
||
self.database.users.update_one({"username": username}, | ||
{"$set": {"course_settings." + courseid: course_user_settings}}) | ||
|
||
return self.show_page(courseid, course_user_settings, ("success", "Course settings successfully updated.")) | ||
|
||
def show_page(self, courseid, course_user_settings, feedback): | ||
""" | ||
Definition of the show page method. | ||
:param: courseid: the id of the course. | ||
:param: course_user_settings: The dict with the settings values. | ||
:param: feedback: a tuple with the type of feedback and the feedback. None if there is no feedback. | ||
:return: | ||
""" | ||
try: | ||
course = self.course_factory.get_course(courseid) | ||
course_user_setting_fields = course.get_course_user_settings() | ||
return self.template_helper.render("course_user_settings.html", course=course, | ||
course_user_setting_fields=course_user_setting_fields, | ||
course_user_settings=course_user_settings, fieldtypes=FieldTypes, | ||
feedback=feedback) | ||
except Exception: | ||
return self.template_helper.render("course_unavailable.html") | ||
|
||
def _is_accessible(self, courseid, username): | ||
""" | ||
Verify if course is accessible and that courseid match an existing course. | ||
:param: courseid - The id of the course. | ||
:param: username - The username of the logged user. | ||
:return: A boolean if the course is accessible for the given user. | ||
""" | ||
try: | ||
course = self.course_factory.get_course(courseid) | ||
return self.user_manager.course_is_user_registered(course, username) \ | ||
and self.user_manager.course_is_open_to_user(course, lti=False) | ||
except Exception: | ||
return False | ||
|
||
def _sanitize_content(self, data, courseid): | ||
""" | ||
Sanitize received data | ||
:param: data - A dictionary that normally contains user settings for a course. | ||
:param: courseid - Id of the course. | ||
:return: A sanitized dict. | ||
""" | ||
if not isinstance(data, dict): | ||
raise TypeError("Incorrect type of data.") | ||
copied_data = {} | ||
course = self.course_factory.get_course(courseid) | ||
add_fields = course.get_course_user_settings() | ||
for field in add_fields: | ||
if field not in data: | ||
# setup default value. | ||
copied_data[field] = add_fields[field].get_cast_type()() | ||
else: | ||
try: | ||
value = data[field] | ||
if value is None or value == "": | ||
value = add_fields[field].get_default_value() | ||
# try to cast given value to be sure that we match expected type. | ||
copied_data[field] = add_fields[field].get_cast_type()(value) | ||
except ValueError: | ||
raise ValueError("Wrong value for field: " + str(field)) | ||
return copied_data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
{# This file is part of INGInious. See the LICENSE and the COPYRIGHTS files for #} | ||
{# more information about the licensing of this file. #} | ||
|
||
{% extends "layout.html" %} | ||
{% block title %}{{ course.get_name(user_manager.session_language()) }}{% endblock %} | ||
{% set registered = user_manager.course_is_user_registered(course) %} | ||
{% set staff = user_manager.has_staff_rights_on_course(course) %} | ||
{% block column %} | ||
{{ template_helper.call('course_menu', course=course, template_helper=template_helper) | safe }} | ||
{%if staff %} | ||
{% if not course.is_open_to_non_staff() %} | ||
<div class="alert alert-warning" role="alert"> | ||
{{ _("This course is currently invisible for students. You can change this by modifying the \"accessibility\" option in the configuration of the course.") }} | ||
</div> | ||
{% endif %} | ||
<div class="list-group"> | ||
<a class="list-group-item list-group-item-action list-group-item-info" href="{{ get_homepath() }}/admin/{{ course.get_id() }}"> | ||
<i class="fa fa-user-secret fa-fw"></i> {{ _("Course administration") }} | ||
</a> | ||
</div> | ||
{% elif registered %} | ||
<div class="list-group"> | ||
<a class="list-group-item list-group-item-action list-group-item-info" href="{{ get_homepath() }}/group/{{ course.get_id() }}"> | ||
<i class="fa fa-group fa-fw"></i> | ||
{% set mygroup = user_manager.get_course_user_group(course) %} | ||
{% if mygroup and user_manager.session_username() in mygroup['students'] %} | ||
{{ _("Group : {}").format(mygroup['description']) }} | ||
{% else %} | ||
{{ _("Group management") }} | ||
{% endif %} | ||
</a> | ||
<a class="list-group-item list-group-item-action list-group-item-info" href="{{ get_homepath() }}/user_settings/{{ course.get_id() }}"> | ||
<i class="fa fa-cogs fa-fw"></i> {{ _("Course Settings") }} | ||
</a> | ||
</div> | ||
{%endif %} | ||
{% endblock %} | ||
{% block navbar %} | ||
<nav aria-label="breadcrumb"> | ||
<ol class="breadcrumb"> | ||
{% if registered %} | ||
<li class="breadcrumb-item"><a href="{{ get_homepath() }}/mycourses" title="{{ _('My courses') }}" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-th-list"></i></a></li> | ||
{% else %} | ||
<li class="breadcrumb-item"><a href="{{get_homepath() }}/courselist" title="{{ _('Course list') }}" data-toggle="tooltip" data-placement="bottom"><i class="fa fa-th-list"></i></a></li> | ||
{% endif %} | ||
<li class="breadcrumb-item"><a href="{{get_homepath() }}/course/{{ course.get_id() }}">{{ course.get_name(user_manager.session_language()) }} <span class="sr-only">{{ _("(current)") }}</span></a></li> | ||
<li class="breadcrumb-item active"><a href="#"><i class="fa fa-cogs"></i> {{ _("Course settings") }}</a></li> | ||
</ol> | ||
</nav> | ||
{% endblock %} | ||
{% block content %} | ||
{% if feedback is not none %} | ||
<div class="alert alert-{{ feedback[0] }}" role="alert"> | ||
{{ _(feedback[1] ) }} | ||
</div> | ||
{% endif %} | ||
<h2>{{_("Course settings")}}</h2> | ||
{% if course_user_setting_fields | length ==0 %} | ||
<div class="alert alert-info" role="alert">{{ _("There is no customizable option for this course") }}</div> | ||
{% else %} | ||
<form method="post" action=""> | ||
{% for key in course_user_setting_fields %} | ||
<div class="form-group row"> | ||
<label class="col-sm-2 " for="{{ key }}" class="control-label">{{ course_user_setting_fields[key].get_description() }}</label> | ||
<div class="col-sm-10"> | ||
{{ course_user_setting_fields[key].render(template_helper, course_user_settings[key]) | safe }} | ||
</div> | ||
</div> | ||
{% endfor %} | ||
<button type="submit" class="btn btn-block btn-primary">{{ _("Save data") }}</button> | ||
</form> | ||
{% endif %} | ||
{% endblock %} |
Oops, something went wrong.