-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompat.py
More file actions
131 lines (92 loc) · 4.71 KB
/
compat.py
File metadata and controls
131 lines (92 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
"""
Proxies and compatibility code for edx-platform features.
This module moderates access to all edx-platform features allowing for cross-version compatibility code.
It also simplifies running tests outside edx-platform's environment by stubbing these functions in unit tests.
"""
# ruff: noqa: PLC0415
from __future__ import annotations
from contextlib import contextmanager
from typing import TYPE_CHECKING
import pytz
from celery import Celery
from django.conf import settings
from learning_paths.models import LearningPath
if TYPE_CHECKING:
from datetime import datetime
from django.contrib.auth.models import User
from learning_paths.keys import LearningPathKey
from opaque_keys.edx.keys import CourseKey, LearningContextKey
def get_celery_app() -> Celery:
"""Get Celery app to reuse configuration and queues."""
if getattr(settings, "TESTING", False):
# We can ignore this in the testing environment.
return Celery(task_always_eager=True)
# noinspection PyUnresolvedReferences,PyPackageRequirements
from lms import CELERY_APP
return CELERY_APP
def get_default_storage_url() -> str:
"""Get the default storage URL from Open edX."""
return f"{settings.LMS_ROOT_URL}{settings.MEDIA_URL}"
def get_course_grading_policy(course_id: CourseKey) -> dict:
"""Get the course grading policy from Open edX."""
# noinspection PyUnresolvedReferences,PyPackageRequirements
from xmodule.modulestore.django import modulestore
return modulestore().get_course(course_id).grading_policy["GRADER"]
def _get_course_name(course_id: CourseKey) -> str:
"""Get the course name from Open edX."""
# noinspection PyUnresolvedReferences,PyPackageRequirements
from openedx.core.djangoapps.content.course_overviews.api import get_course_overview_or_none
name = str(course_id)
if course_overview := get_course_overview_or_none(course_id):
name = course_overview.cert_name_long or course_overview.display_name or name
return name
def _get_learning_path_name(learning_path_key: LearningPathKey) -> str:
"""Get the Learning Path name from the plugin."""
try:
return LearningPath.objects.get(key=learning_path_key).display_name
except LearningPath.DoesNotExist:
return str(learning_path_key)
def get_learning_context_name(learning_context_key: LearningContextKey) -> str:
"""Get the learning context (course or Learning Path) name."""
if learning_context_key.is_course:
return _get_course_name(learning_context_key)
return _get_learning_path_name(learning_context_key)
def get_course_enrollments(course_id: CourseKey, user_id: int | None = None) -> list[User]:
"""Get the course enrollments from Open edX."""
# noinspection PyUnresolvedReferences,PyPackageRequirements
from common.djangoapps.student.models import CourseEnrollment
enrollments = CourseEnrollment.objects.filter(course_id=course_id, is_active=True).select_related('user')
if user_id:
enrollments = enrollments.filter(user__id=user_id)
return [enrollment.user for enrollment in enrollments]
@contextmanager
def prefetch_course_grades(course_id: CourseKey, users: list[User]):
"""
Prefetch the course grades from Open edX.
This optimizes retrieving grades for multiple users.
"""
# noinspection PyUnresolvedReferences,PyPackageRequirements
from lms.djangoapps.grades.api import clear_prefetched_course_grades, prefetch_course_and_subsection_grades
prefetch_course_and_subsection_grades(course_id, users)
try:
yield
finally:
# This uses `clear_prefetched_course_grades` instead of `clear_prefetched_course_and_subsection_grades` because
# these function names were accidentally swapped in the Open edX codebase.
# Ref: https://github.com/openedx/edx-platform/blob/1fe67d3f6b40233791d4599bae28df8c0ac91c4d/lms/djangoapps/grades/models_api.py#L30-L36
clear_prefetched_course_grades(course_id)
def get_course_grade(user: User, course_id: CourseKey): # noqa: ANN201
"""Get the `CourseGrade` instance from Open edX."""
# noinspection PyUnresolvedReferences,PyPackageRequirements
from lms.djangoapps.grades.api import CourseGradeFactory
return CourseGradeFactory().read(user, course_key=course_id)
def get_localized_credential_date(date: datetime) -> str:
"""
Get the localized date from Open edX.
:param date: The datetime to format.
:returns: The formatted date string.
"""
# noinspection PyUnresolvedReferences,PyPackageRequirements
from common.djangoapps.util.date_utils import strftime_localized
localized_date = date.astimezone(pytz.timezone(settings.TIME_ZONE))
return strftime_localized(localized_date, settings.CERTIFICATE_DATE_FORMAT)