openedx-webhooks 22.0.0__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.
- openedx_webhooks/__init__.py +7 -0
- openedx_webhooks/admin.py +40 -0
- openedx_webhooks/apps.py +130 -0
- openedx_webhooks/filters.py +2276 -0
- openedx_webhooks/migrations/0001_initial.py +30 -0
- openedx_webhooks/migrations/0002_webfilter.py +37 -0
- openedx_webhooks/migrations/0003_auto_20230607_1246.py +23 -0
- openedx_webhooks/migrations/0004_auto_20230613_1033.py +28 -0
- openedx_webhooks/migrations/0005_alter_webfilter_event.py +18 -0
- openedx_webhooks/migrations/0006_alter_webfilter_event.py +18 -0
- openedx_webhooks/migrations/0007_alter_webfilter_event.py +18 -0
- openedx_webhooks/migrations/0008_verawood.py +51 -0
- openedx_webhooks/migrations/__init__.py +0 -0
- openedx_webhooks/models.py +185 -0
- openedx_webhooks/receivers.py +434 -0
- openedx_webhooks/settings/__init__.py +0 -0
- openedx_webhooks/settings/cms.py +21 -0
- openedx_webhooks/settings/common.py +191 -0
- openedx_webhooks/settings/test.py +10 -0
- openedx_webhooks/urls.py +10 -0
- openedx_webhooks/utils.py +124 -0
- openedx_webhooks-22.0.0.dist-info/METADATA +415 -0
- openedx_webhooks-22.0.0.dist-info/RECORD +27 -0
- openedx_webhooks-22.0.0.dist-info/WHEEL +5 -0
- openedx_webhooks-22.0.0.dist-info/entry_points.txt +5 -0
- openedx_webhooks-22.0.0.dist-info/licenses/LICENSE.txt +674 -0
- openedx_webhooks-22.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Open edX signal events handler functions.
|
|
3
|
+
"""
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
from attrs import asdict
|
|
8
|
+
|
|
9
|
+
from .models import Webhook
|
|
10
|
+
from .utils import send, value_serializer
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _process_event(event_name, data, **kwargs):
|
|
16
|
+
"""
|
|
17
|
+
Process all events with user data.
|
|
18
|
+
"""
|
|
19
|
+
logger.debug(f"Processing event: {event_name}")
|
|
20
|
+
webhooks = Webhook.objects.filter(enabled=True, event=event_name).order_by('pk')
|
|
21
|
+
|
|
22
|
+
# Get the name of the data type
|
|
23
|
+
data_type = f"{type(data).__module__}.{type(data).__qualname__}"
|
|
24
|
+
|
|
25
|
+
for webhook in webhooks:
|
|
26
|
+
logger.info(f"{event_name} webhook triggered to {webhook.webhook_url}")
|
|
27
|
+
|
|
28
|
+
payload = {
|
|
29
|
+
data_type: asdict(data, value_serializer=value_serializer),
|
|
30
|
+
'event_metadata': (
|
|
31
|
+
asdict(kwargs["metadata"])
|
|
32
|
+
if kwargs.get("metadata") is not None else {}
|
|
33
|
+
),
|
|
34
|
+
}
|
|
35
|
+
try:
|
|
36
|
+
response = send(
|
|
37
|
+
webhook.webhook_url,
|
|
38
|
+
payload,
|
|
39
|
+
www_form_urlencoded=webhook.use_www_form_encoding,
|
|
40
|
+
)
|
|
41
|
+
response.raise_for_status()
|
|
42
|
+
except requests.exceptions.RequestException as exc:
|
|
43
|
+
logger.warning(
|
|
44
|
+
"Webhook delivery failed for %s (configuration %s): %s: %s",
|
|
45
|
+
event_name, webhook.pk, type(exc).__name__, exc,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def role_assignment_created_receiver(role_assignment, **kwargs):
|
|
50
|
+
"""Handle ROLE_ASSIGNMENT_CREATED in both LMS and Studio."""
|
|
51
|
+
_process_event("ROLE_ASSIGNMENT_CREATED", role_assignment, **kwargs)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def role_assignment_deleted_receiver(role_assignment, **kwargs):
|
|
55
|
+
"""Handle ROLE_ASSIGNMENT_DELETED in both LMS and Studio."""
|
|
56
|
+
_process_event("ROLE_ASSIGNMENT_DELETED", role_assignment, **kwargs)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def session_login_completed_receiver(user, **kwargs):
|
|
60
|
+
"""
|
|
61
|
+
Handle SESSION_LOGIN_COMPLETED signal.
|
|
62
|
+
|
|
63
|
+
Example of data sent:
|
|
64
|
+
user_id: 4
|
|
65
|
+
user_is_active: True
|
|
66
|
+
user_pii_username: andres
|
|
67
|
+
user_pii_email: andres@aulasneo.com
|
|
68
|
+
user_pii_name: (empty)
|
|
69
|
+
event_metadata_id: 457f0c26-a1a5-11ed-afe6-0242ac140007
|
|
70
|
+
event_metadata_event_type: org.openedx.learning.auth.session.login.completed.v1
|
|
71
|
+
event_metadata_minorversion: 0
|
|
72
|
+
event_metadata_source: openedx/lms/web
|
|
73
|
+
event_metadata_sourcehost: 8616aa50f067
|
|
74
|
+
event_metadata_time: 2023-01-31 20:24:32.598387
|
|
75
|
+
event_metadata_sourcelib: (0, 8, 1)
|
|
76
|
+
"""
|
|
77
|
+
_process_event("SESSION_LOGIN_COMPLETED", user, **kwargs)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def student_registration_completed_receiver(user, **kwargs):
|
|
81
|
+
"""
|
|
82
|
+
Handle STUDENT_REGISTRATION_COMPLETED signal.
|
|
83
|
+
"""
|
|
84
|
+
_process_event("STUDENT_REGISTRATION_COMPLETED", user, **kwargs)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def course_enrollment_created_receiver(enrollment, **kwargs):
|
|
88
|
+
"""
|
|
89
|
+
Handle COURSE_ENROLLMENT_CREATED signal.
|
|
90
|
+
|
|
91
|
+
Example of data sent:
|
|
92
|
+
enrollment_user_id: 4
|
|
93
|
+
enrollment_user_is_active: True
|
|
94
|
+
enrollment_user_pii_username: andres
|
|
95
|
+
enrollment_user_pii_email: andres@aulasneo.com
|
|
96
|
+
enrollment_user_pii_name: (empty)
|
|
97
|
+
enrollment_course_course_key: course-v1:edX+DemoX+Demo_Course
|
|
98
|
+
enrollment_course_display_name: Demonstration Course
|
|
99
|
+
enrollment_course_start: None
|
|
100
|
+
enrollment_course_end; None
|
|
101
|
+
enrollment_mode: honor
|
|
102
|
+
enrollment_is_active: True
|
|
103
|
+
enrollment_creation_date: 2023-01-31 20:28:10.976084+00:00
|
|
104
|
+
enrollment_created_by: None
|
|
105
|
+
event_metadata_id: c8bee32c-a1a5-11ed-baf0-0242ac140007
|
|
106
|
+
event_metadata_event_type: org.openedx.learning.course.enrollment.created.v1
|
|
107
|
+
event_metadata_minorversio: 0
|
|
108
|
+
event_metadata_source: openedx/lms/web
|
|
109
|
+
event_metadata_sourcehost: 8616aa50f067
|
|
110
|
+
event_metadata_time: 2023-01-31 20:28:12.798285
|
|
111
|
+
event_metadata_sourcelib: (0, 8, 1)
|
|
112
|
+
"""
|
|
113
|
+
_process_event("COURSE_ENROLLMENT_CREATED", enrollment, **kwargs)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def course_enrollment_changed_receiver(enrollment, **kwargs):
|
|
117
|
+
"""
|
|
118
|
+
Handle COURSE_ENROLLMENT_CHANGED signal.
|
|
119
|
+
"""
|
|
120
|
+
_process_event("COURSE_ENROLLMENT_CHANGED", enrollment, **kwargs)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def course_unenrollment_completed_receiver(enrollment, **kwargs):
|
|
124
|
+
"""
|
|
125
|
+
Handle COURSE_UNENROLLMENT_COMPLETED signal.
|
|
126
|
+
"""
|
|
127
|
+
_process_event("COURSE_UNENROLLMENT_COMPLETED", enrollment, **kwargs)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def certificate_created_receiver(certificate, **kwargs):
|
|
131
|
+
"""
|
|
132
|
+
Handle CERTIFICATE_CREATED signal.
|
|
133
|
+
"""
|
|
134
|
+
_process_event("CERTIFICATE_CREATED", certificate, **kwargs)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def certificate_changed_receiver(certificate, **kwargs):
|
|
138
|
+
"""
|
|
139
|
+
Handle CERTIFICATE_CHANGED signal.
|
|
140
|
+
"""
|
|
141
|
+
_process_event("CERTIFICATE_CHANGED", certificate, **kwargs)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def certificate_revoked_receiver(certificate, **kwargs):
|
|
145
|
+
"""
|
|
146
|
+
Handle CERTIFICATE_REVOKED signal.
|
|
147
|
+
"""
|
|
148
|
+
_process_event("CERTIFICATE_REVOKED", certificate, **kwargs)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def cohort_membership_changed_receiver(cohort, **kwargs):
|
|
152
|
+
"""
|
|
153
|
+
Handle COHORT_MEMBERSHIP_CHANGED signal.
|
|
154
|
+
"""
|
|
155
|
+
_process_event("COHORT_MEMBERSHIP_CHANGED", cohort, **kwargs)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def course_discussions_changed_receiver(configuration, **kwargs):
|
|
159
|
+
"""
|
|
160
|
+
Handle COURSE_DISCUSSIONS_CHANGED signal.
|
|
161
|
+
"""
|
|
162
|
+
_process_event("COURSE_DISCUSSIONS_CHANGED", configuration, **kwargs)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def program_certificate_awarded_receiver(program_certificate, **kwargs):
|
|
166
|
+
"""Handle PROGRAM_CERTIFICATE_AWARDED signal."""
|
|
167
|
+
_process_event("PROGRAM_CERTIFICATE_AWARDED", program_certificate, **kwargs)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def program_certificate_revoked_receiver(program_certificate, **kwargs):
|
|
171
|
+
"""Handle PROGRAM_CERTIFICATE_REVOKED signal."""
|
|
172
|
+
_process_event("PROGRAM_CERTIFICATE_REVOKED", program_certificate, **kwargs)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def persistent_grade_summary_changed_receiver(grade, **kwargs):
|
|
176
|
+
"""Handle PERSISTENT_GRADE_SUMMARY_CHANGED signal."""
|
|
177
|
+
_process_event("PERSISTENT_GRADE_SUMMARY_CHANGED", grade, **kwargs)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def xblock_skill_verified_receiver(xblock_info, **kwargs):
|
|
181
|
+
"""Handle XBLOCK_SKILL_VERIFIED signal."""
|
|
182
|
+
_process_event("XBLOCK_SKILL_VERIFIED", xblock_info, **kwargs)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def user_notification_requested_receiver(notification_data, **kwargs):
|
|
186
|
+
"""Handle USER_NOTIFICATION_REQUESTED signal."""
|
|
187
|
+
_process_event("USER_NOTIFICATION_REQUESTED", notification_data, **kwargs)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def exam_attempt_submitted_receiver(exam_attempt, **kwargs):
|
|
191
|
+
"""Handle EXAM_ATTEMPT_SUBMITTED signal."""
|
|
192
|
+
_process_event("EXAM_ATTEMPT_SUBMITTED", exam_attempt, **kwargs)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def exam_attempt_rejected_receiver(exam_attempt, **kwargs):
|
|
196
|
+
"""Handle EXAM_ATTEMPT_REJECTED signal."""
|
|
197
|
+
_process_event("EXAM_ATTEMPT_REJECTED", exam_attempt, **kwargs)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def exam_attempt_verified_receiver(exam_attempt, **kwargs):
|
|
201
|
+
"""Handle EXAM_ATTEMPT_VERIFIED signal."""
|
|
202
|
+
_process_event("EXAM_ATTEMPT_VERIFIED", exam_attempt, **kwargs)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def exam_attempt_errored_receiver(exam_attempt, **kwargs):
|
|
206
|
+
"""Handle EXAM_ATTEMPT_ERRORED signal."""
|
|
207
|
+
_process_event("EXAM_ATTEMPT_ERRORED", exam_attempt, **kwargs)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def exam_attempt_reset_receiver(exam_attempt, **kwargs):
|
|
211
|
+
"""Handle EXAM_ATTEMPT_RESET signal."""
|
|
212
|
+
_process_event("EXAM_ATTEMPT_RESET", exam_attempt, **kwargs)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def course_access_role_added_receiver(course_access_role_data, **kwargs):
|
|
216
|
+
"""Handle COURSE_ACCESS_ROLE_ADDED signal."""
|
|
217
|
+
_process_event("COURSE_ACCESS_ROLE_ADDED", course_access_role_data, **kwargs)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def course_access_role_removed_receiver(course_access_role_data, **kwargs):
|
|
221
|
+
"""Handle COURSE_ACCESS_ROLE_REMOVED signal."""
|
|
222
|
+
_process_event("COURSE_ACCESS_ROLE_REMOVED", course_access_role_data, **kwargs)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def forum_thread_created_receiver(thread, **kwargs):
|
|
226
|
+
"""Handle FORUM_THREAD_CREATED signal."""
|
|
227
|
+
_process_event("FORUM_THREAD_CREATED", thread, **kwargs)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def forum_thread_response_created_receiver(thread, **kwargs):
|
|
231
|
+
"""Handle FORUM_THREAD_RESPONSE_CREATED signal."""
|
|
232
|
+
_process_event("FORUM_THREAD_RESPONSE_CREATED", thread, **kwargs)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def forum_response_comment_created_receiver(thread, **kwargs):
|
|
236
|
+
"""Handle FORUM_RESPONSE_COMMENT_CREATED signal."""
|
|
237
|
+
_process_event("FORUM_RESPONSE_COMMENT_CREATED", thread, **kwargs)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def course_notification_requested_receiver(course_notification_data, **kwargs):
|
|
241
|
+
"""Handle COURSE_NOTIFICATION_REQUESTED signal."""
|
|
242
|
+
_process_event("COURSE_NOTIFICATION_REQUESTED", course_notification_data, **kwargs)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def ora_submission_created_receiver(submission, **kwargs):
|
|
246
|
+
"""Handle ORA_SUBMISSION_CREATED signal."""
|
|
247
|
+
_process_event("ORA_SUBMISSION_CREATED", submission, **kwargs)
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def course_passing_status_updated_receiver(course_passing_status, **kwargs):
|
|
251
|
+
"""Handle COURSE_PASSING_STATUS_UPDATED signal."""
|
|
252
|
+
_process_event("COURSE_PASSING_STATUS_UPDATED", course_passing_status, **kwargs)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def ccx_course_passing_status_updated_receiver(course_passing_status, **kwargs):
|
|
256
|
+
"""Handle CCX_COURSE_PASSING_STATUS_UPDATED signal."""
|
|
257
|
+
_process_event("CCX_COURSE_PASSING_STATUS_UPDATED", course_passing_status, **kwargs)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def badge_awarded_receiver(badge, **kwargs):
|
|
261
|
+
"""Handle BADGE_AWARDED signal."""
|
|
262
|
+
_process_event("BADGE_AWARDED", badge, **kwargs)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def badge_revoked_receiver(badge, **kwargs):
|
|
266
|
+
"""Handle BADGE_REVOKED signal."""
|
|
267
|
+
_process_event("BADGE_REVOKED", badge, **kwargs)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def idv_attempt_created_receiver(idv_attempt, **kwargs):
|
|
271
|
+
"""Handle IDV_ATTEMPT_CREATED signal."""
|
|
272
|
+
_process_event("IDV_ATTEMPT_CREATED", idv_attempt, **kwargs)
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def idv_attempt_pending_receiver(idv_attempt, **kwargs):
|
|
276
|
+
"""Handle IDV_ATTEMPT_PENDING signal."""
|
|
277
|
+
_process_event("IDV_ATTEMPT_PENDING", idv_attempt, **kwargs)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def idv_attempt_approved_receiver(idv_attempt, **kwargs):
|
|
281
|
+
"""Handle IDV_ATTEMPT_APPROVED signal."""
|
|
282
|
+
_process_event("IDV_ATTEMPT_APPROVED", idv_attempt, **kwargs)
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def idv_attempt_denied_receiver(idv_attempt, **kwargs):
|
|
286
|
+
"""Handle IDV_ATTEMPT_DENIED signal."""
|
|
287
|
+
_process_event("IDV_ATTEMPT_DENIED", idv_attempt, **kwargs)
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def external_grader_score_submitted_receiver(score, **kwargs):
|
|
291
|
+
"""Handle EXTERNAL_GRADER_SCORE_SUBMITTED signal."""
|
|
292
|
+
_process_event("EXTERNAL_GRADER_SCORE_SUBMITTED", score, **kwargs)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
def lti_provider_launch_success_receiver(launch_data, **kwargs):
|
|
296
|
+
"""Handle LTI_PROVIDER_LAUNCH_SUCCESS signal."""
|
|
297
|
+
_process_event("LTI_PROVIDER_LAUNCH_SUCCESS", launch_data, **kwargs)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
#
|
|
301
|
+
# Course authoring
|
|
302
|
+
def course_catalog_info_changed_receiver(catalog_info, **kwargs):
|
|
303
|
+
"""Handle COURSE_CATALOG_INFO_CHANGED signal."""
|
|
304
|
+
_process_event("COURSE_CATALOG_INFO_CHANGED", catalog_info, **kwargs)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def xblock_created_receiver(xblock_info, **kwargs):
|
|
308
|
+
"""Handle XBLOCK_CREATED signal."""
|
|
309
|
+
_process_event("XBLOCK_CREATED", xblock_info, **kwargs)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def xblock_updated_receiver(xblock_info, **kwargs):
|
|
313
|
+
"""Handle XBLOCK_UPDATED signal."""
|
|
314
|
+
_process_event("XBLOCK_UPDATED", xblock_info, **kwargs)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def xblock_published_receiver(xblock_info, **kwargs):
|
|
318
|
+
"""Handle XBLOCK_PUBLISHED signal."""
|
|
319
|
+
_process_event("XBLOCK_PUBLISHED", xblock_info, **kwargs)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def xblock_deleted_receiver(xblock_info, **kwargs):
|
|
323
|
+
"""Handle XBLOCK_DELETED signal."""
|
|
324
|
+
_process_event("XBLOCK_DELETED", xblock_info, **kwargs)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def xblock_duplicated_receiver(xblock_info, **kwargs):
|
|
328
|
+
"""Handle XBLOCK_DUPLICATED signal."""
|
|
329
|
+
_process_event("XBLOCK_DUPLICATED", xblock_info, **kwargs)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def course_certificate_config_changed_receiver(certificate_config, **kwargs):
|
|
333
|
+
"""Handle COURSE_CERTIFICATE_CONFIG_CHANGED signal."""
|
|
334
|
+
_process_event("COURSE_CERTIFICATE_CONFIG_CHANGED", certificate_config, **kwargs)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def course_certificate_config_deleted_receiver(certificate_config, **kwargs):
|
|
338
|
+
"""Handle COURSE_CERTIFICATE_CONFIG_DELETED signal."""
|
|
339
|
+
_process_event("COURSE_CERTIFICATE_CONFIG_DELETED", certificate_config, **kwargs)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def course_created_receiver(course, **kwargs):
|
|
343
|
+
"""Handle COURSE_CREATED signal."""
|
|
344
|
+
_process_event("COURSE_CREATED", course, **kwargs)
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def content_library_created_receiver(content_library, **kwargs):
|
|
348
|
+
"""Handle CONTENT_LIBRARY_CREATED signal."""
|
|
349
|
+
_process_event("CONTENT_LIBRARY_CREATED", content_library, **kwargs)
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def content_library_updated_receiver(content_library, **kwargs):
|
|
353
|
+
"""Handle CONTENT_LIBRARY_UPDATED signal."""
|
|
354
|
+
_process_event("CONTENT_LIBRARY_UPDATED", content_library, **kwargs)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def content_library_deleted_receiver(content_library, **kwargs):
|
|
358
|
+
"""Handle CONTENT_LIBRARY_DELETED signal."""
|
|
359
|
+
_process_event("CONTENT_LIBRARY_DELETED", content_library, **kwargs)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def library_block_created_receiver(library_block, **kwargs):
|
|
363
|
+
"""Handle LIBRARY_BLOCK_CREATED signal."""
|
|
364
|
+
_process_event("LIBRARY_BLOCK_CREATED", library_block, **kwargs)
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def library_block_updated_receiver(library_block, **kwargs):
|
|
368
|
+
"""Handle LIBRARY_BLOCK_UPDATED signal."""
|
|
369
|
+
_process_event("LIBRARY_BLOCK_UPDATED", library_block, **kwargs)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def library_block_deleted_receiver(library_block, **kwargs):
|
|
373
|
+
"""Handle LIBRARY_BLOCK_DELETED signal."""
|
|
374
|
+
_process_event("LIBRARY_BLOCK_DELETED", library_block, **kwargs)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def library_block_published_receiver(library_block, **kwargs):
|
|
378
|
+
"""Handle LIBRARY_BLOCK_PUBLISHED signal."""
|
|
379
|
+
_process_event("LIBRARY_BLOCK_PUBLISHED", library_block, **kwargs)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def content_object_associations_changed_receiver(content_object, **kwargs):
|
|
383
|
+
"""Handle CONTENT_OBJECT_ASSOCIATIONS_CHANGED signal."""
|
|
384
|
+
_process_event("CONTENT_OBJECT_ASSOCIATIONS_CHANGED", content_object, **kwargs)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def content_object_tags_changed_receiver(content_object, **kwargs):
|
|
388
|
+
"""Handle CONTENT_OBJECT_TAGS_CHANGED signal."""
|
|
389
|
+
_process_event("CONTENT_OBJECT_TAGS_CHANGED", content_object, **kwargs)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def library_collection_created_receiver(library_collection, **kwargs):
|
|
393
|
+
"""Handle LIBRARY_COLLECTION_CREATED signal."""
|
|
394
|
+
_process_event("LIBRARY_COLLECTION_CREATED", library_collection, **kwargs)
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def library_collection_updated_receiver(library_collection, **kwargs):
|
|
398
|
+
"""Handle LIBRARY_COLLECTION_UPDATED signal."""
|
|
399
|
+
_process_event("LIBRARY_COLLECTION_UPDATED", library_collection, **kwargs)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def library_collection_deleted_receiver(library_collection, **kwargs):
|
|
403
|
+
"""Handle LIBRARY_COLLECTION_DELETED signal."""
|
|
404
|
+
_process_event("LIBRARY_COLLECTION_DELETED", library_collection, **kwargs)
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
def library_container_created_receiver(library_container, **kwargs):
|
|
408
|
+
"""Handle LIBRARY_CONTAINER_CREATED signal."""
|
|
409
|
+
_process_event("LIBRARY_CONTAINER_CREATED", library_container, **kwargs)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def library_container_updated_receiver(library_container, **kwargs):
|
|
413
|
+
"""Handle LIBRARY_CONTAINER_UPDATED signal."""
|
|
414
|
+
_process_event("LIBRARY_CONTAINER_UPDATED", library_container, **kwargs)
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def library_container_deleted_receiver(library_container, **kwargs):
|
|
418
|
+
"""Handle LIBRARY_CONTAINER_DELETED signal."""
|
|
419
|
+
_process_event("LIBRARY_CONTAINER_DELETED", library_container, **kwargs)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def library_container_published_receiver(library_container, **kwargs):
|
|
423
|
+
"""Handle LIBRARY_CONTAINER_PUBLISHED signal."""
|
|
424
|
+
_process_event("LIBRARY_CONTAINER_PUBLISHED", library_container, **kwargs)
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def course_import_completed_receiver(course, **kwargs):
|
|
428
|
+
"""Handle COURSE_IMPORT_COMPLETED signal."""
|
|
429
|
+
_process_event("COURSE_IMPORT_COMPLETED", course, **kwargs)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
def course_rerun_completed_receiver(course, **kwargs):
|
|
433
|
+
"""Handle COURSE_RERUN_COMPLETED signal."""
|
|
434
|
+
_process_event("COURSE_RERUN_COMPLETED", course, **kwargs)
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CMS Pluggable Django App settings.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .common import merge_filters
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def plugin_settings(settings):
|
|
9
|
+
"""
|
|
10
|
+
Declare CMS-safe filters and their handlers.
|
|
11
|
+
"""
|
|
12
|
+
filters_config = {
|
|
13
|
+
"org.openedx.content_authoring.lms.page.url.requested.v1": {
|
|
14
|
+
"fail_silently": False,
|
|
15
|
+
"pipeline": [
|
|
16
|
+
"openedx_webhooks.filters.LMSPageURLRequestedWebFilter"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
merge_filters(settings, filters_config)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""
|
|
3
|
+
Common Pluggable Django App settings.
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def plugin_settings(settings):
|
|
9
|
+
"""
|
|
10
|
+
Declare all filters and their handlers.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
filters_config = {
|
|
14
|
+
"org.openedx.learning.student.login.requested.v1": {
|
|
15
|
+
"fail_silently": False,
|
|
16
|
+
"pipeline": [
|
|
17
|
+
"openedx_webhooks.filters.StudentLoginRequestedWebFilter"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"org.openedx.learning.student.registration.requested.v1": {
|
|
21
|
+
"fail_silently": False,
|
|
22
|
+
"pipeline": [
|
|
23
|
+
"openedx_webhooks.filters.StudentRegistrationRequestedWebFilter"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"org.openedx.learning.student.settings.render.started.v1": {
|
|
27
|
+
"fail_silently": False,
|
|
28
|
+
"pipeline": [
|
|
29
|
+
"openedx_webhooks.filters.AccountSettingsRenderStartedWebFilter"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"org.openedx.learning.course.enrollment.started.v1": {
|
|
33
|
+
"fail_silently": False,
|
|
34
|
+
"pipeline": [
|
|
35
|
+
"openedx_webhooks.filters.CourseEnrollmentStartedWebFilter"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"org.openedx.learning.course.unenrollment.started.v1": {
|
|
39
|
+
"fail_silently": False,
|
|
40
|
+
"pipeline": [
|
|
41
|
+
"openedx_webhooks.filters.CourseUnenrollmentStartedWebFilter"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"org.openedx.learning.certificate.creation.requested.v1": {
|
|
45
|
+
"fail_silently": False,
|
|
46
|
+
"pipeline": [
|
|
47
|
+
"openedx_webhooks.filters.CertificateCreationRequestedWebFilter"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"org.openedx.learning.certificate.render.started.v1": {
|
|
51
|
+
"fail_silently": False,
|
|
52
|
+
"pipeline": [
|
|
53
|
+
"openedx_webhooks.filters.CertificateRenderStartedWebFilter"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"org.openedx.learning.cohort.change.requested.v1": {
|
|
57
|
+
"fail_silently": False,
|
|
58
|
+
"pipeline": [
|
|
59
|
+
"openedx_webhooks.filters.CohortChangeRequestedWebFilter"
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
"org.openedx.learning.cohort.assignment.requested.v1": {
|
|
63
|
+
"fail_silently": False,
|
|
64
|
+
"pipeline": [
|
|
65
|
+
"openedx_webhooks.filters.CohortAssignmentRequestedWebFilter"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"org.openedx.learning.course_about.render.started.v1": {
|
|
69
|
+
"fail_silently": False,
|
|
70
|
+
"pipeline": [
|
|
71
|
+
"openedx_webhooks.filters.CourseAboutRenderStartedWebFilter"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
"org.openedx.learning.dashboard.render.started.v1": {
|
|
75
|
+
"fail_silently": False,
|
|
76
|
+
"pipeline": [
|
|
77
|
+
"openedx_webhooks.filters.DashboardRenderStartedWebFilter"
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
"org.openedx.learning.vertical_block_child.render.started.v1": {
|
|
82
|
+
"fail_silently": False,
|
|
83
|
+
"pipeline": [
|
|
84
|
+
"openedx_webhooks.filters.VerticalBlockChildRenderStartedWebFilter"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"org.openedx.learning.course_enrollment_queryset.requested.v1": {
|
|
88
|
+
"fail_silently": False,
|
|
89
|
+
"pipeline": [
|
|
90
|
+
"openedx_webhooks.filters.CourseEnrollmentQuerysetRequestedWebFilter"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"org.openedx.learning.xblock.render.started.v1": {
|
|
94
|
+
"fail_silently": False,
|
|
95
|
+
"pipeline": [
|
|
96
|
+
"openedx_webhooks.filters.RenderXBlockStartedWebFilter"
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"org.openedx.learning.vertical_block.render.completed.v1": {
|
|
100
|
+
"fail_silently": False,
|
|
101
|
+
"pipeline": [
|
|
102
|
+
"openedx_webhooks.filters.VerticalBlockRenderCompletedWebFilter"
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
"org.openedx.learning.course.homepage.url.creation.started.v1": {
|
|
106
|
+
"fail_silently": False,
|
|
107
|
+
"pipeline": [
|
|
108
|
+
"openedx_webhooks.filters.CourseHomeUrlCreationStartedWebFilter"
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
"org.openedx.learning.home.enrollment.api.rendered.v1": {
|
|
112
|
+
"fail_silently": False,
|
|
113
|
+
"pipeline": [
|
|
114
|
+
"openedx_webhooks.filters.CourseEnrollmentAPIRenderStartedWebFilter"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
"org.openedx.learning.home.courserun.api.rendered.started.v1": {
|
|
118
|
+
"fail_silently": False,
|
|
119
|
+
"pipeline": [
|
|
120
|
+
"openedx_webhooks.filters.CourseRunAPIRenderStartedWebFilter"
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"org.openedx.learning.instructor.dashboard.render.started.v1": {
|
|
124
|
+
"fail_silently": False,
|
|
125
|
+
"pipeline": [
|
|
126
|
+
"openedx_webhooks.filters.InstructorDashboardRenderStartedWebFilter"
|
|
127
|
+
]
|
|
128
|
+
},
|
|
129
|
+
"org.openedx.learning.ora.submission_view.render.started.v1": {
|
|
130
|
+
"fail_silently": False,
|
|
131
|
+
"pipeline": [
|
|
132
|
+
"openedx_webhooks.filters.ORASubmissionViewRenderStartedWebFilter"
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
"org.openedx.learning.idv.page.url.requested.v1": {
|
|
136
|
+
"fail_silently": False,
|
|
137
|
+
"pipeline": [
|
|
138
|
+
"openedx_webhooks.filters.IDVPageURLRequestedWebFilter"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
"org.openedx.learning.course_about.page.url.requested.v1": {
|
|
142
|
+
"fail_silently": False,
|
|
143
|
+
"pipeline": [
|
|
144
|
+
"openedx_webhooks.filters.CourseAboutPageURLRequestedWebFilter"
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
"org.openedx.learning.schedule.queryset.requested.v1": {
|
|
148
|
+
"fail_silently": False,
|
|
149
|
+
"pipeline": [
|
|
150
|
+
"openedx_webhooks.filters.ScheduleQuerySetRequestedWebFilter"
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
"org.openedx.content_authoring.lms.page.url.requested.v1": {
|
|
154
|
+
"fail_silently": False,
|
|
155
|
+
"pipeline": [
|
|
156
|
+
"openedx_webhooks.filters.LMSPageURLRequestedWebFilter"
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
"org.openedx.learning.instructor.dashboard.tabs.requested.v1": {
|
|
160
|
+
"fail_silently": False,
|
|
161
|
+
"pipeline": [
|
|
162
|
+
"openedx_webhooks.filters.InstructorDashboardTabsRequestedWebFilter"
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
"org.openedx.learning.account.settings.read_only_fields.requested.v1": {
|
|
166
|
+
"fail_silently": False,
|
|
167
|
+
"pipeline": [
|
|
168
|
+
"openedx_webhooks.filters.AccountSettingsReadOnlyFieldsRequestedWebFilter"
|
|
169
|
+
]
|
|
170
|
+
},
|
|
171
|
+
"org.openedx.learning.grade.context.requested.v1": {
|
|
172
|
+
"fail_silently": False,
|
|
173
|
+
"pipeline": [
|
|
174
|
+
"openedx_webhooks.filters.GradeEventContextRequestedWebFilter"
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
merge_filters(settings, filters_config)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def merge_filters(settings, filters_config):
|
|
183
|
+
"""Register each step once while preserving other plugins' configuration."""
|
|
184
|
+
if not hasattr(settings, 'OPEN_EDX_FILTERS_CONFIG'):
|
|
185
|
+
settings.OPEN_EDX_FILTERS_CONFIG = {}
|
|
186
|
+
for key, filter_config in filters_config.items():
|
|
187
|
+
config = settings.OPEN_EDX_FILTERS_CONFIG.setdefault(key, {"fail_silently": False})
|
|
188
|
+
pipeline = config.setdefault('pipeline', [])
|
|
189
|
+
for step in filter_config['pipeline']:
|
|
190
|
+
if step not in pipeline:
|
|
191
|
+
pipeline.append(step)
|
openedx_webhooks/urls.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""
|
|
2
|
+
URLs for webhooks.
|
|
3
|
+
"""
|
|
4
|
+
from django.urls import re_path # pylint: disable=unused-import
|
|
5
|
+
from django.views.generic import TemplateView # pylint: disable=unused-import
|
|
6
|
+
|
|
7
|
+
urlpatterns = [
|
|
8
|
+
# TODO: Fill in URL patterns and views here.
|
|
9
|
+
# re_path(r'', TemplateView.as_view(template_name="openedx_webhooks/base.html")),
|
|
10
|
+
]
|