diff --git a/eox_nelp/apps.py b/eox_nelp/apps.py index 4a500c9a..e7849513 100644 --- a/eox_nelp/apps.py +++ b/eox_nelp/apps.py @@ -46,6 +46,11 @@ class EoxNelpConfig(AppConfig): 'signal_path': 'openedx.core.djangoapps.signals.signals.COURSE_GRADE_CHANGED', 'dispatch_uid': 'course_grade_publisher_receiver', }, + { + 'receiver_func_name': 'certificate_publisher', + 'signal_path': 'openedx_events.learning.signals.CERTIFICATE_CREATED', + 'dispatch_uid': 'certificate_publisher_receiver', + }, ], }, }, diff --git a/eox_nelp/signals/receivers.py b/eox_nelp/signals/receivers.py index 21987388..226fbfa6 100644 --- a/eox_nelp/signals/receivers.py +++ b/eox_nelp/signals/receivers.py @@ -5,10 +5,18 @@ Functions: block_completion_progress_publisher: it will publish the user progress based on post_save signal. course_grade_changed_progress_publisher: it will publish the user progress based on COURSE_GRADE_CHANGED signal. + create_course_notifications: this will create upcoming notifications based on the sub-section due dates. + certificate_publisher: Publish the user certificate data to the NELC certificates service. """ +import logging + +from django.conf import settings + from eox_nelp.notifications.tasks import create_course_notifications as create_course_notifications_task from eox_nelp.signals.tasks import dispatch_futurex_progress +LOGGER = logging.getLogger(__name__) + def block_completion_progress_publisher(instance, **kwargs): # pylint: disable=unused-argument """This receiver is connected to the post_save BlockCompletion signal @@ -53,3 +61,45 @@ def create_course_notifications(course_key, **kwargs): # pylint: disable=unused course_key: Opaque keys locator used to identify a course. """ create_course_notifications_task.delay(course_id=str(course_key)) + + +def certificate_publisher(certificate, **kwargs): # pylint: disable=unused-argument + """ + Receiver that is connected to the CERTIFICATE_CREATED signal from 'openedx_events.learning.signals'. + + Basically this verifies that the publish action is active and validates the certificate mode in order + to publish just certificates with valid modes. That behavior is controlled by the following settings: + + - ENABLE_CERTIFICATE_PUBLISHER: If this is true the receiver will publish the certificate data, + default is False. + - CERTIFICATE_PUBLISHER_VALID_MODES: List of valid modes, default ['no-id-professional'] + + Args: + certificate: This an instance of the class defined in this link + https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/data.py#L100 + and will provide of the user certificate data. + """ + if not getattr(settings, "ENABLE_CERTIFICATE_PUBLISHER", False): + return + + default_modes = [ + "no-id-professional", + ] + valid_modes = getattr(settings, "CERTIFICATE_PUBLISHER_VALID_MODES", default_modes) + + if certificate.mode in valid_modes: + LOGGER.info( + "The %s certificate associated with the user <%s> and course <%s> has been already generated " + "and its data will be sent to the NELC certificate service.", + certificate.mode, + certificate.user.pii.username, + certificate.course.course_key, + ) + else: + LOGGER.info( + "The %s certificate associated with the user <%s> and course <%s>" + "doesn't have a valid mode and therefore its data won't be published.", + certificate.mode, + certificate.user.pii.username, + certificate.course.course_key, + ) diff --git a/requirements/base.in b/requirements/base.in index b03f7b75..43ffa456 100644 --- a/requirements/base.in +++ b/requirements/base.in @@ -1,17 +1,18 @@ # Main requirements of your plugin application. -c constraints.txt +bs4 Django +django-filter +djangorestframework +djangorestframework-jsonapi==5.0.0 +edx-drf-extensions +edx-i18n-tools +edx-opaque-keys eox-core eox-tenant eox-theming -edx-i18n-tools -django-filter -djangorestframework -bs4 mako -edx-opaque-keys +openedx-events # Open edX Events from Hooks Extension Framework (OEP-50) requests-oauthlib social-auth-app-django -djangorestframework-jsonapi==5.0.0 -edx-drf-extensions diff --git a/requirements/base.txt b/requirements/base.txt index e38c78fa..2187d5d5 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -8,29 +8,29 @@ amqp==5.1.1 # via kombu appdirs==1.4.4 # via fs -asgiref==3.6.0 +asgiref==3.7.2 # via django attrs==23.1.0 # via openedx-events beautifulsoup4==4.12.2 # via bs4 -billiard==3.6.4.0 +billiard==4.1.0 # via celery bs4==0.0.1 # via -r requirements/base.in -celery==5.2.7 +celery==5.3.1 # via # eox-core # event-tracking -certifi==2022.12.7 +certifi==2023.7.22 # via requests cffi==1.15.1 # via # cryptography # pynacl -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via requests -click==8.1.3 +click==8.1.6 # via # celery # click-didyoumean @@ -42,15 +42,9 @@ click-didyoumean==0.3.0 # via celery click-plugins==1.1.1 # via celery -click-repl==0.2.0 +click-repl==0.3.0 # via celery -coreapi==2.3.3 - # via drf-yasg -coreschema==0.0.4 - # via - # coreapi - # drf-yasg -cryptography==40.0.2 +cryptography==41.0.2 # via # jwcrypto # pyjwt @@ -59,9 +53,9 @@ defusedxml==0.7.1 # via # python3-openid # social-auth-core -deprecated==1.2.13 +deprecated==1.2.14 # via jwcrypto -django==3.2.19 +django==3.2.20 # via # -c requirements/constraints.txt # -r requirements/base.in @@ -69,6 +63,7 @@ django==3.2.19 # django-filter # django-model-utils # django-oauth-toolkit + # django-waffle # djangorestframework # djangorestframework-jsonapi # drf-jwt @@ -100,19 +95,19 @@ django-model-utils==4.3.1 # via # edx-proctoring # edx-when -django-oauth-toolkit==2.2.0 +django-oauth-toolkit==2.3.0 # via eox-core django-oauth2-provider==0.2.6.1 # via eox-core django-simple-history==3.3.0 # via edx-proctoring -django-waffle==3.0.0 +django-waffle==4.0.0 # via # edx-django-utils # edx-drf-extensions # edx-proctoring # eox-core -django-webpack-loader==1.8.1 +django-webpack-loader==2.0.1 # via edx-proctoring djangorestframework==3.12.4 # via @@ -131,11 +126,11 @@ djangorestframework-jsonapi==5.0.0 # -r requirements/base.in drf-jwt==1.19.2 # via edx-drf-extensions -drf-yasg==1.21.5 +drf-yasg==1.21.7 # via edx-api-doc-tools -edx-api-doc-tools==1.6.0 +edx-api-doc-tools==1.7.0 # via eox-core -edx-django-utils==5.4.0 +edx-django-utils==5.6.0 # via # edx-drf-extensions # edx-rest-api-client @@ -147,7 +142,7 @@ edx-drf-extensions==8.0.0 # -r requirements/base.in # edx-proctoring # edx-when -edx-i18n-tools==0.9.2 +edx-i18n-tools==1.0.0 # via -r requirements/base.in edx-opaque-keys[django]==2.3.0 # via @@ -157,15 +152,15 @@ edx-opaque-keys[django]==2.3.0 # edx-when # eox-core # openedx-events -edx-proctoring==4.15.1 +edx-proctoring==4.16.0 # via eox-core -edx-rest-api-client==5.5.0 +edx-rest-api-client==5.6.0 # via edx-proctoring -edx-when==2.3.0 +edx-when==2.4.0 # via edx-proctoring eox-core==8.1.0 # via -r requirements/base.in -eox-tenant==9.0.0 +eox-tenant==9.2.1 # via # -r requirements/base.in # eox-theming @@ -173,7 +168,7 @@ eox-theming==5.0.0 # via -r requirements/base.in event-tracking==2.1.0 # via edx-proctoring -fastavro==1.7.3 +fastavro==1.8.2 # via openedx-events fs==2.4.16 # via xblock @@ -185,26 +180,21 @@ inflection==0.5.1 # via # djangorestframework-jsonapi # drf-yasg -itypes==1.2.0 - # via coreapi -jinja2==3.1.2 - # via coreschema jsonfield==3.1.0 # via edx-proctoring -jwcrypto==1.4.2 +jwcrypto==1.5.0 # via django-oauth-toolkit -kombu==5.2.4 +kombu==5.3.1 # via celery -lxml==4.9.2 +lxml==4.9.3 # via xblock mako==1.2.4 # via -r requirements/base.in -markupsafe==2.1.2 +markupsafe==2.1.3 # via - # jinja2 # mako # xblock -newrelic==8.8.0 +newrelic==8.9.0 # via edx-django-utils oauthlib==3.2.2 # via @@ -212,28 +202,30 @@ oauthlib==3.2.2 # requests-oauthlib # social-auth-core openedx-events==0.13.0 - # via eox-core + # via + # -r requirements/base.in + # eox-core packaging==23.1 # via drf-yasg -path==16.6.0 +path==16.7.1 # via edx-i18n-tools pbr==5.11.1 # via stevedore polib==1.2.0 # via edx-i18n-tools -prompt-toolkit==3.0.38 +prompt-toolkit==3.0.39 # via click-repl psutil==5.9.5 # via edx-django-utils pycparser==2.21 # via cffi -pycryptodomex==3.17 +pycryptodomex==3.18.0 # via # edx-proctoring # pyjwkest pyjwkest==1.4.2 # via edx-drf-extensions -pyjwt[crypto]==2.6.0 +pyjwt[crypto]==2.8.0 # via # drf-jwt # edx-drf-extensions @@ -248,6 +240,7 @@ pynacl==1.5.0 # via edx-django-utils python-dateutil==2.8.2 # via + # celery # edx-drf-extensions # edx-proctoring # xblock @@ -255,19 +248,18 @@ python3-openid==3.2.0 # via social-auth-core pytz==2023.3 # via - # celery # django # drf-yasg # edx-proctoring # event-tracking # xblock -pyyaml==6.0 +pyyaml==6.0.1 # via + # drf-yasg # edx-i18n-tools # xblock -requests==2.29.0 +requests==2.31.0 # via - # coreapi # django-oauth-toolkit # edx-drf-extensions # edx-rest-api-client @@ -279,10 +271,6 @@ requests-oauthlib==1.3.1 # via # -r requirements/base.in # social-auth-core -ruamel-yaml==0.17.22 - # via drf-yasg -ruamel-yaml-clib==0.2.7 - # via ruamel-yaml rules==3.3 # via edx-proctoring semantic-version==2.10.0 @@ -291,7 +279,6 @@ shortuuid==1.0.11 # via django-oauth2-provider six==1.16.0 # via - # click-repl # edx-drf-extensions # eox-core # eox-theming @@ -309,15 +296,17 @@ soupsieve==2.4.1 # via beautifulsoup4 sqlparse==0.4.4 # via django -stevedore==5.0.0 +stevedore==5.1.0 # via # edx-django-utils # edx-opaque-keys +typing-extensions==4.7.1 + # via asgiref +tzdata==2023.3 + # via celery uritemplate==4.1.1 - # via - # coreapi - # drf-yasg -urllib3==1.26.15 + # via drf-yasg +urllib3==2.0.4 # via requests vine==5.0.0 # via diff --git a/requirements/django.txt b/requirements/django.txt index 0e0a4523..480c0782 100644 --- a/requirements/django.txt +++ b/requirements/django.txt @@ -1 +1 @@ -django==3.2.19 +django==3.2.20 diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index 92eba9e8..759456d5 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -6,17 +6,19 @@ # build==0.10.0 # via pip-tools -click==8.1.3 +click==8.1.6 # via pip-tools packaging==23.1 # via build -pip-tools==6.13.0 +pip-tools==7.1.0 # via -r requirements/pip-tools.in pyproject-hooks==1.0.0 # via build tomli==2.0.1 - # via build -wheel==0.40.0 + # via + # build + # pip-tools +wheel==0.41.0 # via pip-tools # The following packages are considered to be unsafe in a requirements file: diff --git a/requirements/test.txt b/requirements/test.txt index 42c280cb..441362c6 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -12,11 +12,11 @@ appdirs==1.4.4 # via # -r requirements/base.txt # fs -asgiref==3.6.0 +asgiref==3.7.2 # via # -r requirements/base.txt # django -astroid==2.15.4 +astroid==2.15.6 # via pylint attrs==23.1.0 # via @@ -26,18 +26,18 @@ beautifulsoup4==4.12.2 # via # -r requirements/base.txt # bs4 -billiard==3.6.4.0 +billiard==4.1.0 # via # -r requirements/base.txt # celery bs4==0.0.1 # via -r requirements/base.txt -celery==5.2.7 +celery==5.3.1 # via # -r requirements/base.txt # eox-core # event-tracking -certifi==2022.12.7 +certifi==2023.7.22 # via # -r requirements/base.txt # requests @@ -46,11 +46,11 @@ cffi==1.15.1 # -r requirements/base.txt # cryptography # pynacl -charset-normalizer==3.1.0 +charset-normalizer==3.2.0 # via # -r requirements/base.txt # requests -click==8.1.3 +click==8.1.6 # via # -r requirements/base.txt # celery @@ -67,22 +67,13 @@ click-plugins==1.1.1 # via # -r requirements/base.txt # celery -click-repl==0.2.0 +click-repl==0.3.0 # via # -r requirements/base.txt # celery -coreapi==2.3.3 - # via - # -r requirements/base.txt - # drf-yasg -coreschema==0.0.4 - # via - # -r requirements/base.txt - # coreapi - # drf-yasg -coverage==7.2.5 +coverage==7.2.7 # via -r requirements/test.in -cryptography==40.0.2 +cryptography==41.0.2 # via # -r requirements/base.txt # jwcrypto @@ -95,13 +86,13 @@ defusedxml==0.7.1 # -r requirements/base.txt # python3-openid # social-auth-core -deprecated==1.2.13 +deprecated==1.2.14 # via # -r requirements/base.txt # jwcrypto -dill==0.3.6 +dill==0.3.7 # via pylint -django==3.2.19 +django==3.2.20 # via # -c requirements/constraints.txt # -r requirements/base.txt @@ -109,6 +100,7 @@ django==3.2.19 # django-filter # django-model-utils # django-oauth-toolkit + # django-waffle # djangorestframework # djangorestframework-jsonapi # drf-jwt @@ -146,7 +138,7 @@ django-model-utils==4.3.1 # -r requirements/base.txt # edx-proctoring # edx-when -django-oauth-toolkit==2.2.0 +django-oauth-toolkit==2.3.0 # via # -r requirements/base.txt # eox-core @@ -158,14 +150,14 @@ django-simple-history==3.3.0 # via # -r requirements/base.txt # edx-proctoring -django-waffle==3.0.0 +django-waffle==4.0.0 # via # -r requirements/base.txt # edx-django-utils # edx-drf-extensions # edx-proctoring # eox-core -django-webpack-loader==1.8.1 +django-webpack-loader==2.0.1 # via # -r requirements/base.txt # edx-proctoring @@ -188,15 +180,15 @@ drf-jwt==1.19.2 # via # -r requirements/base.txt # edx-drf-extensions -drf-yasg==1.21.5 +drf-yasg==1.21.7 # via # -r requirements/base.txt # edx-api-doc-tools -edx-api-doc-tools==1.6.0 +edx-api-doc-tools==1.7.0 # via # -r requirements/base.txt # eox-core -edx-django-utils==5.4.0 +edx-django-utils==5.6.0 # via # -r requirements/base.txt # edx-drf-extensions @@ -209,7 +201,7 @@ edx-drf-extensions==8.0.0 # -r requirements/base.txt # edx-proctoring # edx-when -edx-i18n-tools==0.9.2 +edx-i18n-tools==1.0.0 # via -r requirements/base.txt edx-opaque-keys[django]==2.3.0 # via @@ -219,21 +211,21 @@ edx-opaque-keys[django]==2.3.0 # edx-when # eox-core # openedx-events -edx-proctoring==4.15.1 +edx-proctoring==4.16.0 # via # -r requirements/base.txt # eox-core -edx-rest-api-client==5.5.0 +edx-rest-api-client==5.6.0 # via # -r requirements/base.txt # edx-proctoring -edx-when==2.3.0 +edx-when==2.4.0 # via # -r requirements/base.txt # edx-proctoring eox-core==8.1.0 # via -r requirements/base.txt -eox-tenant==9.0.0 +eox-tenant==9.2.1 # via # -r requirements/base.txt # eox-theming @@ -243,11 +235,11 @@ event-tracking==2.1.0 # via # -r requirements/base.txt # edx-proctoring -fastavro==1.7.3 +fastavro==1.8.2 # via # -r requirements/base.txt # openedx-events -flake8==6.0.0 +flake8==6.1.0 # via -r requirements/test.in fs==2.4.16 # via @@ -268,47 +260,38 @@ inflection==0.5.1 # drf-yasg isort==5.12.0 # via pylint -itypes==1.2.0 - # via - # -r requirements/base.txt - # coreapi -jinja2==3.1.2 - # via - # -r requirements/base.txt - # coreschema jsonfield==3.1.0 # via # -r requirements/base.txt # edx-proctoring -jwcrypto==1.4.2 +jwcrypto==1.5.0 # via # -r requirements/base.txt # django-oauth-toolkit -kombu==5.2.4 +kombu==5.3.1 # via # -r requirements/base.txt # celery lazy-object-proxy==1.9.0 # via astroid -lxml==4.9.2 +lxml==4.9.3 # via # -r requirements/base.txt # xblock mako==1.2.4 # via -r requirements/base.txt -markupsafe==2.1.2 +markupsafe==2.1.3 # via # -r requirements/base.txt - # jinja2 # mako # xblock mccabe==0.7.0 # via # flake8 # pylint -mock==5.0.2 +mock==5.1.0 # via -r requirements/test.in -newrelic==8.8.0 +newrelic==8.9.0 # via # -r requirements/base.txt # edx-django-utils @@ -326,7 +309,7 @@ packaging==23.1 # via # -r requirements/base.txt # drf-yasg -path==16.6.0 +path==16.7.1 # via # -r requirements/base.txt # edx-i18n-tools @@ -337,13 +320,13 @@ pbr==5.11.1 # via # -r requirements/base.txt # stevedore -platformdirs==3.5.0 +platformdirs==3.10.0 # via pylint polib==1.2.0 # via # -r requirements/base.txt # edx-i18n-tools -prompt-toolkit==3.0.38 +prompt-toolkit==3.0.39 # via # -r requirements/base.txt # click-repl @@ -351,7 +334,7 @@ psutil==5.9.5 # via # -r requirements/base.txt # edx-django-utils -pycodestyle==2.10.0 +pycodestyle==2.11.0 # via # -r requirements/test.in # flake8 @@ -359,18 +342,18 @@ pycparser==2.21 # via # -r requirements/base.txt # cffi -pycryptodomex==3.17 +pycryptodomex==3.18.0 # via # -r requirements/base.txt # edx-proctoring # pyjwkest -pyflakes==3.0.1 +pyflakes==3.1.0 # via flake8 pyjwkest==1.4.2 # via # -r requirements/base.txt # edx-drf-extensions -pyjwt[crypto]==2.6.0 +pyjwt[crypto]==2.8.0 # via # -r requirements/base.txt # drf-jwt @@ -378,7 +361,7 @@ pyjwt[crypto]==2.6.0 # edx-proctoring # edx-rest-api-client # social-auth-core -pylint==2.17.3 +pylint==2.17.5 # via -r requirements/test.in pymongo==3.13.0 # via @@ -392,6 +375,7 @@ pynacl==1.5.0 python-dateutil==2.8.2 # via # -r requirements/base.txt + # celery # edx-drf-extensions # edx-proctoring # xblock @@ -402,21 +386,20 @@ python3-openid==3.2.0 pytz==2023.3 # via # -r requirements/base.txt - # celery # django # drf-yasg # edx-proctoring # event-tracking # xblock -pyyaml==6.0 +pyyaml==6.0.1 # via # -r requirements/base.txt + # drf-yasg # edx-i18n-tools # xblock -requests==2.29.0 +requests==2.31.0 # via # -r requirements/base.txt - # coreapi # django-oauth-toolkit # edx-drf-extensions # edx-rest-api-client @@ -428,14 +411,6 @@ requests-oauthlib==1.3.1 # via # -r requirements/base.txt # social-auth-core -ruamel-yaml==0.17.22 - # via - # -r requirements/base.txt - # drf-yasg -ruamel-yaml-clib==0.2.7 - # via - # -r requirements/base.txt - # ruamel-yaml rules==3.3 # via # -r requirements/base.txt @@ -451,7 +426,6 @@ shortuuid==1.0.11 six==1.16.0 # via # -r requirements/base.txt - # click-repl # edx-drf-extensions # eox-core # eox-theming @@ -477,7 +451,7 @@ sqlparse==0.4.4 # via # -r requirements/base.txt # django -stevedore==5.0.0 +stevedore==5.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -486,16 +460,22 @@ testfixtures==7.1.0 # via -r requirements/test.in tomli==2.0.1 # via pylint -tomlkit==0.11.8 +tomlkit==0.12.1 # via pylint -typing-extensions==4.5.0 - # via astroid +typing-extensions==4.7.1 + # via + # -r requirements/base.txt + # asgiref + # astroid +tzdata==2023.3 + # via + # -r requirements/base.txt + # celery uritemplate==4.1.1 # via # -r requirements/base.txt - # coreapi # drf-yasg -urllib3==1.26.15 +urllib3==2.0.4 # via # -r requirements/base.txt # requests diff --git a/requirements/tox.txt b/requirements/tox.txt index 71cf72f8..408bd04e 100644 --- a/requirements/tox.txt +++ b/requirements/tox.txt @@ -4,15 +4,15 @@ # # make upgrade # -cachetools==5.3.0 +cachetools==5.3.1 # via tox chardet==5.1.0 # via tox colorama==0.4.6 # via tox -distlib==0.3.6 +distlib==0.3.7 # via virtualenv -filelock==3.12.0 +filelock==3.12.2 # via # tox # virtualenv @@ -20,19 +20,19 @@ packaging==23.1 # via # pyproject-api # tox -platformdirs==3.5.0 +platformdirs==3.10.0 # via # tox # virtualenv -pluggy==1.0.0 +pluggy==1.2.0 # via tox -pyproject-api==1.5.1 +pyproject-api==1.5.3 # via tox tomli==2.0.1 # via # pyproject-api # tox -tox==4.5.1 +tox==4.6.4 # via -r requirements/tox.in -virtualenv==20.23.0 +virtualenv==20.24.2 # via tox