learning-paths-plugin 0.5.0__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/CHANGELOG.rst +10 -0
- {learning_paths_plugin-0.5.0/learning_paths_plugin.egg-info → learning_paths_plugin-0.6.0}/PKG-INFO +11 -1
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/__init__.py +1 -1
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/receivers.py +39 -21
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0/learning_paths_plugin.egg-info}/PKG-INFO +11 -1
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/LICENSE.txt +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/MANIFEST.in +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/README.rst +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/admin.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/__init__.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/urls.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/__init__.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/filters.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/permissions.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/serializers.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/urls.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/utils.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/views.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/apps.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/compat.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/conftest.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/keys.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0001_initial.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0002_learningpath_uuid.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0003_learningpath_subtitle.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0004_auto_20240207_1633.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0005_learningpathstep_weight_learningpathgradingcriteria.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0006_enrollment_models.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0007_replace_uuid_with_learningpathkey.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0008_remove_learningpathstep_relative_due_date_in_days.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0009_remove_learningpath_slug.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0010_learningpath_invite_only.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0011_replace_learningpath_image_url_with_image.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0012_alter_learningpath_subtitle.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0013_enrollment_audit.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0014_remove_learningpath_duration_in_days_and_more.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0015_make_skill_level_optional.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/0016_alter_learningpathstep_options.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/__init__.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/models.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/settings.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/templates/learning_paths/base.html +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/urls.py +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths_plugin.egg-info/SOURCES.txt +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths_plugin.egg-info/dependency_links.txt +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths_plugin.egg-info/entry_points.txt +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths_plugin.egg-info/not-zip-safe +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths_plugin.egg-info/requires.txt +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths_plugin.egg-info/top_level.txt +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/pyproject.toml +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/requirements/base.in +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/requirements/constraints.txt +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/setup.cfg +0 -0
- {learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/setup.py +0 -0
|
@@ -16,6 +16,16 @@ Unreleased
|
|
|
16
16
|
|
|
17
17
|
*
|
|
18
18
|
|
|
19
|
+
0.6.0 - 2026-10-22
|
|
20
|
+
******************
|
|
21
|
+
|
|
22
|
+
Fixed
|
|
23
|
+
=====
|
|
24
|
+
|
|
25
|
+
* Process pending Learning Path enrollments when a user activates the account or changes the email address, instead
|
|
26
|
+
of only when the account is created. Enrollments are no longer created for accounts that have not been activated.
|
|
27
|
+
* Link all unclaimed enrollment allowed records to the user, including the inactive ones.
|
|
28
|
+
|
|
19
29
|
0.5.0 - 2026-08-11
|
|
20
30
|
******************
|
|
21
31
|
|
{learning_paths_plugin-0.5.0/learning_paths_plugin.egg-info → learning_paths_plugin-0.6.0}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: learning-paths-plugin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Learning Paths plugin
|
|
5
5
|
Home-page: https://github.com/open-craft/learning-paths-plugin
|
|
6
6
|
Author: OpenCraft
|
|
@@ -120,6 +120,16 @@ Unreleased
|
|
|
120
120
|
|
|
121
121
|
*
|
|
122
122
|
|
|
123
|
+
0.6.0 - 2026-10-22
|
|
124
|
+
******************
|
|
125
|
+
|
|
126
|
+
Fixed
|
|
127
|
+
=====
|
|
128
|
+
|
|
129
|
+
* Process pending Learning Path enrollments when a user activates the account or changes the email address, instead
|
|
130
|
+
of only when the account is created. Enrollments are no longer created for accounts that have not been activated.
|
|
131
|
+
* Link all unclaimed enrollment allowed records to the user, including the inactive ones.
|
|
132
|
+
|
|
123
133
|
0.5.0 - 2026-08-11
|
|
124
134
|
******************
|
|
125
135
|
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
6
|
|
|
7
|
-
from django.db import IntegrityError
|
|
8
7
|
from django.db.models.signals import post_save
|
|
9
8
|
from django.dispatch import receiver
|
|
10
9
|
|
|
@@ -19,63 +18,82 @@ logger = logging.getLogger(__name__)
|
|
|
19
18
|
|
|
20
19
|
def process_pending_enrollments(sender, instance, created, **kwargs):
|
|
21
20
|
"""
|
|
22
|
-
Process pending enrollments
|
|
21
|
+
Process pending enrollments when a user becomes able to claim them.
|
|
23
22
|
|
|
24
23
|
Bulk enrollment API allows enrolling users with just the email. So learners who
|
|
25
24
|
do not have an account yet would also be enrolled. This information is stored
|
|
26
25
|
in the LearningPathEnrollmentAllowed model. This signal handler processes such
|
|
27
|
-
instances and
|
|
26
|
+
instances and creates the corresponding LearningPathEnrollment objects.
|
|
27
|
+
|
|
28
|
+
The entries are processed only for active users (i.e., users who confirmed their email address) when:
|
|
29
|
+
1. The user is created (e.g., when the account is created already activated).
|
|
30
|
+
2. The user activates the account.
|
|
31
|
+
3. The user changes the email address (the change is applied after confirming the new email address).
|
|
28
32
|
|
|
29
33
|
Args:
|
|
30
34
|
sender: User model class.
|
|
31
35
|
instance: The actual instance being saved.
|
|
32
36
|
created: A boolean indicating whether this is a creation and not an update.
|
|
33
37
|
"""
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
instance,
|
|
38
|
-
)
|
|
38
|
+
# `_changed_fields` is set by the `pre_save` receiver of the User model in edx-platform.
|
|
39
|
+
changed_fields = getattr(instance, "_changed_fields", {})
|
|
40
|
+
if not instance.is_active or not (created or {"email", "is_active"} & changed_fields.keys()):
|
|
39
41
|
return
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
process_pending_enrollments_for_user(instance)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def process_pending_enrollments_for_user(user) -> int:
|
|
47
|
+
"""
|
|
48
|
+
Process the LearningPathEnrollmentAllowed entries matching the user's email.
|
|
49
|
+
|
|
50
|
+
Active entries are converted into enrollments, unless the user already has an enrollment (active or not) in the
|
|
51
|
+
learning path. All entries that are not linked to any user yet are deactivated and linked to the user, so they
|
|
52
|
+
cannot be claimed by another account that changes its email to the same address.
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
The number of created enrollments.
|
|
56
|
+
"""
|
|
57
|
+
logger.info("[LearningPaths] Processing pending enrollments for user %s", user)
|
|
58
|
+
pending_enrollments = LearningPathEnrollmentAllowed.objects.filter(email=user.email, user__isnull=True)
|
|
43
59
|
enrollments_created = 0
|
|
44
60
|
|
|
45
61
|
for entry in pending_enrollments:
|
|
46
|
-
|
|
62
|
+
enrollment_exists = LearningPathEnrollment.objects.filter(learning_path=entry.learning_path, user=user).exists()
|
|
63
|
+
|
|
64
|
+
if entry.is_active and not enrollment_exists:
|
|
47
65
|
audit_data = {
|
|
48
|
-
"enrolled_by":
|
|
66
|
+
"enrolled_by": user,
|
|
49
67
|
"state_transition": LearningPathEnrollmentAudit.ALLOWEDTOENROLL_TO_ENROLLED,
|
|
50
68
|
}
|
|
51
69
|
if last_allowed_audit := entry.audit.order_by("-created").first():
|
|
52
70
|
for field in ["reason", "org", "role"]:
|
|
53
71
|
audit_data[field] = getattr(last_allowed_audit, field, "")
|
|
54
72
|
|
|
55
|
-
enrollment = LearningPathEnrollment(learning_path=entry.learning_path, user=
|
|
73
|
+
enrollment = LearningPathEnrollment(learning_path=entry.learning_path, user=user)
|
|
56
74
|
enrollment._audit = audit_data # pylint: disable=protected-access
|
|
57
75
|
enrollment.save()
|
|
58
76
|
enrollments_created += 1
|
|
59
77
|
|
|
60
78
|
# Link existing audits from the "allowed to enroll" entry to the new enrollment.
|
|
61
79
|
entry.audit.update(enrollment=enrollment)
|
|
62
|
-
|
|
63
|
-
except IntegrityError: # pragma: no cover
|
|
80
|
+
elif entry.is_active:
|
|
64
81
|
logger.info(
|
|
65
82
|
"[LearningPaths] Enrollment already exists for user %s in the learning path %s",
|
|
66
|
-
|
|
83
|
+
user,
|
|
67
84
|
entry.learning_path.key,
|
|
68
85
|
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
86
|
+
|
|
87
|
+
entry.is_active = False
|
|
88
|
+
entry.user = user
|
|
89
|
+
entry.save()
|
|
73
90
|
|
|
74
91
|
logger.info(
|
|
75
92
|
"[LearningPaths] Processed %d pending Learning Path enrollments for user %s.",
|
|
76
93
|
enrollments_created,
|
|
77
|
-
|
|
94
|
+
user,
|
|
78
95
|
)
|
|
96
|
+
return enrollments_created
|
|
79
97
|
|
|
80
98
|
|
|
81
99
|
def _create_enrollment_audit(instance: LearningPathEnrollment | LearningPathEnrollmentAllowed, audit_data: dict):
|
{learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0/learning_paths_plugin.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: learning-paths-plugin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Learning Paths plugin
|
|
5
5
|
Home-page: https://github.com/open-craft/learning-paths-plugin
|
|
6
6
|
Author: OpenCraft
|
|
@@ -120,6 +120,16 @@ Unreleased
|
|
|
120
120
|
|
|
121
121
|
*
|
|
122
122
|
|
|
123
|
+
0.6.0 - 2026-10-22
|
|
124
|
+
******************
|
|
125
|
+
|
|
126
|
+
Fixed
|
|
127
|
+
=====
|
|
128
|
+
|
|
129
|
+
* Process pending Learning Path enrollments when a user activates the account or changes the email address, instead
|
|
130
|
+
of only when the account is created. Enrollments are no longer created for accounts that have not been activated.
|
|
131
|
+
* Link all unclaimed enrollment allowed records to the user, including the inactive ones.
|
|
132
|
+
|
|
123
133
|
0.5.0 - 2026-08-11
|
|
124
134
|
******************
|
|
125
135
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/__init__.py
RENAMED
|
File without changes
|
{learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/filters.py
RENAMED
|
File without changes
|
{learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/permissions.py
RENAMED
|
File without changes
|
{learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/api/v1/serializers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{learning_paths_plugin-0.5.0 → learning_paths_plugin-0.6.0}/learning_paths/migrations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|