From 9322fd4a1f35a13b709cbefb5a8071dbc3d85d02 Mon Sep 17 00:00:00 2001 From: johanv26 Date: Fri, 19 Aug 2022 12:21:12 -0500 Subject: [PATCH 1/5] feat: add course creator option admin by eox nelp This allow modify the course creator model admin using the eox-nelp plugin. This change add the possibilty to add or delete course creator from admin. --- eox_nelp/admin/__init__.py | 4 ++ eox_nelp/admin/course_creators.py | 36 ++++++++++++++ eox_nelp/admin/register_admin_model.py | 17 +++++++ .../backends/course_creators_l_v1.py | 23 +++++++++ eox_nelp/edxapp_wrapper/course_creators.py | 15 ++++++ eox_nelp/settings/common.py | 47 +------------------ 6 files changed, 97 insertions(+), 45 deletions(-) create mode 100644 eox_nelp/admin/__init__.py create mode 100644 eox_nelp/admin/course_creators.py create mode 100644 eox_nelp/admin/register_admin_model.py create mode 100644 eox_nelp/edxapp_wrapper/backends/course_creators_l_v1.py create mode 100644 eox_nelp/edxapp_wrapper/course_creators.py diff --git a/eox_nelp/admin/__init__.py b/eox_nelp/admin/__init__.py new file mode 100644 index 00000000..cc605756 --- /dev/null +++ b/eox_nelp/admin/__init__.py @@ -0,0 +1,4 @@ +"""General admin module file. +Register all the nelp admin models. +""" +from eox_nelp.admin.course_creators import * diff --git a/eox_nelp/admin/course_creators.py b/eox_nelp/admin/course_creators.py new file mode 100644 index 00000000..e2bf6ea4 --- /dev/null +++ b/eox_nelp/admin/course_creators.py @@ -0,0 +1,36 @@ +"""courseCreators admin file. +Contains all the nelped admin models for course_creators. +classes: + nelpCourseCreatorAdmin: EoxNelp CourseCreators admin class. +""" +from __future__ import absolute_import + +from django.contrib import admin + +from eox_nelp.admin.register_admin_model import register_admin_model as register +from eox_nelp.edxapp_wrapper.course_creators import ( + CourseCreator, + CourseCreatorAdmin, +) + + +class NelpCourseCreatorAdmin(CourseCreatorAdmin): + """EoxSupport CertificateTemplate admin class. + This adds searching fields and shows the organization name instead of the organization id. + """ + readonly_fields = ['state_changed'] + # Controls the order on the edit form (without this, read-only fields appear at the end). + fieldsets = () + add_fieldsets = ( + (None, { + 'fields': ['username', 'state', 'state_changed', 'note', 'all_organizations', 'organizations'] + }), + ) + + def has_add_permission(self, request): + return True + def has_delete_permission(self, request, obj=None): + return True + + +register(CourseCreator, NelpCourseCreatorAdmin) diff --git a/eox_nelp/admin/register_admin_model.py b/eox_nelp/admin/register_admin_model.py new file mode 100644 index 00000000..b23e2e45 --- /dev/null +++ b/eox_nelp/admin/register_admin_model.py @@ -0,0 +1,17 @@ +"""General method to register admin models. +methods: + register_admin_model: Force register admin model. +""" +from django.contrib import admin + + +def register_admin_model(model, admin_model): + """Associate a model with the given admin model. + Args: + model: Django model. + admin_class: Admin model. + """ + if admin.site.is_registered(model): + admin.site.unregister(model) + + admin.site.register(model, admin_model) diff --git a/eox_nelp/edxapp_wrapper/backends/course_creators_l_v1.py b/eox_nelp/edxapp_wrapper/backends/course_creators_l_v1.py new file mode 100644 index 00000000..78de726a --- /dev/null +++ b/eox_nelp/edxapp_wrapper/backends/course_creators_l_v1.py @@ -0,0 +1,23 @@ +"""Backend for course_creators module. +This file contains all the necessary course_creators dependencies from +https://github.com/eduNEXT/edunext-platform/tree/master/cms/djangoapps/course_creators +""" +from cms.djangoapps.course_creators import admin, models # pylint: disable=import-error + + +def get_course_creator_model(): + """Allow to get the model CourseCreator from + https://github.com/eduNEXT/edunext-platform/tree/master/cms/djangoapps/course_creators/models.py + Returns: + CourseCreator model. + """ + return models.CourseCreator + + +def get_course_creator_admin(): + """Allow to get the openedX CourseCreatorAdmin class. + https://github.com/eduNEXT/edunext-platform/tree/master/cms/djangoapps/course_creators/admin.py + Returns: + CourseCreatorAdmin class. + """ + return admin.CourseCreatorAdmin diff --git a/eox_nelp/edxapp_wrapper/course_creators.py b/eox_nelp/edxapp_wrapper/course_creators.py new file mode 100644 index 00000000..7b00d579 --- /dev/null +++ b/eox_nelp/edxapp_wrapper/course_creators.py @@ -0,0 +1,15 @@ +"""Wrapper course_creator module file. +This contains all the required dependencies from course_creators. +Attributes: + backend:Imported ccx module by using the plugin settings. + CourseCreator: Wrapper courseCreator model. + CourseCreatorAdmin: Wrapper CourseCreatorAdmin class. +""" +from importlib import import_module + +from django.conf import settings + +backend = import_module(settings.EOX_NELP_COURSE_CREATORS_BACKEND) + +CourseCreator = backend.get_course_creator_model() +CourseCreatorAdmin = backend.get_course_creator_admin() diff --git a/eox_nelp/settings/common.py b/eox_nelp/settings/common.py index e8794e3b..6d970388 100644 --- a/eox_nelp/settings/common.py +++ b/eox_nelp/settings/common.py @@ -20,52 +20,9 @@ def plugin_settings(settings): """ - Defines eox-core settings when app is used as a plugin to edx-platform. + Defines eox-nelp settings when app is used as a plugin to edx-platform. See: https://github.com/edx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst """ - - settings.eox_nelp_ENABLE_STATICFILES_STORAGE = False - settings.eox_nelp_STATICFILES_STORAGE = "eox_nelp.storage.ProductionStorage" - settings.eox_nelp_LOAD_PERMISSIONS = True - settings.DATA_API_DEF_PAGE_SIZE = 1000 - settings.DATA_API_MAX_PAGE_SIZE = 5000 - - settings.eox_nelp_COURSE_MANAGEMENT_REQUEST_TIMEOUT = 1000 - settings.eox_nelp_USER_ENABLE_MULTI_TENANCY = True - settings.eox_nelp_USER_ORIGIN_SITE_SOURCES = ['fetch_from_unfiltered_table', ] - settings.eox_nelp_APPEND_LMS_MIDDLEWARE_CLASSES = False - settings.eox_nelp_ENABLE_UPDATE_USERS = True - settings.eox_nelp_USER_UPDATE_SAFE_FIELDS = ["is_active", "password", "fullname", "mailing_address", "year_of_birth", "gender", "level_of_education", "city", "country", "goals", "bio", "phone_number"] - settings.eox_nelp_BEARER_AUTHENTICATION = 'eox_nelp.edxapp_wrapper.backends.bearer_authentication_j_v1' - settings.eox_nelp_ASYNC_TASKS = [] - settings.eox_nelp_THIRD_PARTY_AUTH_BACKEND = 'eox_nelp.edxapp_wrapper.backends.third_party_auth_l_v1' - - if settings.eox_nelp_USER_ENABLE_MULTI_TENANCY: - settings.eox_nelp_USER_ORIGIN_SITE_SOURCES = [ - 'fetch_from_created_on_site_prop', - 'fetch_from_user_signup_source', - ] - - # Sentry Integration - settings.eox_nelp_SENTRY_INTEGRATION_DSN = None - - # The setting eox_nelp_SENTRY_IGNORED_ERRORS is a list of rules that defines which exceptions to ignore. - # An example below: - # eox_nelp_SENTRY_IGNORED_ERRORS = [ - # { - # "exc_class": "openedx.core.djangoapps.user_authn.exceptions.AuthFailedError", - # "exc_text": ["AuthFailedError.*Email or password is incorrect"] - # }, - # ] - # Every rule support only 2 keys for now: - # - exc_class: the path to the exception class we want to ignore. It can only be one - # - exc_text: a list of regex expressions to search on the last traceback frame text of the exception - - # In this example we have only one rule. We are ignoring AuthFailedError exceptions whose traceback text - # has a match with the regex provided in the exc_text unique element. If exc_text contains more than one - # regex, the exception is ignored if any of the regex matches the traceback text. - settings.eox_nelp_SENTRY_IGNORED_ERRORS = [] - settings.eox_nelp_SENTRY_ENVIRONMENT = None - + settings.EOX_NELP_COURSE_CREATORS_BACKEND = 'eox_nelp.edxapp_wrapper.backends.course_creators_l_v1' if find_spec('eox_audit_model') and EOX_AUDIT_MODEL_APP not in settings.INSTALLED_APPS: settings.INSTALLED_APPS.append(EOX_AUDIT_MODEL_APP) From 2ddf854cbb872dca32e0403ccc12dbea728fdf7c Mon Sep 17 00:00:00 2001 From: johanv26 Date: Fri, 19 Aug 2022 15:44:05 -0500 Subject: [PATCH 2/5] refactor: separate the CMS config --- eox_nelp/apps.py | 27 ++++++++++++++++++++------- setup.py | 6 +++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/eox_nelp/apps.py b/eox_nelp/apps.py index e1e4d3a6..9c3ac8c3 100644 --- a/eox_nelp/apps.py +++ b/eox_nelp/apps.py @@ -7,7 +7,7 @@ from django.apps import AppConfig -class eoxNelpConfig(AppConfig): +class EoxNelpConfig(AppConfig): """ Nelp plugin for custom development. configuration. """ @@ -20,11 +20,6 @@ class eoxNelpConfig(AppConfig): 'regex': r'^eox-nelp/', 'relative_path': 'urls', }, - 'cms.djangoapp': { - 'namespace': 'eox-nelp', - 'regex': r'^eox-nelp/', - 'relative_path': 'urls', - } }, 'settings_config': { 'lms.djangoapp': { @@ -33,9 +28,27 @@ class eoxNelpConfig(AppConfig): 'production': {'relative_path': 'settings.production'}, 'devstack': {'relative_path': 'settings.devstack'}, }, + } + } + + +class EoxNelpCMSConfig(AppConfig): + """App configuration""" + name = 'eox_nelp' + verbose_name = "eduNEXT Openedx Extensions" + + plugin_app = { + 'url_config': { + 'cms.djangoapp': { + 'namespace': 'eox-nelp', + 'regex': r'^eox-nelp/', + 'relative_path': 'urls', + } + }, + 'settings_config': { 'cms.djangoapp': { - 'common': {'relative_path': 'settings.common'}, 'test': {'relative_path': 'settings.test'}, + 'common': {'relative_path': 'settings.common'}, 'production': {'relative_path': 'settings.production'}, 'devstack': {'relative_path': 'settings.devstack'}, }, diff --git a/setup.py b/setup.py index 0b76a8cf..053d4049 100644 --- a/setup.py +++ b/setup.py @@ -92,10 +92,10 @@ def get_version(*file_paths): zip_safe=False, entry_points={ "lms.djangoapp": [ - 'eox_nelp = eox_nelp.apps:eoxNelpConfig', + 'eox_nelp = eox_nelp.apps:EoxNelpConfig', ], "cms.djangoapp": [ - 'eox_nelp = eox_nelp.apps:eoxNelpConfig', -], + 'eox_nelp = eox_nelp.apps:EoxNelpCMSConfig', + ], }, ) From edd5ed205fc254d0c9c1325e4be903af0eb75e27 Mon Sep 17 00:00:00 2001 From: johanv26 Date: Fri, 19 Aug 2022 15:50:39 -0500 Subject: [PATCH 3/5] fix: lms installed apps without course_creators Due course_creators is an studio app, when lms use `eox_nelp` it bring an error. This avoid the following error ```RuntimeError: Model class cms.djangoapps.course_creators.models.CourseCreator doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS```. So you have to add this one in the `INSTALLED_APPS`. --- eox_nelp/settings/common.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eox_nelp/settings/common.py b/eox_nelp/settings/common.py index 6d970388..46312ff0 100644 --- a/eox_nelp/settings/common.py +++ b/eox_nelp/settings/common.py @@ -16,7 +16,7 @@ 'django_countries', ) EOX_AUDIT_MODEL_APP = 'eox_audit_model.apps.EoxAuditModelConfig' - +COURSE_CREATOR_APP = 'cms.djangoapps.course_creators' def plugin_settings(settings): """ @@ -26,3 +26,5 @@ def plugin_settings(settings): settings.EOX_NELP_COURSE_CREATORS_BACKEND = 'eox_nelp.edxapp_wrapper.backends.course_creators_l_v1' if find_spec('eox_audit_model') and EOX_AUDIT_MODEL_APP not in settings.INSTALLED_APPS: settings.INSTALLED_APPS.append(EOX_AUDIT_MODEL_APP) + if COURSE_CREATOR_APP not in settings.INSTALLED_APPS: + settings.INSTALLED_APPS.append(COURSE_CREATOR_APP) From a125a7569bbfd536f28897a1a2c94aa41e39a324 Mon Sep 17 00:00:00 2001 From: johanv26 Date: Fri, 19 Aug 2022 17:12:48 -0500 Subject: [PATCH 4/5] style: apply code suggestions from review --- eox_nelp/admin/course_creators.py | 8 ++++---- eox_nelp/apps.py | 2 +- eox_nelp/edxapp_wrapper/course_creators.py | 4 ++-- eox_nelp/settings/test.py | 2 -- manage.py | 2 -- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/eox_nelp/admin/course_creators.py b/eox_nelp/admin/course_creators.py index e2bf6ea4..312ef61a 100644 --- a/eox_nelp/admin/course_creators.py +++ b/eox_nelp/admin/course_creators.py @@ -1,9 +1,8 @@ -"""courseCreators admin file. +"""CourseCreators admin file. Contains all the nelped admin models for course_creators. classes: - nelpCourseCreatorAdmin: EoxNelp CourseCreators admin class. + NelpCourseCreatorAdmin: EoxNelp CourseCreators admin class. """ -from __future__ import absolute_import from django.contrib import admin @@ -15,7 +14,7 @@ class NelpCourseCreatorAdmin(CourseCreatorAdmin): - """EoxSupport CertificateTemplate admin class. + """Nelp CourseCreatorAdmin class. This adds searching fields and shows the organization name instead of the organization id. """ readonly_fields = ['state_changed'] @@ -29,6 +28,7 @@ class NelpCourseCreatorAdmin(CourseCreatorAdmin): def has_add_permission(self, request): return True + def has_delete_permission(self, request, obj=None): return True diff --git a/eox_nelp/apps.py b/eox_nelp/apps.py index 9c3ac8c3..ae85d109 100644 --- a/eox_nelp/apps.py +++ b/eox_nelp/apps.py @@ -35,7 +35,7 @@ class EoxNelpConfig(AppConfig): class EoxNelpCMSConfig(AppConfig): """App configuration""" name = 'eox_nelp' - verbose_name = "eduNEXT Openedx Extensions" + verbose_name = "Nelp Openedx Extensions" plugin_app = { 'url_config': { diff --git a/eox_nelp/edxapp_wrapper/course_creators.py b/eox_nelp/edxapp_wrapper/course_creators.py index 7b00d579..a75891f8 100644 --- a/eox_nelp/edxapp_wrapper/course_creators.py +++ b/eox_nelp/edxapp_wrapper/course_creators.py @@ -1,8 +1,8 @@ """Wrapper course_creator module file. This contains all the required dependencies from course_creators. Attributes: - backend:Imported ccx module by using the plugin settings. - CourseCreator: Wrapper courseCreator model. + backend:Imported module by using the plugin settings. + CourseCreator: Wrapper CourseCreator model. CourseCreatorAdmin: Wrapper CourseCreatorAdmin class. """ from importlib import import_module diff --git a/eox_nelp/settings/test.py b/eox_nelp/settings/test.py index 51409c37..bf7a14a6 100644 --- a/eox_nelp/settings/test.py +++ b/eox_nelp/settings/test.py @@ -2,8 +2,6 @@ Settings for eox-nelp """ -from __future__ import absolute_import, unicode_literals - from .common import * # pylint: disable=wildcard-import, unused-wildcard-import diff --git a/manage.py b/manage.py index 1650b47e..8ec9954b 100755 --- a/manage.py +++ b/manage.py @@ -3,8 +3,6 @@ Django administration utility. """ -from __future__ import absolute_import, unicode_literals - import os import sys From 71e8c18e9cd5977ac38a022e1f2387d45ab1d9a1 Mon Sep 17 00:00:00 2001 From: johanv26 Date: Fri, 19 Aug 2022 17:27:31 -0500 Subject: [PATCH 5/5] refactor: change course-creator backend to koa Due this backend was backend was tested in koa it could add uncertainty affirm that would work in lilac too. --- .../{course_creators_l_v1.py => course_creators_k_v1.py} | 0 eox_nelp/settings/common.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename eox_nelp/edxapp_wrapper/backends/{course_creators_l_v1.py => course_creators_k_v1.py} (100%) diff --git a/eox_nelp/edxapp_wrapper/backends/course_creators_l_v1.py b/eox_nelp/edxapp_wrapper/backends/course_creators_k_v1.py similarity index 100% rename from eox_nelp/edxapp_wrapper/backends/course_creators_l_v1.py rename to eox_nelp/edxapp_wrapper/backends/course_creators_k_v1.py diff --git a/eox_nelp/settings/common.py b/eox_nelp/settings/common.py index 46312ff0..70e2b8c3 100644 --- a/eox_nelp/settings/common.py +++ b/eox_nelp/settings/common.py @@ -23,7 +23,7 @@ def plugin_settings(settings): Defines eox-nelp settings when app is used as a plugin to edx-platform. See: https://github.com/edx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst """ - settings.EOX_NELP_COURSE_CREATORS_BACKEND = 'eox_nelp.edxapp_wrapper.backends.course_creators_l_v1' + settings.EOX_NELP_COURSE_CREATORS_BACKEND = 'eox_nelp.edxapp_wrapper.backends.course_creators_k_v1' if find_spec('eox_audit_model') and EOX_AUDIT_MODEL_APP not in settings.INSTALLED_APPS: settings.INSTALLED_APPS.append(EOX_AUDIT_MODEL_APP) if COURSE_CREATOR_APP not in settings.INSTALLED_APPS: