learning-credentials 0.2.0rc1__py2.py3-none-any.whl
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/__init__.py +3 -0
- learning_credentials/admin.py +263 -0
- learning_credentials/apps.py +24 -0
- learning_credentials/compat.py +117 -0
- learning_credentials/exceptions.py +9 -0
- learning_credentials/generators.py +224 -0
- learning_credentials/migrations/0001_initial.py +205 -0
- learning_credentials/migrations/0002_migrate_to_learning_credentials.py +32 -0
- learning_credentials/migrations/0003_rename_certificates_to_credentials.py +128 -0
- learning_credentials/migrations/0004_replace_course_keys_with_learning_context_keys.py +59 -0
- learning_credentials/migrations/0005_rename_processors_and_generators.py +106 -0
- learning_credentials/migrations/__init__.py +0 -0
- learning_credentials/models.py +381 -0
- learning_credentials/processors.py +306 -0
- learning_credentials/settings/__init__.py +1 -0
- learning_credentials/settings/common.py +12 -0
- learning_credentials/settings/production.py +13 -0
- learning_credentials/tasks.py +53 -0
- learning_credentials/templates/learning_credentials/base.html +22 -0
- learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/body.html +22 -0
- learning_credentials/templates/learning_credentials/edx_ace/certificate_generated/email/head.html +0 -0
- learning_credentials/urls.py +9 -0
- learning_credentials/views.py +1 -0
- learning_credentials-0.2.0rc1.dist-info/METADATA +204 -0
- learning_credentials-0.2.0rc1.dist-info/RECORD +34 -0
- learning_credentials-0.2.0rc1.dist-info/WHEEL +6 -0
- learning_credentials-0.2.0rc1.dist-info/entry_points.txt +3 -0
- learning_credentials-0.2.0rc1.dist-info/licenses/LICENSE.txt +664 -0
- learning_credentials-0.2.0rc1.dist-info/top_level.txt +2 -0
- openedx_certificates/__init__.py +1 -0
- openedx_certificates/apps.py +11 -0
- openedx_certificates/migrations/0001_initial.py +206 -0
- openedx_certificates/migrations/__init__.py +0 -0
- openedx_certificates/models.py +38 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""openedx_certificates Django application initialization."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from django.apps import AppConfig
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OpenedxCertificatesConfig(AppConfig):
|
|
9
|
+
"""Configuration for the openedx_certificates Django application."""
|
|
10
|
+
|
|
11
|
+
name = 'openedx_certificates'
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Generated by Django 3.2.23 on 2023-11-14 15:54
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
import django.db.models.deletion
|
|
5
|
+
import django.utils.timezone
|
|
6
|
+
import jsonfield.fields
|
|
7
|
+
import model_utils.fields
|
|
8
|
+
import opaque_keys.edx.django.models
|
|
9
|
+
import openedx_certificates.models
|
|
10
|
+
import uuid
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Migration(migrations.Migration):
|
|
14
|
+
initial = True
|
|
15
|
+
|
|
16
|
+
dependencies = [
|
|
17
|
+
('django_celery_beat', '0018_improve_crontab_helptext'),
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
operations = [
|
|
21
|
+
migrations.CreateModel(
|
|
22
|
+
name='ExternalCertificateAsset',
|
|
23
|
+
fields=[
|
|
24
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
25
|
+
(
|
|
26
|
+
'created',
|
|
27
|
+
model_utils.fields.AutoCreatedField(
|
|
28
|
+
default=django.utils.timezone.now, editable=False, verbose_name='created'
|
|
29
|
+
),
|
|
30
|
+
),
|
|
31
|
+
(
|
|
32
|
+
'modified',
|
|
33
|
+
model_utils.fields.AutoLastModifiedField(
|
|
34
|
+
default=django.utils.timezone.now, editable=False, verbose_name='modified'
|
|
35
|
+
),
|
|
36
|
+
),
|
|
37
|
+
('description', models.CharField(blank=True, help_text='Description of the asset.', max_length=255)),
|
|
38
|
+
(
|
|
39
|
+
'asset',
|
|
40
|
+
models.FileField(
|
|
41
|
+
help_text='Asset file. It could be a PDF template, image or font file.',
|
|
42
|
+
max_length=255,
|
|
43
|
+
upload_to=openedx_certificates.models.ExternalCertificateAsset.template_assets_path,
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
(
|
|
47
|
+
'asset_slug',
|
|
48
|
+
models.SlugField(
|
|
49
|
+
help_text="Asset's unique slug. We can reference the asset in templates using this value.",
|
|
50
|
+
max_length=255,
|
|
51
|
+
unique=True,
|
|
52
|
+
),
|
|
53
|
+
),
|
|
54
|
+
],
|
|
55
|
+
options={
|
|
56
|
+
'get_latest_by': 'created',
|
|
57
|
+
},
|
|
58
|
+
),
|
|
59
|
+
migrations.CreateModel(
|
|
60
|
+
name='ExternalCertificateType',
|
|
61
|
+
fields=[
|
|
62
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
63
|
+
(
|
|
64
|
+
'created',
|
|
65
|
+
model_utils.fields.AutoCreatedField(
|
|
66
|
+
default=django.utils.timezone.now, editable=False, verbose_name='created'
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
(
|
|
70
|
+
'modified',
|
|
71
|
+
model_utils.fields.AutoLastModifiedField(
|
|
72
|
+
default=django.utils.timezone.now, editable=False, verbose_name='modified'
|
|
73
|
+
),
|
|
74
|
+
),
|
|
75
|
+
('name', models.CharField(help_text='Name of the certificate type.', max_length=255, unique=True)),
|
|
76
|
+
(
|
|
77
|
+
'retrieval_func',
|
|
78
|
+
models.CharField(help_text='A name of the function to retrieve eligible users.', max_length=200),
|
|
79
|
+
),
|
|
80
|
+
(
|
|
81
|
+
'generation_func',
|
|
82
|
+
models.CharField(help_text='A name of the function to generate certificates.', max_length=200),
|
|
83
|
+
),
|
|
84
|
+
(
|
|
85
|
+
'custom_options',
|
|
86
|
+
jsonfield.fields.JSONField(blank=True, default=dict, help_text='Custom options for the functions.'),
|
|
87
|
+
),
|
|
88
|
+
],
|
|
89
|
+
options={
|
|
90
|
+
'abstract': False,
|
|
91
|
+
},
|
|
92
|
+
),
|
|
93
|
+
migrations.CreateModel(
|
|
94
|
+
name='ExternalCertificate',
|
|
95
|
+
fields=[
|
|
96
|
+
(
|
|
97
|
+
'created',
|
|
98
|
+
model_utils.fields.AutoCreatedField(
|
|
99
|
+
default=django.utils.timezone.now, editable=False, verbose_name='created'
|
|
100
|
+
),
|
|
101
|
+
),
|
|
102
|
+
(
|
|
103
|
+
'modified',
|
|
104
|
+
model_utils.fields.AutoLastModifiedField(
|
|
105
|
+
default=django.utils.timezone.now, editable=False, verbose_name='modified'
|
|
106
|
+
),
|
|
107
|
+
),
|
|
108
|
+
(
|
|
109
|
+
'uuid',
|
|
110
|
+
models.UUIDField(
|
|
111
|
+
default=uuid.uuid4,
|
|
112
|
+
editable=False,
|
|
113
|
+
help_text='Auto-generated UUID of the certificate',
|
|
114
|
+
primary_key=True,
|
|
115
|
+
serialize=False,
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
('user_id', models.IntegerField(help_text='ID of the user receiving the certificate')),
|
|
119
|
+
('user_full_name', models.CharField(help_text='User receiving the certificate', max_length=255)),
|
|
120
|
+
(
|
|
121
|
+
'course_id',
|
|
122
|
+
opaque_keys.edx.django.models.CourseKeyField(
|
|
123
|
+
help_text='ID of a course for which the certificate was issued', max_length=255
|
|
124
|
+
),
|
|
125
|
+
),
|
|
126
|
+
('certificate_type', models.CharField(help_text='Type of the certificate', max_length=255)),
|
|
127
|
+
(
|
|
128
|
+
'status',
|
|
129
|
+
models.CharField(
|
|
130
|
+
choices=[
|
|
131
|
+
('generating', 'Generating'),
|
|
132
|
+
('available', 'Available'),
|
|
133
|
+
('error', 'Error'),
|
|
134
|
+
('invalidated', 'Invalidated'),
|
|
135
|
+
],
|
|
136
|
+
default='generating',
|
|
137
|
+
help_text='Status of the certificate generation task',
|
|
138
|
+
max_length=32,
|
|
139
|
+
),
|
|
140
|
+
),
|
|
141
|
+
(
|
|
142
|
+
'download_url',
|
|
143
|
+
models.URLField(blank=True, help_text='URL of the generated certificate PDF (e.g., to S3)'),
|
|
144
|
+
),
|
|
145
|
+
(
|
|
146
|
+
'legacy_id',
|
|
147
|
+
models.IntegerField(
|
|
148
|
+
help_text='Legacy ID of the certificate imported from another system', null=True
|
|
149
|
+
),
|
|
150
|
+
),
|
|
151
|
+
('generation_task_id', models.CharField(help_text='Task ID from the Celery queue', max_length=255)),
|
|
152
|
+
],
|
|
153
|
+
options={
|
|
154
|
+
'unique_together': {('user_id', 'course_id', 'certificate_type')},
|
|
155
|
+
},
|
|
156
|
+
),
|
|
157
|
+
migrations.CreateModel(
|
|
158
|
+
name='ExternalCertificateCourseConfiguration',
|
|
159
|
+
fields=[
|
|
160
|
+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
161
|
+
(
|
|
162
|
+
'created',
|
|
163
|
+
model_utils.fields.AutoCreatedField(
|
|
164
|
+
default=django.utils.timezone.now, editable=False, verbose_name='created'
|
|
165
|
+
),
|
|
166
|
+
),
|
|
167
|
+
(
|
|
168
|
+
'modified',
|
|
169
|
+
model_utils.fields.AutoLastModifiedField(
|
|
170
|
+
default=django.utils.timezone.now, editable=False, verbose_name='modified'
|
|
171
|
+
),
|
|
172
|
+
),
|
|
173
|
+
(
|
|
174
|
+
'course_id',
|
|
175
|
+
opaque_keys.edx.django.models.CourseKeyField(help_text='The ID of the course.', max_length=255),
|
|
176
|
+
),
|
|
177
|
+
(
|
|
178
|
+
'custom_options',
|
|
179
|
+
jsonfield.fields.JSONField(
|
|
180
|
+
blank=True,
|
|
181
|
+
default=dict,
|
|
182
|
+
help_text='Custom options for the functions. If specified, they are merged with the options defined in the certificate type.',
|
|
183
|
+
),
|
|
184
|
+
),
|
|
185
|
+
(
|
|
186
|
+
'certificate_type',
|
|
187
|
+
models.ForeignKey(
|
|
188
|
+
help_text='Associated certificate type.',
|
|
189
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
190
|
+
to='openedx_certificates.externalcertificatetype',
|
|
191
|
+
),
|
|
192
|
+
),
|
|
193
|
+
(
|
|
194
|
+
'periodic_task',
|
|
195
|
+
models.OneToOneField(
|
|
196
|
+
help_text='Associated periodic task.',
|
|
197
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
198
|
+
to='django_celery_beat.periodictask',
|
|
199
|
+
),
|
|
200
|
+
),
|
|
201
|
+
],
|
|
202
|
+
options={
|
|
203
|
+
'unique_together': {('course_id', 'certificate_type')},
|
|
204
|
+
},
|
|
205
|
+
),
|
|
206
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Proxy models for backward compatibility with the old app structure.
|
|
3
|
+
|
|
4
|
+
These will redirect to the new models in learning_credentials.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from learning_credentials.models import Credential as LearningCredential
|
|
8
|
+
from learning_credentials.models import CredentialAsset as LearningCredentialAsset
|
|
9
|
+
from learning_credentials.models import CredentialConfiguration as LearningCredentialConfiguration
|
|
10
|
+
from learning_credentials.models import CredentialType as LearningCredentialType
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ExternalCertificate(LearningCredential):
|
|
14
|
+
"""Proxy model for backward compatibility."""
|
|
15
|
+
|
|
16
|
+
class Meta: # noqa: D106
|
|
17
|
+
proxy = True
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ExternalCertificateAsset(LearningCredentialAsset):
|
|
21
|
+
"""Proxy model for backward compatibility."""
|
|
22
|
+
|
|
23
|
+
class Meta: # noqa: D106
|
|
24
|
+
proxy = True
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ExternalCertificateType(LearningCredentialType):
|
|
28
|
+
"""Proxy model for backward compatibility."""
|
|
29
|
+
|
|
30
|
+
class Meta: # noqa: D106
|
|
31
|
+
proxy = True
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ExternalCertificateCourseConfiguration(LearningCredentialConfiguration):
|
|
35
|
+
"""Proxy model for backward compatibility."""
|
|
36
|
+
|
|
37
|
+
class Meta: # noqa: D106
|
|
38
|
+
proxy = True
|