From 011711e8d37d646c4e26583916bbd65d60576175 Mon Sep 17 00:00:00 2001 From: Ivan Niedielnitsev <81557788+NiedielnitsevIvan@users.noreply.github.com> Date: Mon, 29 Apr 2024 16:42:04 +0300 Subject: [PATCH] feat: [AXM-252] add settings for edx-ace push notifications (#2541) * feat: [AXM-252] create policy for push notifications * feat: [AXM-252] add API for store device token * feat: [AXM-252] add settings for edx-ace push notifications * chore: [AXM-252] add edx-ace and django-push-notification to dev requirements * chore: [AXM-252] update edx-ace version * fix: [AXM-252] add create token edndpoint to urls * chore: [AXM-252] update django push notifications version * style: [AXM-252] fix code style issues after review * chore: [AXM-252] bump edx-ace version * refactor: [AXM-252] some push notif policy refactoring * chore: [AXM-252] change edx-ace branch to mob-develop * chore: [AXM-252] recompile requirements after rebase --- .../mobile_api/notifications/urls.py | 10 ++ .../mobile_api/notifications/views.py | 50 ++++++ lms/djangoapps/mobile_api/urls.py | 1 + .../djangoapps/ace_common/settings/common.py | 29 ++++ .../ace_common/settings/production.py | 22 +++ openedx/core/djangoapps/ace_common/utils.py | 20 +++ .../core/djangoapps/notifications/policies.py | 41 +++++ requirements/edx/base.txt | 87 ++++++++++- requirements/edx/development.txt | 142 +++++++++++++++++- requirements/edx/doc.txt | 116 +++++++++++++- requirements/edx/github.in | 3 + requirements/edx/testing.txt | 119 ++++++++++++++- setup.py | 3 +- 13 files changed, 628 insertions(+), 15 deletions(-) create mode 100644 lms/djangoapps/mobile_api/notifications/urls.py create mode 100644 lms/djangoapps/mobile_api/notifications/views.py create mode 100644 openedx/core/djangoapps/ace_common/utils.py create mode 100644 openedx/core/djangoapps/notifications/policies.py diff --git a/lms/djangoapps/mobile_api/notifications/urls.py b/lms/djangoapps/mobile_api/notifications/urls.py new file mode 100644 index 000000000000..17b970916a47 --- /dev/null +++ b/lms/djangoapps/mobile_api/notifications/urls.py @@ -0,0 +1,10 @@ +from django.urls import path +from .views import GCMDeviceViewSet + + +CREATE_GCM_DEVICE = GCMDeviceViewSet.as_view({'post': 'create'}) + + +urlpatterns = [ + path('create-token/', CREATE_GCM_DEVICE, name='gcmdevice-list'), +] diff --git a/lms/djangoapps/mobile_api/notifications/views.py b/lms/djangoapps/mobile_api/notifications/views.py new file mode 100644 index 000000000000..aeab8c5445c9 --- /dev/null +++ b/lms/djangoapps/mobile_api/notifications/views.py @@ -0,0 +1,50 @@ +from django.conf import settings +from rest_framework import status +from rest_framework.response import Response + +from edx_ace.push_notifications.views import GCMDeviceViewSet as GCMDeviceViewSetBase + +from ..decorators import mobile_view + + +@mobile_view(is_user=True) +class GCMDeviceViewSet(GCMDeviceViewSetBase): + """ + **Use Case** + This endpoint allows clients to register a device for push notifications. + + If the device is already registered, the existing registration will be updated. + If setting PUSH_NOTIFICATIONS_SETTINGS is not configured, the endpoint will return a 501 error. + + **Example Request** + POST /api/mobile/{version}/notifications/create-token/ + **POST Parameters** + The body of the POST request can include the following parameters. + * name (optional) - A name of the device. + * registration_id (required) - The device token of the device. + * device_id (optional) - ANDROID_ID / TelephonyManager.getDeviceId() (always as hex) + * active (optional) - Whether the device is active, default is True. + If False, the device will not receive notifications. + * cloud_message_type (required) - You should choose FCM or GCM. Currently, only FCM is supported. + * application_id (optional) - Opaque application identity, should be filled in for multiple + key/certificate access. + **Example Response** + ```json + { + "id": 1, + "name": "My Device", + "registration_id": "fj3j4", + "device_id": 1234, + "active": true, + "date_created": "2024-04-18T07:39:37.132787Z", + "cloud_message_type": "FCM", + "application_id": "my_app_id" + } + ``` + """ + + def create(self, request, *args, **kwargs): + if not getattr(settings, 'PUSH_NOTIFICATIONS_SETTINGS', None): + return Response('Push notifications are not configured.', status.HTTP_501_NOT_IMPLEMENTED) + + return super().create(request, *args, **kwargs) diff --git a/lms/djangoapps/mobile_api/urls.py b/lms/djangoapps/mobile_api/urls.py index 1ad34ced5de9..c7aacc0b669a 100644 --- a/lms/djangoapps/mobile_api/urls.py +++ b/lms/djangoapps/mobile_api/urls.py @@ -10,5 +10,6 @@ urlpatterns = [ path('users/', include('lms.djangoapps.mobile_api.users.urls')), path('my_user_info', my_user_info, name='user-info'), + path('notifications/', include('lms.djangoapps.mobile_api.notifications.urls')), path('course_info/', include('lms.djangoapps.mobile_api.course_info.urls')), ] diff --git a/openedx/core/djangoapps/ace_common/settings/common.py b/openedx/core/djangoapps/ace_common/settings/common.py index 11bfbce5c59f..58341470ed8d 100644 --- a/openedx/core/djangoapps/ace_common/settings/common.py +++ b/openedx/core/djangoapps/ace_common/settings/common.py @@ -1,11 +1,14 @@ """ Settings for ace_common app. """ +from openedx.core.djangoapps.ace_common.utils import setup_firebase_app ACE_ROUTING_KEY = 'edx.lms.core.default' def plugin_settings(settings): # lint-amnesty, pylint: disable=missing-function-docstring, missing-module-docstring + if 'push_notifications' not in settings.INSTALLED_APPS: + settings.INSTALLED_APPS.append('push_notifications') settings.ACE_ENABLED_CHANNELS = [ 'django_email' ] @@ -22,3 +25,29 @@ def plugin_settings(settings): # lint-amnesty, pylint: disable=missing-function settings.ACE_ROUTING_KEY = ACE_ROUTING_KEY settings.FEATURES['test_django_plugin'] = True + settings.FCM_APP_NAME = 'fcm-edx-platform' + + if getattr(settings, 'FIREBASE_SETUP_STATUS', None) is None: + settings.ACE_CHANNEL_DEFAULT_PUSH = 'push_notification' + + # Note: To local development with Firebase, you must set FIREBASE_CREDENTIALS. + settings.FCM_APP_NAME = 'fcm-edx-platform' + settings.FIREBASE_CREDENTIALS = None + + if firebase_app := setup_firebase_app(settings.FIREBASE_CREDENTIALS, settings.FCM_APP_NAME): + settings.ACE_ENABLED_CHANNELS.append(settings.ACE_CHANNEL_DEFAULT_PUSH) + settings.ACE_ENABLED_POLICIES.append(settings.ACE_CHANNEL_DEFAULT_PUSH) + + settings.PUSH_NOTIFICATIONS_SETTINGS = { + 'CONFIG': 'push_notifications.conf.AppConfig', + 'APPLICATIONS': { + settings.FCM_APP_NAME: { + 'PLATFORM': 'FCM', + 'FIREBASE_APP': firebase_app, + }, + }, + 'UPDATE_ON_DUPLICATE_REG_ID': True, + } + settings.FIREBASE_SETUP_STATUS = True + else: + settings.FIREBASE_SETUP_STATUS = False diff --git a/openedx/core/djangoapps/ace_common/settings/production.py b/openedx/core/djangoapps/ace_common/settings/production.py index cc4da91c18db..b7ac5b12db17 100644 --- a/openedx/core/djangoapps/ace_common/settings/production.py +++ b/openedx/core/djangoapps/ace_common/settings/production.py @@ -1,4 +1,5 @@ """Common environment variables unique to the ace_common plugin.""" +from openedx.core.djangoapps.ace_common.utils import setup_firebase_app def plugin_settings(settings): @@ -26,3 +27,24 @@ def plugin_settings(settings): settings.ACE_CHANNEL_TRANSACTIONAL_EMAIL = settings.ENV_TOKENS.get( 'ACE_CHANNEL_TRANSACTIONAL_EMAIL', settings.ACE_CHANNEL_TRANSACTIONAL_EMAIL ) + settings.FCM_APP_NAME = settings.ENV_TOKENS.get('FCM_APP_NAME', 'fcm-edx-platform') + settings.FIREBASE_CREDENTIALS = settings.ENV_TOKENS.get('FIREBASE_CREDENTIALS', {}) + + if getattr(settings, 'FIREBASE_SETUP_STATUS', None) is None: + if firebase_app := setup_firebase_app(settings.FIREBASE_CREDENTIALS, settings.FCM_APP_NAME): + settings.ACE_ENABLED_CHANNELS.append(settings.ACE_CHANNEL_DEFAULT_PUSH) + settings.ACE_ENABLED_POLICIES.append(settings.ACE_CHANNEL_DEFAULT_PUSH) + + settings.PUSH_NOTIFICATIONS_SETTINGS = { + 'CONFIG': 'push_notifications.conf.AppConfig', + 'APPLICATIONS': { + settings.FCM_APP_NAME: { + 'PLATFORM': 'FCM', + 'FIREBASE_APP': firebase_app, + }, + }, + 'UPDATE_ON_DUPLICATE_REG_ID': True, + } + settings.FIREBASE_SETUP_STATUS = True + else: + settings.FIREBASE_SETUP_STATUS = False diff --git a/openedx/core/djangoapps/ace_common/utils.py b/openedx/core/djangoapps/ace_common/utils.py new file mode 100644 index 000000000000..adf5586dc449 --- /dev/null +++ b/openedx/core/djangoapps/ace_common/utils.py @@ -0,0 +1,20 @@ +""" +Utility functions for edx-ace. +""" +import logging + +log = logging.getLogger(__name__) + + +def setup_firebase_app(firebase_credentials, app_name='fcm-app'): + """ + Returns a Firebase app instance if the Firebase credentials are provided. + """ + try: + import firebase_admin # pylint: disable=import-outside-toplevel + except ImportError: + log.error('Could not import firebase_admin package.') + return + if firebase_credentials: + certificate = firebase_admin.credentials.Certificate(firebase_credentials) + return firebase_admin.initialize_app(certificate, name=app_name) diff --git a/openedx/core/djangoapps/notifications/policies.py b/openedx/core/djangoapps/notifications/policies.py new file mode 100644 index 000000000000..768d05e62efd --- /dev/null +++ b/openedx/core/djangoapps/notifications/policies.py @@ -0,0 +1,41 @@ +"""Policies for the notifications app.""" + +from edx_ace.channel import ChannelType +from edx_ace.policy import Policy, PolicyResult +from opaque_keys.edx.keys import CourseKey + +from .models import CourseNotificationPreference + + +class CoursePushNotificationOptout(Policy): + """ + Course Push Notification optOut Policy. + """ + + def check(self, message): + """ + Check if the user has opted out of push notifications for the given course. + :param message: + :return: + """ + course_ids = message.context.get('course_ids', []) + app_label = message.context.get('app_label') + + if not (app_label or message.context.get('send_push_notification', False)): + return PolicyResult(deny={ChannelType.PUSH}) + + course_keys = [CourseKey.from_string(course_id) for course_id in course_ids] + for course_key in course_keys: + course_notification_preference = CourseNotificationPreference.get_user_course_preference( + message.recipient.lms_user_id, + course_key + ) + push_notification_preference = course_notification_preference.get_notification_type_config( + app_label, + notification_type='push', + ).get('push', False) + + if not push_notification_preference: + return PolicyResult(deny={ChannelType.PUSH}) + + return PolicyResult(deny=frozenset()) diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 12e24dd01972..642ab2a6bf0c 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -4,6 +4,12 @@ # # make upgrade # +-e git+https://github.com/jazzband/django-push-notifications.git@906fe52058bad36b6af2bb292fdb9292ccaa94e5#egg=django_push_notifications + # via -r requirements/edx/github.in +-e git+https://github.com/raccoongang/edx-ace.git@mob-develop#egg=edx_ace + # via + # -r requirements/edx/github.in + # -r requirements/edx/kernel.in -e git+https://github.com/anupdhabarde/edx-proctoring-proctortrack.git@31c6c9923a51c903ae83760ecbbac191363aa2a2#egg=edx_proctoring_proctortrack # via -r requirements/edx/github.in acid-xblock==0.3.0 @@ -90,6 +96,10 @@ botocore==1.34.45 # s3transfer bridgekeeper==0.9 # via -r requirements/edx/kernel.in +cachecontrol==0.14.0 + # via firebase-admin +cachetools==5.3.3 + # via google-auth camel-converter[pydantic]==3.1.1 # via meilisearch celery==5.3.6 @@ -196,6 +206,7 @@ django==4.2.10 # django-multi-email-field # django-mysql # django-oauth-toolkit + # django-push-notifications # django-sekizai # django-ses # django-statici18n @@ -411,8 +422,6 @@ drf-yasg==1.21.5 # -c requirements/edx/../constraints.txt # django-user-tasks # edx-api-doc-tools -edx-ace==1.8.0 - # via -r requirements/edx/kernel.in edx-api-doc-tools==1.8.0 # via # -r requirements/edx/kernel.in @@ -572,6 +581,8 @@ fastavro==1.9.4 # via openedx-events filelock==3.13.1 # via snowflake-connector-python +firebase-admin==5.0.0 + # via edx-ace frozenlist==1.4.1 # via # aiohttp @@ -592,6 +603,49 @@ geoip2==4.8.0 # via -r requirements/edx/kernel.in glob2==0.7 # via -r requirements/edx/kernel.in +google-api-core[grpc]==1.34.1 + # via + # firebase-admin + # google-api-python-client + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-api-python-client==2.127.0 + # via firebase-admin +google-auth==2.29.0 + # via + # google-api-core + # google-api-python-client + # google-auth-httplib2 + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-auth-httplib2==0.2.0 + # via google-api-python-client +google-cloud-core==2.4.1 + # via + # google-cloud-firestore + # google-cloud-storage +google-cloud-firestore==2.16.0 + # via firebase-admin +google-cloud-storage==2.14.0 + # via firebase-admin +google-crc32c==1.5.0 + # via + # google-cloud-storage + # google-resumable-media +google-resumable-media==2.7.0 + # via google-cloud-storage +googleapis-common-protos==1.63.0 + # via + # google-api-core + # grpcio-status +grpcio==1.62.2 + # via + # google-api-core + # grpcio-status +grpcio-status==1.48.2 + # via google-api-core gunicorn==22.0.0 # via -r requirements/edx/kernel.in help-tokens==2.4.0 @@ -600,6 +654,10 @@ html5lib==1.1 # via # -r requirements/edx/kernel.in # ora2 +httplib2==0.22.0 + # via + # google-api-python-client + # google-auth-httplib2 icalendar==5.0.11 # via -r requirements/edx/kernel.in idna==3.6 @@ -731,6 +789,8 @@ monotonic==1.6 # py2neo mpmath==1.3.0 # via sympy +msgpack==1.0.8 + # via cachecontrol multidict==6.0.5 # via # aiohttp @@ -848,6 +908,15 @@ polib==1.2.0 # via edx-i18n-tools prompt-toolkit==3.0.43 # via click-repl +proto-plus==1.23.0 + # via google-cloud-firestore +protobuf==3.20.3 + # via + # google-api-core + # google-cloud-firestore + # googleapis-common-protos + # grpcio-status + # proto-plus psutil==5.9.8 # via # -r requirements/edx/paver.txt @@ -857,7 +926,12 @@ py2neo @ https://github.com/overhangio/py2neo/releases/download/2021.2.3/py2neo- # -c requirements/edx/../constraints.txt # -r requirements/edx/bundled.in pyasn1==0.5.1 - # via pgpy + # via + # pgpy + # pyasn1-modules + # rsa +pyasn1-modules==0.4.0 + # via google-auth pycountry==23.12.11 # via -r requirements/edx/kernel.in pycparser==2.21 @@ -919,6 +993,7 @@ pyopenssl==22.0.0 pyparsing==3.1.1 # via # chem + # httplib2 # openedx-calc pyrsistent==0.20.0 # via optimizely-sdk @@ -1003,6 +1078,7 @@ requests==2.31.0 # -r requirements/edx/paver.txt # algoliasearch # analytics-python + # cachecontrol # coreapi # django-oauth-toolkit # edx-bulk-grades @@ -1010,6 +1086,8 @@ requests==2.31.0 # edx-enterprise # edx-rest-api-client # geoip2 + # google-api-core + # google-cloud-storage # mailsnake # meilisearch # openai @@ -1031,6 +1109,8 @@ rpds-py==0.18.0 # via # jsonschema # referencing +rsa==4.9 + # via google-auth ruamel-yaml==0.18.6 # via drf-yasg ruamel-yaml-clib==0.2.8 @@ -1177,6 +1257,7 @@ uritemplate==4.1.1 # coreapi # drf-spectacular # drf-yasg + # google-api-python-client urllib3==1.26.18 # via # -c requirements/edx/../constraints.txt diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 4c2d23507355..d08a30846e39 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -4,6 +4,14 @@ # # make upgrade # +-e git+https://github.com/jazzband/django-push-notifications.git@906fe52058bad36b6af2bb292fdb9292ccaa94e5#egg=django_push_notifications + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt +-e git+https://github.com/raccoongang/edx-ace.git@mob-develop#egg=edx_ace + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt -e git+https://github.com/anupdhabarde/edx-proctoring-proctortrack.git@31c6c9923a51c903ae83760ecbbac191363aa2a2#egg=edx_proctoring_proctortrack # via # -r requirements/edx/doc.txt @@ -166,9 +174,16 @@ build==1.0.3 # via # -r requirements/edx/../pip-tools.txt # pip-tools -cachetools==5.3.2 +cachecontrol==0.14.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # firebase-admin +cachetools==5.3.3 # via + # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt + # google-auth # tox camel-converter[pydantic]==3.1.1 # via @@ -362,6 +377,7 @@ django==4.2.10 # django-multi-email-field # django-mysql # django-oauth-toolkit + # django-push-notifications # django-sekizai # django-ses # django-statici18n @@ -668,10 +684,6 @@ drf-yasg==1.21.5 # -r requirements/edx/testing.txt # django-user-tasks # edx-api-doc-tools -edx-ace==1.8.0 - # via - # -r requirements/edx/doc.txt - # -r requirements/edx/testing.txt edx-api-doc-tools==1.8.0 # via # -r requirements/edx/doc.txt @@ -914,6 +926,11 @@ filelock==3.13.1 # snowflake-connector-python # tox # virtualenv +firebase-admin==5.0.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # edx-ace freezegun==1.4.0 # via -r requirements/edx/testing.txt frozenlist==1.4.1 @@ -953,10 +970,83 @@ glob2==0.7 # via # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt +google-api-core[grpc]==1.34.1 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # firebase-admin + # google-api-python-client + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-api-python-client==2.127.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # firebase-admin +google-auth==2.29.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-api-core + # google-api-python-client + # google-auth-httplib2 + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-auth-httplib2==0.2.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-api-python-client +google-cloud-core==2.4.1 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-cloud-firestore + # google-cloud-storage +google-cloud-firestore==2.16.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # firebase-admin +google-cloud-storage==2.14.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # firebase-admin +google-crc32c==1.5.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-cloud-storage + # google-resumable-media +google-resumable-media==2.7.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-cloud-storage +googleapis-common-protos==1.63.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-api-core + # grpcio-status grimp==3.2 # via # -r requirements/edx/testing.txt # import-linter +grpcio==1.62.2 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-api-core + # grpcio-status +grpcio-status==1.48.2 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-api-core gunicorn==22.0.0 # via # -r requirements/edx/doc.txt @@ -974,6 +1064,12 @@ html5lib==1.1 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # ora2 +httplib2==0.22.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-api-python-client + # google-auth-httplib2 httpretty==1.1.4 # via -r requirements/edx/testing.txt icalendar==5.0.11 @@ -1213,6 +1309,11 @@ mpmath==1.3.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # sympy +msgpack==1.0.8 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # cachecontrol multidict==6.0.5 # via # -r requirements/edx/doc.txt @@ -1426,6 +1527,20 @@ prompt-toolkit==3.0.43 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # click-repl +proto-plus==1.23.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-cloud-firestore +protobuf==3.20.3 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-api-core + # google-cloud-firestore + # googleapis-common-protos + # grpcio-status + # proto-plus psutil==5.9.8 # via # -r requirements/edx/doc.txt @@ -1445,6 +1560,13 @@ pyasn1==0.5.1 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # pgpy + # pyasn1-modules + # rsa +pyasn1-modules==0.4.0 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-auth pycodestyle==2.8.0 # via # -c requirements/edx/../constraints.txt @@ -1575,6 +1697,7 @@ pyparsing==3.1.1 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # chem + # httplib2 # openedx-calc pyproject-api==1.6.1 # via @@ -1736,6 +1859,7 @@ requests==2.31.0 # -r requirements/edx/testing.txt # algoliasearch # analytics-python + # cachecontrol # coreapi # django-oauth-toolkit # djangorestframework-stubs @@ -1744,6 +1868,8 @@ requests==2.31.0 # edx-enterprise # edx-rest-api-client # geoip2 + # google-api-core + # google-cloud-storage # mailsnake # meilisearch # openai @@ -1770,6 +1896,11 @@ rpds-py==0.18.0 # -r requirements/edx/testing.txt # jsonschema # referencing +rsa==4.9 + # via + # -r requirements/edx/doc.txt + # -r requirements/edx/testing.txt + # google-auth ruamel-yaml==0.18.6 # via # -r requirements/edx/doc.txt @@ -2097,6 +2228,7 @@ uritemplate==4.1.1 # coreapi # drf-spectacular # drf-yasg + # google-api-python-client urllib3==1.26.18 # via # -c requirements/edx/../constraints.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index 8be896b0b22c..a097d20f6639 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -4,6 +4,10 @@ # # make upgrade # +-e git+https://github.com/jazzband/django-push-notifications.git@906fe52058bad36b6af2bb292fdb9292ccaa94e5#egg=django_push_notifications + # via -r requirements/edx/base.txt +-e git+https://github.com/raccoongang/edx-ace.git@mob-develop#egg=edx_ace + # via -r requirements/edx/base.txt -e git+https://github.com/anupdhabarde/edx-proctoring-proctortrack.git@31c6c9923a51c903ae83760ecbbac191363aa2a2#egg=edx_proctoring_proctortrack # via -r requirements/edx/base.txt accessible-pygments==0.0.4 @@ -119,6 +123,14 @@ botocore==1.34.45 # s3transfer bridgekeeper==0.9 # via -r requirements/edx/base.txt +cachecontrol==0.14.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +cachetools==5.3.3 + # via + # -r requirements/edx/base.txt + # google-auth camel-converter[pydantic]==3.1.1 # via # -r requirements/edx/base.txt @@ -246,6 +258,7 @@ django==4.2.10 # django-multi-email-field # django-mysql # django-oauth-toolkit + # django-push-notifications # django-sekizai # django-ses # django-statici18n @@ -489,8 +502,6 @@ drf-yasg==1.21.5 # -r requirements/edx/base.txt # django-user-tasks # edx-api-doc-tools -edx-ace==1.8.0 - # via -r requirements/edx/base.txt edx-api-doc-tools==1.8.0 # via # -r requirements/edx/base.txt @@ -660,6 +671,10 @@ filelock==3.13.1 # via # -r requirements/edx/base.txt # snowflake-connector-python +firebase-admin==5.0.0 + # via + # -r requirements/edx/base.txt + # edx-ace frozenlist==1.4.1 # via # -r requirements/edx/base.txt @@ -687,6 +702,67 @@ gitpython==3.1.42 # via -r requirements/edx/doc.in glob2==0.7 # via -r requirements/edx/base.txt +google-api-core[grpc]==1.34.1 + # via + # -r requirements/edx/base.txt + # firebase-admin + # google-api-python-client + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-api-python-client==2.127.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +google-auth==2.29.0 + # via + # -r requirements/edx/base.txt + # google-api-core + # google-api-python-client + # google-auth-httplib2 + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-auth-httplib2==0.2.0 + # via + # -r requirements/edx/base.txt + # google-api-python-client +google-cloud-core==2.4.1 + # via + # -r requirements/edx/base.txt + # google-cloud-firestore + # google-cloud-storage +google-cloud-firestore==2.16.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +google-cloud-storage==2.14.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +google-crc32c==1.5.0 + # via + # -r requirements/edx/base.txt + # google-cloud-storage + # google-resumable-media +google-resumable-media==2.7.0 + # via + # -r requirements/edx/base.txt + # google-cloud-storage +googleapis-common-protos==1.63.0 + # via + # -r requirements/edx/base.txt + # google-api-core + # grpcio-status +grpcio==1.62.2 + # via + # -r requirements/edx/base.txt + # google-api-core + # grpcio-status +grpcio-status==1.48.2 + # via + # -r requirements/edx/base.txt + # google-api-core gunicorn==22.0.0 # via -r requirements/edx/base.txt help-tokens==2.4.0 @@ -695,6 +771,11 @@ html5lib==1.1 # via # -r requirements/edx/base.txt # ora2 +httplib2==0.22.0 + # via + # -r requirements/edx/base.txt + # google-api-python-client + # google-auth-httplib2 icalendar==5.0.11 # via -r requirements/edx/base.txt idna==3.6 @@ -861,6 +942,10 @@ mpmath==1.3.0 # via # -r requirements/edx/base.txt # sympy +msgpack==1.0.8 + # via + # -r requirements/edx/base.txt + # cachecontrol multidict==6.0.5 # via # -r requirements/edx/base.txt @@ -1001,6 +1086,18 @@ prompt-toolkit==3.0.43 # via # -r requirements/edx/base.txt # click-repl +proto-plus==1.23.0 + # via + # -r requirements/edx/base.txt + # google-cloud-firestore +protobuf==3.20.3 + # via + # -r requirements/edx/base.txt + # google-api-core + # google-cloud-firestore + # googleapis-common-protos + # grpcio-status + # proto-plus psutil==5.9.8 # via # -r requirements/edx/base.txt @@ -1013,6 +1110,12 @@ pyasn1==0.5.1 # via # -r requirements/edx/base.txt # pgpy + # pyasn1-modules + # rsa +pyasn1-modules==0.4.0 + # via + # -r requirements/edx/base.txt + # google-auth pycountry==23.12.11 # via -r requirements/edx/base.txt pycparser==2.21 @@ -1091,6 +1194,7 @@ pyparsing==3.1.1 # via # -r requirements/edx/base.txt # chem + # httplib2 # openedx-calc pyrsistent==0.20.0 # via @@ -1187,6 +1291,7 @@ requests==2.31.0 # -r requirements/edx/base.txt # algoliasearch # analytics-python + # cachecontrol # coreapi # django-oauth-toolkit # edx-bulk-grades @@ -1194,6 +1299,8 @@ requests==2.31.0 # edx-enterprise # edx-rest-api-client # geoip2 + # google-api-core + # google-cloud-storage # mailsnake # meilisearch # openai @@ -1217,6 +1324,10 @@ rpds-py==0.18.0 # -r requirements/edx/base.txt # jsonschema # referencing +rsa==4.9 + # via + # -r requirements/edx/base.txt + # google-auth ruamel-yaml==0.18.6 # via # -r requirements/edx/base.txt @@ -1433,6 +1544,7 @@ uritemplate==4.1.1 # coreapi # drf-spectacular # drf-yasg + # google-api-python-client urllib3==1.26.18 # via # -c requirements/edx/../constraints.txt diff --git a/requirements/edx/github.in b/requirements/edx/github.in index ea6d47eec8a0..0d01c506c7a6 100644 --- a/requirements/edx/github.in +++ b/requirements/edx/github.in @@ -90,3 +90,6 @@ # django42 support PR merged but new release is pending. # https://github.com/openedx/edx-platform/issues/33431 -e git+https://github.com/anupdhabarde/edx-proctoring-proctortrack.git@31c6c9923a51c903ae83760ecbbac191363aa2a2#egg=edx_proctoring_proctortrack + +-e git+https://github.com/raccoongang/edx-ace.git@mob-develop#egg=edx_ace +-e git+https://github.com/jazzband/django-push-notifications.git@906fe52058bad36b6af2bb292fdb9292ccaa94e5#egg=django_push_notifications diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 4a0d69073588..51ef8374e024 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -4,6 +4,10 @@ # # make upgrade # +-e git+https://github.com/jazzband/django-push-notifications.git@906fe52058bad36b6af2bb292fdb9292ccaa94e5#egg=django_push_notifications + # via -r requirements/edx/base.txt +-e git+https://github.com/raccoongang/edx-ace.git@mob-develop#egg=edx_ace + # via -r requirements/edx/base.txt -e git+https://github.com/anupdhabarde/edx-proctoring-proctortrack.git@31c6c9923a51c903ae83760ecbbac191363aa2a2#egg=edx_proctoring_proctortrack # via -r requirements/edx/base.txt acid-xblock==0.3.0 @@ -119,8 +123,15 @@ botocore==1.34.45 # s3transfer bridgekeeper==0.9 # via -r requirements/edx/base.txt -cachetools==5.3.2 - # via tox +cachecontrol==0.14.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +cachetools==5.3.3 + # via + # -r requirements/edx/base.txt + # google-auth + # tox camel-converter[pydantic]==3.1.1 # via # -r requirements/edx/base.txt @@ -275,6 +286,7 @@ django==4.2.10 # django-multi-email-field # django-mysql # django-oauth-toolkit + # django-push-notifications # django-sekizai # django-ses # django-statici18n @@ -513,8 +525,6 @@ drf-yasg==1.21.5 # -r requirements/edx/base.txt # django-user-tasks # edx-api-doc-tools -edx-ace==1.8.0 - # via -r requirements/edx/base.txt edx-api-doc-tools==1.8.0 # via # -r requirements/edx/base.txt @@ -700,6 +710,10 @@ filelock==3.13.1 # snowflake-connector-python # tox # virtualenv +firebase-admin==5.0.0 + # via + # -r requirements/edx/base.txt + # edx-ace freezegun==1.4.0 # via -r requirements/edx/testing.in frozenlist==1.4.1 @@ -725,8 +739,69 @@ geoip2==4.8.0 # via -r requirements/edx/base.txt glob2==0.7 # via -r requirements/edx/base.txt +google-api-core[grpc]==1.34.1 + # via + # -r requirements/edx/base.txt + # firebase-admin + # google-api-python-client + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-api-python-client==2.127.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +google-auth==2.29.0 + # via + # -r requirements/edx/base.txt + # google-api-core + # google-api-python-client + # google-auth-httplib2 + # google-cloud-core + # google-cloud-firestore + # google-cloud-storage +google-auth-httplib2==0.2.0 + # via + # -r requirements/edx/base.txt + # google-api-python-client +google-cloud-core==2.4.1 + # via + # -r requirements/edx/base.txt + # google-cloud-firestore + # google-cloud-storage +google-cloud-firestore==2.16.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +google-cloud-storage==2.14.0 + # via + # -r requirements/edx/base.txt + # firebase-admin +google-crc32c==1.5.0 + # via + # -r requirements/edx/base.txt + # google-cloud-storage + # google-resumable-media +google-resumable-media==2.7.0 + # via + # -r requirements/edx/base.txt + # google-cloud-storage +googleapis-common-protos==1.63.0 + # via + # -r requirements/edx/base.txt + # google-api-core + # grpcio-status grimp==3.2 # via import-linter +grpcio==1.62.2 + # via + # -r requirements/edx/base.txt + # google-api-core + # grpcio-status +grpcio-status==1.48.2 + # via + # -r requirements/edx/base.txt + # google-api-core gunicorn==22.0.0 # via -r requirements/edx/base.txt h11==0.14.0 @@ -737,6 +812,11 @@ html5lib==1.1 # via # -r requirements/edx/base.txt # ora2 +httplib2==0.22.0 + # via + # -r requirements/edx/base.txt + # google-api-python-client + # google-auth-httplib2 httpretty==1.1.4 # via -r requirements/edx/testing.in icalendar==5.0.11 @@ -916,6 +996,10 @@ mpmath==1.3.0 # via # -r requirements/edx/base.txt # sympy +msgpack==1.0.8 + # via + # -r requirements/edx/base.txt + # cachecontrol multidict==6.0.5 # via # -r requirements/edx/base.txt @@ -1067,6 +1151,18 @@ prompt-toolkit==3.0.43 # via # -r requirements/edx/base.txt # click-repl +proto-plus==1.23.0 + # via + # -r requirements/edx/base.txt + # google-cloud-firestore +protobuf==3.20.3 + # via + # -r requirements/edx/base.txt + # google-api-core + # google-cloud-firestore + # googleapis-common-protos + # grpcio-status + # proto-plus psutil==5.9.8 # via # -r requirements/edx/base.txt @@ -1083,6 +1179,12 @@ pyasn1==0.5.1 # via # -r requirements/edx/base.txt # pgpy + # pyasn1-modules + # rsa +pyasn1-modules==0.4.0 + # via + # -r requirements/edx/base.txt + # google-auth pycodestyle==2.8.0 # via # -c requirements/edx/../constraints.txt @@ -1180,6 +1282,7 @@ pyparsing==3.1.1 # via # -r requirements/edx/base.txt # chem + # httplib2 # openedx-calc pyproject-api==1.6.1 # via tox @@ -1308,6 +1411,7 @@ requests==2.31.0 # -r requirements/edx/base.txt # algoliasearch # analytics-python + # cachecontrol # coreapi # django-oauth-toolkit # edx-bulk-grades @@ -1315,6 +1419,8 @@ requests==2.31.0 # edx-enterprise # edx-rest-api-client # geoip2 + # google-api-core + # google-cloud-storage # mailsnake # meilisearch # openai @@ -1338,6 +1444,10 @@ rpds-py==0.18.0 # -r requirements/edx/base.txt # jsonschema # referencing +rsa==4.9 + # via + # -r requirements/edx/base.txt + # google-auth ruamel-yaml==0.18.6 # via # -r requirements/edx/base.txt @@ -1543,6 +1653,7 @@ uritemplate==4.1.1 # coreapi # drf-spectacular # drf-yasg + # google-api-python-client urllib3==1.26.18 # via # -c requirements/edx/../constraints.txt diff --git a/setup.py b/setup.py index 4bbbe894fc77..188072354fd2 100644 --- a/setup.py +++ b/setup.py @@ -129,7 +129,8 @@ 'discussions_link = openedx.core.djangoapps.discussions.transformers:DiscussionsTopicLinkTransformer', ], "openedx.ace.policy": [ - "bulk_email_optout = lms.djangoapps.bulk_email.policies:CourseEmailOptout" + "bulk_email_optout = lms.djangoapps.bulk_email.policies:CourseEmailOptout", + "bulk_push_notification_optout = openedx.core.djangoapps.notifications.policies:CoursePushNotificationOptout", # lint-amnesty, pylint: disable=line-too-long ], "openedx.call_to_action": [ "personalized_learner_schedules = openedx.features.personalized_learner_schedules.call_to_action:PersonalizedLearnerScheduleCallToAction" # lint-amnesty, pylint: disable=line-too-long