166 lines
5.4 KiB
Python
166 lines
5.4 KiB
Python
""" Contains the APIs for course credit requirements """
|
|
|
|
from .exceptions import InvalidCreditRequirements
|
|
from .models import CreditCourse, CreditRequirement
|
|
from openedx.core.djangoapps.credit.exceptions import InvalidCreditCourse
|
|
|
|
|
|
def set_credit_requirements(course_key, requirements):
|
|
""" Add requirements to given course
|
|
|
|
Args:
|
|
course_key(CourseKey): The identifier for course
|
|
requirements(list): List of requirements to be added
|
|
|
|
Example:
|
|
>>> set_credit_requirements(
|
|
"course-v1-edX-DemoX-1T2015",
|
|
[
|
|
{
|
|
"namespace": "verification",
|
|
"name": "verification",
|
|
"criteria": {},
|
|
},
|
|
{
|
|
"namespace": "reverification",
|
|
"name": "midterm",
|
|
"criteria": {},
|
|
},
|
|
{
|
|
"namespace": "proctored_exam",
|
|
"name": "final",
|
|
"criteria": {},
|
|
},
|
|
{
|
|
"namespace": "grade",
|
|
"name": "grade",
|
|
"criteria": {"min_grade": 0.8},
|
|
},
|
|
])
|
|
|
|
Raises:
|
|
InvalidCreditRequirements
|
|
|
|
Returns:
|
|
None
|
|
"""
|
|
|
|
invalid_requirements = _validate_requirements(requirements)
|
|
if invalid_requirements:
|
|
invalid_requirements = ", ".join(invalid_requirements)
|
|
raise InvalidCreditRequirements(invalid_requirements)
|
|
|
|
try:
|
|
credit_course = CreditCourse.get_credit_course(course_key=course_key)
|
|
except CreditCourse.DoesNotExist:
|
|
raise InvalidCreditCourse()
|
|
|
|
old_requirements = CreditRequirement.get_course_requirements(course_key=course_key)
|
|
requirements_to_disable = _get_requirements_to_disable(old_requirements, requirements)
|
|
if requirements_to_disable:
|
|
CreditRequirement.disable_credit_requirements(requirements_to_disable)
|
|
|
|
for requirement in requirements:
|
|
CreditRequirement.add_or_update_course_requirement(credit_course, requirement)
|
|
|
|
|
|
def get_credit_requirements(course_key, namespace=None):
|
|
""" Returns the requirements of a given course and namespace
|
|
|
|
Args:
|
|
course_key(CourseKey): The identifier for course
|
|
namespace(str): Namespace of requirements
|
|
|
|
Example:
|
|
>>> get_credit_requirements("course-v1-edX-DemoX-1T2015")
|
|
{
|
|
requirements =
|
|
[
|
|
{
|
|
"namespace": "verification",
|
|
"name": "verification",
|
|
"criteria": {},
|
|
},
|
|
{
|
|
"namespace": "reverification",
|
|
"name": "midterm",
|
|
"criteria": {},
|
|
},
|
|
{
|
|
"namespace": "proctored_exam",
|
|
"name": "final",
|
|
"criteria": {},
|
|
},
|
|
{
|
|
"namespace": "grade",
|
|
"name": "grade",
|
|
"criteria": {"min_grade": 0.8},
|
|
},
|
|
]
|
|
}
|
|
|
|
Returns:
|
|
Dict of requirements in the given namespace
|
|
"""
|
|
|
|
requirements = CreditRequirement.get_course_requirements(course_key, namespace)
|
|
return [
|
|
{
|
|
"namespace": requirement.namespace,
|
|
"name": requirement.name,
|
|
"criteria": requirement.criteria
|
|
}
|
|
for requirement in requirements
|
|
]
|
|
|
|
|
|
def _get_requirements_to_disable(old_requirements, new_requirements):
|
|
""" Returns the ids of CreditRequirement to be disabled that are deleted from the courseware
|
|
|
|
Args:
|
|
old_requirements(QuerySet): QuerySet of CreditRequirement
|
|
new_requirements(list): List of requirements being added
|
|
|
|
Returns:
|
|
List of ids of CreditRequirement that are not in new_requirements
|
|
"""
|
|
requirements_to_disable = []
|
|
for old_req in old_requirements:
|
|
found_flag = False
|
|
for req in new_requirements:
|
|
if req["namespace"] == old_req.namespace and req["name"] == old_req.name:
|
|
found_flag = True
|
|
break
|
|
if not found_flag:
|
|
requirements_to_disable.append(old_req.id)
|
|
return requirements_to_disable
|
|
|
|
|
|
def _validate_requirements(requirements):
|
|
""" Validate the requirements
|
|
|
|
Args:
|
|
requirements(list): List of requirements
|
|
|
|
Returns:
|
|
List of strings of invalid requirements
|
|
"""
|
|
invalid_requirements = []
|
|
for requirement in requirements:
|
|
invalid_params = []
|
|
if not requirement.get("namespace"):
|
|
invalid_params.append("namespace")
|
|
if not requirement.get("name"):
|
|
invalid_params.append("name")
|
|
if "criteria" not in requirement:
|
|
invalid_params.append("criteria")
|
|
|
|
if invalid_params:
|
|
invalid_requirements.append(
|
|
u"{requirement} has missing/invalid parameters: {params}".format(
|
|
requirement=requirement,
|
|
params=invalid_params,
|
|
)
|
|
)
|
|
return invalid_requirements
|