learning-credentials 0.2.1__tar.gz → 0.2.2__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_credentials-0.2.1 → learning_credentials-0.2.2}/CHANGELOG.rst +12 -0
- {learning_credentials-0.2.1/learning_credentials.egg-info → learning_credentials-0.2.2}/PKG-INFO +27 -27
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/__init__.py +0 -2
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/compat.py +2 -0
- learning_credentials-0.2.2/learning_credentials/conf/locale/config.yaml +85 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/migrations/0001_initial.py +2 -2
- learning_credentials-0.2.2/learning_credentials/migrations/0002_migrate_to_learning_credentials.py +40 -0
- learning_credentials-0.2.2/learning_credentials/migrations/0006_cleanup_openedx_certificates_tables.py +21 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/models.py +1 -1
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/processors.py +71 -5
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/settings/common.py +0 -3
- {learning_credentials-0.2.1 → learning_credentials-0.2.2/learning_credentials.egg-info}/PKG-INFO +27 -27
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials.egg-info/SOURCES.txt +2 -9
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials.egg-info/entry_points.txt +0 -1
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials.egg-info/requires.txt +7 -7
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials.egg-info/top_level.txt +0 -1
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/pyproject.toml +97 -18
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/tests/test_processors.py +27 -1
- learning_credentials-0.2.1/learning_credentials/migrations/0002_migrate_to_learning_credentials.py +0 -32
- learning_credentials-0.2.1/learning_credentials.egg-info/not-zip-safe +0 -1
- learning_credentials-0.2.1/openedx_certificates/__init__.py +0 -1
- learning_credentials-0.2.1/openedx_certificates/apps.py +0 -11
- learning_credentials-0.2.1/openedx_certificates/migrations/0001_initial.py +0 -206
- learning_credentials-0.2.1/openedx_certificates/migrations/__init__.py +0 -0
- learning_credentials-0.2.1/openedx_certificates/models.py +0 -38
- learning_credentials-0.2.1/requirements/base.in +0 -17
- learning_credentials-0.2.1/requirements/constraints.txt +0 -12
- learning_credentials-0.2.1/setup.py +0 -173
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/LICENSE.txt +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/MANIFEST.in +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/README.rst +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/admin.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/apps.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/exceptions.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/generators.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/migrations/0003_rename_certificates_to_credentials.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/migrations/0004_replace_course_keys_with_learning_context_keys.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/migrations/0005_rename_processors_and_generators.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/migrations/__init__.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/settings/__init__.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/settings/production.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/tasks.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/templates/learning_credentials/base.html +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/body.html +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/body.txt +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/from_name.txt +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/head.html +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/subject.txt +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/urls.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/views.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials.egg-info/dependency_links.txt +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/setup.cfg +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/tests/test_generators.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/tests/test_models.py +0 -0
- {learning_credentials-0.2.1 → learning_credentials-0.2.2}/tests/test_tasks.py +0 -0
|
@@ -16,6 +16,18 @@ Unreleased
|
|
|
16
16
|
|
|
17
17
|
*
|
|
18
18
|
|
|
19
|
+
0.2.2 - 2025-08-05
|
|
20
|
+
|
|
21
|
+
Added
|
|
22
|
+
=====
|
|
23
|
+
|
|
24
|
+
* Step-specific options support for Learning Path credentials.
|
|
25
|
+
|
|
26
|
+
Removed
|
|
27
|
+
=======
|
|
28
|
+
|
|
29
|
+
* Legacy `openedx_certificates` app.
|
|
30
|
+
|
|
19
31
|
0.2.1 – 2025-05-05
|
|
20
32
|
******************
|
|
21
33
|
|
{learning_credentials-0.2.1/learning_credentials.egg-info → learning_credentials-0.2.2}/PKG-INFO
RENAMED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: learning-credentials
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A pluggable service for preparing Open edX credentials.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
Author-email: OpenCraft <help@opencraft.com>
|
|
6
|
+
License-Expression: AGPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/open-craft/learning-credentials
|
|
8
|
+
Project-URL: Repository, https://github.com/open-craft/learning-credentials
|
|
9
|
+
Project-URL: Documentation, https://learning-credentials.readthedocs.io/
|
|
10
|
+
Keywords: Python,edx,credentials,django
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
12
|
Classifier: Framework :: Django
|
|
12
13
|
Classifier: Framework :: Django :: 4.2
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -19,31 +19,20 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
19
|
Requires-Python: >=3.11
|
|
20
20
|
Description-Content-Type: text/x-rst
|
|
21
21
|
License-File: LICENSE.txt
|
|
22
|
-
Requires-Dist: celery
|
|
23
22
|
Requires-Dist: django
|
|
24
|
-
Requires-Dist: django-celery-beat
|
|
25
23
|
Requires-Dist: django-model-utils
|
|
26
|
-
Requires-Dist:
|
|
24
|
+
Requires-Dist: edx-opaque-keys
|
|
25
|
+
Requires-Dist: celery
|
|
26
|
+
Requires-Dist: django-celery-beat
|
|
27
27
|
Requires-Dist: django_reverse_admin
|
|
28
28
|
Requires-Dist: djangorestframework
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist: edx_ace
|
|
31
|
-
Requires-Dist: learning-paths-plugin>=0.3.0
|
|
32
|
-
Requires-Dist: openedx-completion-aggregator
|
|
29
|
+
Requires-Dist: django-object-actions
|
|
33
30
|
Requires-Dist: pypdf
|
|
34
31
|
Requires-Dist: reportlab
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Dynamic: description
|
|
39
|
-
Dynamic: description-content-type
|
|
40
|
-
Dynamic: home-page
|
|
41
|
-
Dynamic: keywords
|
|
42
|
-
Dynamic: license
|
|
32
|
+
Requires-Dist: openedx-completion-aggregator
|
|
33
|
+
Requires-Dist: edx_ace
|
|
34
|
+
Requires-Dist: learning-paths-plugin>=0.3.4
|
|
43
35
|
Dynamic: license-file
|
|
44
|
-
Dynamic: requires-dist
|
|
45
|
-
Dynamic: requires-python
|
|
46
|
-
Dynamic: summary
|
|
47
36
|
|
|
48
37
|
learning-credentials
|
|
49
38
|
####################
|
|
@@ -167,7 +156,6 @@ Please do not report security issues in public. Please email security@openedx.or
|
|
|
167
156
|
:target: https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=open-craft/learning-credentials
|
|
168
157
|
:alt: Visualization
|
|
169
158
|
|
|
170
|
-
|
|
171
159
|
Change Log
|
|
172
160
|
##########
|
|
173
161
|
|
|
@@ -186,6 +174,18 @@ Unreleased
|
|
|
186
174
|
|
|
187
175
|
*
|
|
188
176
|
|
|
177
|
+
0.2.2 - 2025-08-05
|
|
178
|
+
|
|
179
|
+
Added
|
|
180
|
+
=====
|
|
181
|
+
|
|
182
|
+
* Step-specific options support for Learning Path credentials.
|
|
183
|
+
|
|
184
|
+
Removed
|
|
185
|
+
=======
|
|
186
|
+
|
|
187
|
+
* Legacy `openedx_certificates` app.
|
|
188
|
+
|
|
189
189
|
0.2.1 – 2025-05-05
|
|
190
190
|
******************
|
|
191
191
|
|
|
@@ -5,6 +5,8 @@ This module moderates access to all edx-platform features allowing for cross-ver
|
|
|
5
5
|
It also simplifies running tests outside edx-platform's environment by stubbing these functions in unit tests.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
# ruff: noqa: PLC0415
|
|
9
|
+
|
|
8
10
|
from __future__ import annotations
|
|
9
11
|
|
|
10
12
|
from contextlib import contextmanager
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Configuration for i18n workflow.
|
|
2
|
+
|
|
3
|
+
locales:
|
|
4
|
+
- en # English - Source Language
|
|
5
|
+
- am # Amharic
|
|
6
|
+
- ar # Arabic
|
|
7
|
+
- az # Azerbaijani
|
|
8
|
+
- bg_BG # Bulgarian (Bulgaria)
|
|
9
|
+
- bn_BD # Bengali (Bangladesh)
|
|
10
|
+
- bn_IN # Bengali (India)
|
|
11
|
+
- bs # Bosnian
|
|
12
|
+
- ca # Catalan
|
|
13
|
+
- ca@valencia # Catalan (Valencia)
|
|
14
|
+
- cs # Czech
|
|
15
|
+
- cy # Welsh
|
|
16
|
+
- da # Danish
|
|
17
|
+
- de_DE # German (Germany)
|
|
18
|
+
- el # Greek
|
|
19
|
+
- en # English
|
|
20
|
+
- en_GB # English (United Kingdom)
|
|
21
|
+
# Don't pull these until we figure out why pages randomly display in these locales,
|
|
22
|
+
# when the user's browser is in English and the user is not logged in.
|
|
23
|
+
# - en@lolcat # LOLCAT English
|
|
24
|
+
# - en@pirate # Pirate English
|
|
25
|
+
- es_419 # Spanish (Latin America)
|
|
26
|
+
- es_AR # Spanish (Argentina)
|
|
27
|
+
- es_EC # Spanish (Ecuador)
|
|
28
|
+
- es_ES # Spanish (Spain)
|
|
29
|
+
- es_MX # Spanish (Mexico)
|
|
30
|
+
- es_PE # Spanish (Peru)
|
|
31
|
+
- et_EE # Estonian (Estonia)
|
|
32
|
+
- eu_ES # Basque (Spain)
|
|
33
|
+
- fa # Persian
|
|
34
|
+
- fa_IR # Persian (Iran)
|
|
35
|
+
- fi_FI # Finnish (Finland)
|
|
36
|
+
- fil # Filipino
|
|
37
|
+
- fr # French
|
|
38
|
+
- gl # Galician
|
|
39
|
+
- gu # Gujarati
|
|
40
|
+
- he # Hebrew
|
|
41
|
+
- hi # Hindi
|
|
42
|
+
- hr # Croatian
|
|
43
|
+
- hu # Hungarian
|
|
44
|
+
- hy_AM # Armenian (Armenia)
|
|
45
|
+
- id # Indonesian
|
|
46
|
+
- it_IT # Italian (Italy)
|
|
47
|
+
- ja_JP # Japanese (Japan)
|
|
48
|
+
- kk_KZ # Kazakh (Kazakhstan)
|
|
49
|
+
- km_KH # Khmer (Cambodia)
|
|
50
|
+
- kn # Kannada
|
|
51
|
+
- ko_KR # Korean (Korea)
|
|
52
|
+
- lt_LT # Lithuanian (Lithuania)
|
|
53
|
+
- ml # Malayalam
|
|
54
|
+
- mn # Mongolian
|
|
55
|
+
- mr # Marathi
|
|
56
|
+
- ms # Malay
|
|
57
|
+
- nb # Norwegian Bokmål
|
|
58
|
+
- ne # Nepali
|
|
59
|
+
- nl_NL # Dutch (Netherlands)
|
|
60
|
+
- or # Oriya
|
|
61
|
+
- pl # Polish
|
|
62
|
+
- pt_BR # Portuguese (Brazil)
|
|
63
|
+
- pt_PT # Portuguese (Portugal)
|
|
64
|
+
- ro # Romanian
|
|
65
|
+
- ru # Russian
|
|
66
|
+
- si # Sinhala
|
|
67
|
+
- sk # Slovak
|
|
68
|
+
- sl # Slovenian
|
|
69
|
+
- sq # Albanian
|
|
70
|
+
- sr # Serbian
|
|
71
|
+
- ta # Tamil
|
|
72
|
+
- te # Telugu
|
|
73
|
+
- th # Thai
|
|
74
|
+
- tr_TR # Turkish (Turkey)
|
|
75
|
+
- uk # Ukranian
|
|
76
|
+
- ur # Urdu
|
|
77
|
+
- uz # Uzbek
|
|
78
|
+
- vi # Vietnamese
|
|
79
|
+
- zh_CN # Chinese (China)
|
|
80
|
+
- zh_HK # Chinese (Hong Kong)
|
|
81
|
+
- zh_TW # Chinese (Taiwan)
|
|
82
|
+
|
|
83
|
+
# The locales used for fake-accented English, for testing.
|
|
84
|
+
dummy_locales:
|
|
85
|
+
- eo
|
|
@@ -5,7 +5,7 @@ import model_utils.fields
|
|
|
5
5
|
import opaque_keys.edx.django.models
|
|
6
6
|
import uuid
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import learning_credentials.models
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Migration(migrations.Migration):
|
|
@@ -39,7 +39,7 @@ class Migration(migrations.Migration):
|
|
|
39
39
|
models.FileField(
|
|
40
40
|
help_text='Asset file. It could be a PDF template, image or font file.',
|
|
41
41
|
max_length=255,
|
|
42
|
-
upload_to=
|
|
42
|
+
upload_to=learning_credentials.models.CredentialAsset.template_assets_path,
|
|
43
43
|
),
|
|
44
44
|
),
|
|
45
45
|
(
|
learning_credentials-0.2.2/learning_credentials/migrations/0002_migrate_to_learning_credentials.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from django.db import migrations
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def migrate_data_if_tables_exist(apps, schema_editor):
|
|
5
|
+
"""Migrate data from openedx_certificates to learning_credentials tables if the source tables exist."""
|
|
6
|
+
connection = schema_editor.connection
|
|
7
|
+
cursor = connection.cursor()
|
|
8
|
+
table_names = connection.introspection.table_names(cursor)
|
|
9
|
+
|
|
10
|
+
tables_to_migrate = [
|
|
11
|
+
(
|
|
12
|
+
"openedx_certificates_externalcertificatetype",
|
|
13
|
+
"learning_credentials_externalcertificatetype",
|
|
14
|
+
"id, created, modified, name, retrieval_func, generation_func, custom_options",
|
|
15
|
+
),
|
|
16
|
+
(
|
|
17
|
+
"openedx_certificates_externalcertificatecourseconfiguration",
|
|
18
|
+
"learning_credentials_externalcertificatecourseconfiguration",
|
|
19
|
+
"id, created, modified, course_id, custom_options, certificate_type_id, periodic_task_id",
|
|
20
|
+
),
|
|
21
|
+
(
|
|
22
|
+
"openedx_certificates_externalcertificateasset",
|
|
23
|
+
"learning_credentials_externalcertificateasset",
|
|
24
|
+
"id, created, modified, description, asset, asset_slug",
|
|
25
|
+
),
|
|
26
|
+
(
|
|
27
|
+
"openedx_certificates_externalcertificate",
|
|
28
|
+
"learning_credentials_externalcertificate",
|
|
29
|
+
"uuid, created, modified, user_id, user_full_name, course_id, certificate_type, status, download_url, legacy_id, generation_task_id",
|
|
30
|
+
),
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
for source_table, target_table, fields in tables_to_migrate:
|
|
34
|
+
if source_table in table_names:
|
|
35
|
+
cursor.execute(f"INSERT INTO {target_table} ({fields}) SELECT {fields} FROM {source_table};")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Migration(migrations.Migration):
|
|
39
|
+
dependencies = [("learning_credentials", "0001_initial")]
|
|
40
|
+
operations = [migrations.RunPython(migrate_data_if_tables_exist, migrations.RunPython.noop)]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Clean up legacy `openedx_certificates` tables.
|
|
2
|
+
|
|
3
|
+
from django.db import migrations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("learning_credentials", "0005_rename_processors_and_generators"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.RunSQL(
|
|
13
|
+
sql=[
|
|
14
|
+
"DROP TABLE IF EXISTS openedx_certificates_externalcertificate;",
|
|
15
|
+
"DROP TABLE IF EXISTS openedx_certificates_externalcertificateasset;",
|
|
16
|
+
"DROP TABLE IF EXISTS openedx_certificates_externalcertificatecourseconfiguration;",
|
|
17
|
+
"DROP TABLE IF EXISTS openedx_certificates_externalcertificatetype;",
|
|
18
|
+
],
|
|
19
|
+
reverse_sql=migrations.RunSQL.noop,
|
|
20
|
+
),
|
|
21
|
+
]
|
|
@@ -106,7 +106,7 @@ class CredentialConfiguration(TimeStampedModel):
|
|
|
106
106
|
|
|
107
107
|
def save(self, *args, **kwargs):
|
|
108
108
|
"""Create a new PeriodicTask every time a new CredentialConfiguration is created."""
|
|
109
|
-
from learning_credentials.tasks import generate_credentials_for_config_task as task #
|
|
109
|
+
from learning_credentials.tasks import generate_credentials_for_config_task as task # noqa: PLC0415
|
|
110
110
|
|
|
111
111
|
# Use __wrapped__ to get the original function, as the task is wrapped by the @app.task decorator.
|
|
112
112
|
task_path = f"{task.__wrapped__.__module__}.{task.__wrapped__.__name__}"
|
{learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/processors.py
RENAMED
|
@@ -45,12 +45,14 @@ def _process_learning_context(
|
|
|
45
45
|
Process a learning context (course or learning path) using the given course processor function.
|
|
46
46
|
|
|
47
47
|
For courses, runs the processor directly. For learning paths, runs the processor on each
|
|
48
|
-
course in the path
|
|
48
|
+
course in the path with step-specific options (if available), and returns the intersection
|
|
49
|
+
of eligible users across all courses.
|
|
49
50
|
|
|
50
51
|
Args:
|
|
51
52
|
learning_context_key: A course key or learning path key to process
|
|
52
53
|
course_processor: A function that processes a single course and returns eligible user IDs
|
|
53
|
-
options: Options to pass to the processor
|
|
54
|
+
options: Options to pass to the processor. For learning paths, may contain a "steps" key
|
|
55
|
+
with step-specific options in the format: {"steps": {"<course_key>": {...}}}
|
|
54
56
|
|
|
55
57
|
Returns:
|
|
56
58
|
A list of eligible user IDs
|
|
@@ -62,7 +64,9 @@ def _process_learning_context(
|
|
|
62
64
|
|
|
63
65
|
results = None
|
|
64
66
|
for course in learning_path.steps.all():
|
|
65
|
-
|
|
67
|
+
course_options = options.get("steps", {}).get(str(course.course_key), options)
|
|
68
|
+
course_results = set(course_processor(course.course_key, course_options))
|
|
69
|
+
|
|
66
70
|
if results is None:
|
|
67
71
|
results = course_results
|
|
68
72
|
else:
|
|
@@ -205,6 +209,28 @@ def retrieve_subsection_grades(learning_context_key: LearningContextKey, options
|
|
|
205
209
|
3. Exam: 70%
|
|
206
210
|
The grades for the Total category will be calculated as follows:
|
|
207
211
|
total_grade = (homework_grade * 0.2) + (lab_grade * 0.1) + (exam_grade * 0.7)
|
|
212
|
+
- steps: For learning paths only. A dictionary with step-specific options in the format
|
|
213
|
+
{"<course_key>": {...}}. If provided, each course in the learning path will use its specific
|
|
214
|
+
options instead of the global options. Example::
|
|
215
|
+
|
|
216
|
+
{
|
|
217
|
+
"required_grades": {
|
|
218
|
+
"Total": 0.8
|
|
219
|
+
},
|
|
220
|
+
"steps": {
|
|
221
|
+
"course-v1:edX+DemoX+Demo_Course": {
|
|
222
|
+
"required_grades": {
|
|
223
|
+
"Total": 0.9
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
"course-v1:edX+CS101+2023": {
|
|
227
|
+
"required_grades": {
|
|
228
|
+
"Homework": 0.5,
|
|
229
|
+
"Total": 0.7
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
208
234
|
"""
|
|
209
235
|
return _process_learning_context(learning_context_key, _retrieve_course_subsection_grades, options)
|
|
210
236
|
|
|
@@ -277,6 +303,21 @@ def retrieve_completions(learning_context_key: LearningContextKey, options: dict
|
|
|
277
303
|
|
|
278
304
|
Options:
|
|
279
305
|
- required_completion: The minimum required completion percentage. The default value is 0.9.
|
|
306
|
+
- steps: For learning paths only. A dictionary with step-specific options in the format
|
|
307
|
+
{"<course_key>": {...}}. If provided, each course in the learning path will use its specific
|
|
308
|
+
options instead of the global options. Example::
|
|
309
|
+
|
|
310
|
+
{
|
|
311
|
+
"required_completion": 0.8,
|
|
312
|
+
"steps": {
|
|
313
|
+
"course-v1:edX+DemoX+Demo_Course": {
|
|
314
|
+
"required_completion": 0.9
|
|
315
|
+
},
|
|
316
|
+
"course-v1:edX+CS101+2023": {
|
|
317
|
+
"required_completion": 0.7
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
280
321
|
"""
|
|
281
322
|
return _process_learning_context(learning_context_key, _retrieve_course_completions, options)
|
|
282
323
|
|
|
@@ -295,8 +336,7 @@ def retrieve_completions_and_grades(learning_context_key: LearningContextKey, op
|
|
|
295
336
|
Options:
|
|
296
337
|
- required_completion: The minimum required completion percentage (default: 0.9)
|
|
297
338
|
- required_grades: A dictionary of required grades for each category, where the keys are the category names and
|
|
298
|
-
the values are the minimum required grades. The grades are percentages in the range [0, 1].
|
|
299
|
-
Example::
|
|
339
|
+
the values are the minimum required grades. The grades are percentages in the range [0, 1]. Example::
|
|
300
340
|
|
|
301
341
|
{
|
|
302
342
|
"required_grades": {
|
|
@@ -305,6 +345,32 @@ def retrieve_completions_and_grades(learning_context_key: LearningContextKey, op
|
|
|
305
345
|
"Total": 0.8
|
|
306
346
|
}
|
|
307
347
|
}
|
|
348
|
+
|
|
349
|
+
- steps: For learning paths only. A dictionary with step-specific options in the format
|
|
350
|
+
{"<course_key>": {...}}. If provided, each course in the learning path will use its specific
|
|
351
|
+
options instead of the global options. Example::
|
|
352
|
+
|
|
353
|
+
{
|
|
354
|
+
"required_completion": 0.8,
|
|
355
|
+
"required_grades": {
|
|
356
|
+
"Total": 0.7
|
|
357
|
+
},
|
|
358
|
+
"steps": {
|
|
359
|
+
"course-v1:edX+DemoX+Demo_Course": {
|
|
360
|
+
"required_completion": 0.9,
|
|
361
|
+
"required_grades": {
|
|
362
|
+
"Total": 0.8
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
"course-v1:edX+CS101+2023": {
|
|
366
|
+
"required_completion": 0.7,
|
|
367
|
+
"required_grades": {
|
|
368
|
+
"Homework": 0.5,
|
|
369
|
+
"Total": 0.6
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
308
374
|
"""
|
|
309
375
|
completion_eligible_users = set(retrieve_completions(learning_context_key, options))
|
|
310
376
|
grades_eligible_users = set(retrieve_subsection_grades(learning_context_key, options))
|
{learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials/settings/common.py
RENAMED
|
@@ -7,6 +7,3 @@ def plugin_settings(settings: Settings):
|
|
|
7
7
|
"""Add `django_celery_beat` to `INSTALLED_APPS`."""
|
|
8
8
|
if 'django_celery_beat' not in settings.INSTALLED_APPS:
|
|
9
9
|
settings.INSTALLED_APPS += ('django_celery_beat',)
|
|
10
|
-
# Temporary app to handle migrations.
|
|
11
|
-
if 'openedx_certificates' not in settings.INSTALLED_APPS:
|
|
12
|
-
settings.INSTALLED_APPS += ('openedx_certificates',)
|
{learning_credentials-0.2.1 → learning_credentials-0.2.2/learning_credentials.egg-info}/PKG-INFO
RENAMED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: learning-credentials
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A pluggable service for preparing Open edX credentials.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
Author-email: OpenCraft <help@opencraft.com>
|
|
6
|
+
License-Expression: AGPL-3.0-or-later
|
|
7
|
+
Project-URL: Homepage, https://github.com/open-craft/learning-credentials
|
|
8
|
+
Project-URL: Repository, https://github.com/open-craft/learning-credentials
|
|
9
|
+
Project-URL: Documentation, https://learning-credentials.readthedocs.io/
|
|
10
|
+
Keywords: Python,edx,credentials,django
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
12
|
Classifier: Framework :: Django
|
|
12
13
|
Classifier: Framework :: Django :: 4.2
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -19,31 +19,20 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
19
19
|
Requires-Python: >=3.11
|
|
20
20
|
Description-Content-Type: text/x-rst
|
|
21
21
|
License-File: LICENSE.txt
|
|
22
|
-
Requires-Dist: celery
|
|
23
22
|
Requires-Dist: django
|
|
24
|
-
Requires-Dist: django-celery-beat
|
|
25
23
|
Requires-Dist: django-model-utils
|
|
26
|
-
Requires-Dist:
|
|
24
|
+
Requires-Dist: edx-opaque-keys
|
|
25
|
+
Requires-Dist: celery
|
|
26
|
+
Requires-Dist: django-celery-beat
|
|
27
27
|
Requires-Dist: django_reverse_admin
|
|
28
28
|
Requires-Dist: djangorestframework
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist: edx_ace
|
|
31
|
-
Requires-Dist: learning-paths-plugin>=0.3.0
|
|
32
|
-
Requires-Dist: openedx-completion-aggregator
|
|
29
|
+
Requires-Dist: django-object-actions
|
|
33
30
|
Requires-Dist: pypdf
|
|
34
31
|
Requires-Dist: reportlab
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Dynamic: description
|
|
39
|
-
Dynamic: description-content-type
|
|
40
|
-
Dynamic: home-page
|
|
41
|
-
Dynamic: keywords
|
|
42
|
-
Dynamic: license
|
|
32
|
+
Requires-Dist: openedx-completion-aggregator
|
|
33
|
+
Requires-Dist: edx_ace
|
|
34
|
+
Requires-Dist: learning-paths-plugin>=0.3.4
|
|
43
35
|
Dynamic: license-file
|
|
44
|
-
Dynamic: requires-dist
|
|
45
|
-
Dynamic: requires-python
|
|
46
|
-
Dynamic: summary
|
|
47
36
|
|
|
48
37
|
learning-credentials
|
|
49
38
|
####################
|
|
@@ -167,7 +156,6 @@ Please do not report security issues in public. Please email security@openedx.or
|
|
|
167
156
|
:target: https://mango-dune-07a8b7110.1.azurestaticapps.net/?repo=open-craft/learning-credentials
|
|
168
157
|
:alt: Visualization
|
|
169
158
|
|
|
170
|
-
|
|
171
159
|
Change Log
|
|
172
160
|
##########
|
|
173
161
|
|
|
@@ -186,6 +174,18 @@ Unreleased
|
|
|
186
174
|
|
|
187
175
|
*
|
|
188
176
|
|
|
177
|
+
0.2.2 - 2025-08-05
|
|
178
|
+
|
|
179
|
+
Added
|
|
180
|
+
=====
|
|
181
|
+
|
|
182
|
+
* Step-specific options support for Learning Path credentials.
|
|
183
|
+
|
|
184
|
+
Removed
|
|
185
|
+
=======
|
|
186
|
+
|
|
187
|
+
* Legacy `openedx_certificates` app.
|
|
188
|
+
|
|
189
189
|
0.2.1 – 2025-05-05
|
|
190
190
|
******************
|
|
191
191
|
|
{learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials.egg-info/SOURCES.txt
RENAMED
|
@@ -3,7 +3,6 @@ LICENSE.txt
|
|
|
3
3
|
MANIFEST.in
|
|
4
4
|
README.rst
|
|
5
5
|
pyproject.toml
|
|
6
|
-
setup.py
|
|
7
6
|
learning_credentials/__init__.py
|
|
8
7
|
learning_credentials/admin.py
|
|
9
8
|
learning_credentials/apps.py
|
|
@@ -19,14 +18,15 @@ learning_credentials.egg-info/PKG-INFO
|
|
|
19
18
|
learning_credentials.egg-info/SOURCES.txt
|
|
20
19
|
learning_credentials.egg-info/dependency_links.txt
|
|
21
20
|
learning_credentials.egg-info/entry_points.txt
|
|
22
|
-
learning_credentials.egg-info/not-zip-safe
|
|
23
21
|
learning_credentials.egg-info/requires.txt
|
|
24
22
|
learning_credentials.egg-info/top_level.txt
|
|
23
|
+
learning_credentials/conf/locale/config.yaml
|
|
25
24
|
learning_credentials/migrations/0001_initial.py
|
|
26
25
|
learning_credentials/migrations/0002_migrate_to_learning_credentials.py
|
|
27
26
|
learning_credentials/migrations/0003_rename_certificates_to_credentials.py
|
|
28
27
|
learning_credentials/migrations/0004_replace_course_keys_with_learning_context_keys.py
|
|
29
28
|
learning_credentials/migrations/0005_rename_processors_and_generators.py
|
|
29
|
+
learning_credentials/migrations/0006_cleanup_openedx_certificates_tables.py
|
|
30
30
|
learning_credentials/migrations/__init__.py
|
|
31
31
|
learning_credentials/settings/__init__.py
|
|
32
32
|
learning_credentials/settings/common.py
|
|
@@ -37,13 +37,6 @@ learning_credentials/templates/learning_credentials/edx_ace/certificate_generate
|
|
|
37
37
|
learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/from_name.txt
|
|
38
38
|
learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/head.html
|
|
39
39
|
learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/subject.txt
|
|
40
|
-
openedx_certificates/__init__.py
|
|
41
|
-
openedx_certificates/apps.py
|
|
42
|
-
openedx_certificates/models.py
|
|
43
|
-
openedx_certificates/migrations/0001_initial.py
|
|
44
|
-
openedx_certificates/migrations/__init__.py
|
|
45
|
-
requirements/base.in
|
|
46
|
-
requirements/constraints.txt
|
|
47
40
|
tests/test_generators.py
|
|
48
41
|
tests/test_models.py
|
|
49
42
|
tests/test_processors.py
|
{learning_credentials-0.2.1 → learning_credentials-0.2.2}/learning_credentials.egg-info/requires.txt
RENAMED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
celery
|
|
2
1
|
django
|
|
3
|
-
django-celery-beat
|
|
4
2
|
django-model-utils
|
|
5
|
-
|
|
3
|
+
edx-opaque-keys
|
|
4
|
+
celery
|
|
5
|
+
django-celery-beat
|
|
6
6
|
django_reverse_admin
|
|
7
7
|
djangorestframework
|
|
8
|
-
|
|
9
|
-
edx_ace
|
|
10
|
-
learning-paths-plugin>=0.3.0
|
|
11
|
-
openedx-completion-aggregator
|
|
8
|
+
django-object-actions
|
|
12
9
|
pypdf
|
|
13
10
|
reportlab
|
|
11
|
+
openedx-completion-aggregator
|
|
12
|
+
edx_ace
|
|
13
|
+
learning-paths-plugin>=0.3.4
|