Add switch to disable forum digest in prod.

This commit is contained in:
Awais Jibran
2020-03-09 17:12:39 +05:00
parent fa7cae74e0
commit 88c6d412e5
8 changed files with 112 additions and 78 deletions

View File

@@ -1,12 +0,0 @@
"""
Discussion settings and flags.
"""
from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace
# Namespace for course experience waffle flags.
WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name='edx_discussions')
# Waffle flag to enable the use of Bootstrap
USE_BOOTSTRAP_FLAG = WaffleFlag(WAFFLE_FLAG_NAMESPACE, 'use_bootstrap', flag_undefined_default=True)

View File

@@ -0,0 +1,39 @@
"""
Discussion settings and flags.
"""
from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace
USE_BOOTSTRAP = 'use_bootstrap'
ENABLE_FORUM_DAILY_DIGEST = 'enable_forum_daily_digest'
def waffle_flags():
"""
Returns the namespaced, cached, audited Waffle flags dictionary for Grades.
"""
namespace = WaffleFlagNamespace(name='edx_discussions')
return {
# Waffle flag to enable the use of Bootstrap
USE_BOOTSTRAP: WaffleFlag(
namespace,
USE_BOOTSTRAP,
flag_undefined_default=True
),
# By default, enable forum notifications. Can be disabled platform wide.
ENABLE_FORUM_DAILY_DIGEST: WaffleFlag(
namespace,
ENABLE_FORUM_DAILY_DIGEST,
flag_undefined_default=True
),
}
def use_bootstrap_flag_enabled():
"""Returns whether use of bootstrap is enabled."""
return waffle_flags()[USE_BOOTSTRAP].is_enabled()
def is_forum_daily_digest_enabled():
"""Returns whether forum notification features should be visible"""
return waffle_flags()[ENABLE_FORUM_DAILY_DIGEST].is_enabled()

View File

@@ -8,10 +8,9 @@ from django.utils.translation import ugettext_noop
import lms.djangoapps.discussion.django_comment_client.utils as utils
from lms.djangoapps.courseware.tabs import EnrolledTab
from lms.djangoapps.discussion.config.waffle import use_bootstrap_flag_enabled
from xmodule.tabs import TabFragmentViewMixin
from .config import USE_BOOTSTRAP_FLAG
class DiscussionTab(TabFragmentViewMixin, EnrolledTab):
"""
@@ -39,4 +38,4 @@ class DiscussionTab(TabFragmentViewMixin, EnrolledTab):
"""
Returns true if this tab is rendered with Bootstrap.
"""
return USE_BOOTSTRAP_FLAG.is_enabled()
return use_bootstrap_flag_enabled()

View File

@@ -44,19 +44,21 @@
<span class="row-description"><%- gettext("Follow or unfollow posts") %></span>
</td>
</tr>
<tr class="helpgrid-row helpgrid-row-notification">
<th scope="row" class="row-title"><%- gettext('Receive updates') %></td>
<td class="row-item-full" colspan="3">
<label for="email-setting-checkbox">
<span class="sr"><%- gettext("Toggle Notifications Setting") %></span>
<span class="notification-checkbox">
<input type="checkbox" id="email-setting-checkbox" class="email-setting" name="email-notification"/>
<span class="icon fa fa-envelope" aria-hidden="true"></span>
</span>
</label>
<span class="row-description"><%- gettext("Check this box to receive an email digest once a day notifying you about new, unread activity from posts you are following.") %></span>
</td>
</tr>
<% if (window.ENABLE_FORUM_DAILY_DIGEST) {%>
<tr class="helpgrid-row helpgrid-row-notification">
<th scope="row" class="row-title"><%- gettext('Receive updates') %></td>
<td class="row-item-full" colspan="3">
<label for="email-setting-checkbox">
<span class="sr"><%- gettext("Toggle Notifications Setting") %></span>
<span class="notification-checkbox">
<input type="checkbox" id="email-setting-checkbox" class="email-setting" name="email-notification"/>
<span class="icon fa fa-envelope" aria-hidden="true"></span>
</span>
</label>
<span class="row-description"><%- gettext("Check this box to receive an email digest once a day notifying you about new, unread activity from posts you are following.") %></span>
</td>
</tr>
<% } %>
</table>
<% } %>
</div>

View File

@@ -30,6 +30,7 @@ import openedx.core.djangoapps.django_comment_common.comment_client as cc
from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.courseware.courses import get_course_with_access
from lms.djangoapps.courseware.views.views import CourseTabView
from lms.djangoapps.discussion.config.waffle import is_forum_daily_digest_enabled, use_bootstrap_flag_enabled
from lms.djangoapps.discussion.django_comment_client.base.views import track_thread_viewed_event
from lms.djangoapps.discussion.django_comment_client.constants import TYPE_ENTRY
from lms.djangoapps.discussion.django_comment_client.permissions import has_permission
@@ -59,8 +60,6 @@ from student.models import CourseEnrollment
from util.json_request import JsonResponse, expect_json
from xmodule.modulestore.django import modulestore
from .config import USE_BOOTSTRAP_FLAG
log = logging.getLogger("edx.discussions")
@@ -433,7 +432,7 @@ def _create_base_discussion_view_context(request, course_key):
user_info = cc_user.to_dict()
course = get_course_with_access(user, 'load', course_key, check_if_enrolled=True)
course_settings = make_course_settings(course, user)
uses_bootstrap = USE_BOOTSTRAP_FLAG.is_enabled()
uses_bootstrap = use_bootstrap_flag_enabled()
return {
'csrf': csrf(request)['csrf_token'],
'course': course,
@@ -519,6 +518,7 @@ def _create_discussion_board_context(request, base_context, thread=None):
'is_commentable_divided': is_commentable_divided(course_key, discussion_id, course_discussion_settings),
# If the default topic id is None the front-end code will look for a topic that contains "General"
'discussion_default_topic_id': _get_discussion_default_topic_id(course),
'enable_daily_digest': is_forum_daily_digest_enabled()
})
context.update(
get_experiment_user_metadata_context(
@@ -818,7 +818,7 @@ class DiscussionBoardFragmentView(EdxFragmentView):
the files are loaded individually, but in production just the single bundle is loaded.
"""
is_right_to_left = get_language_bidi()
if USE_BOOTSTRAP_FLAG.is_enabled():
if use_bootstrap_flag_enabled():
css_file = BOOTSTRAP_DISCUSSION_CSS_PATH
if is_right_to_left:
css_file = css_file.replace('.css', '-rtl.css')

View File

@@ -100,6 +100,11 @@ FEATURES = {
# this should remain off in production until digest notifications are online.
'ENABLE_DISCUSSION_HOME_PANEL': False,
# settings for forums/discussions to on/off daily digest feature. Set this to True if you want to
# enable the UI for the users to subscribe and unsubscribe for daily digest. This setting is the
# part of deprecation of daily digest in production.
'ENABLE_FORUM_DAILY_DIGEST': True,
# Set this to True if you want the discussion digest emails enabled automatically for new users.
# This will be set on all new account registrations.
# It is not recommended to enable this feature if ENABLE_DISCUSSION_HOME_PANEL is not enabled, since

View File

@@ -1,13 +1,23 @@
<%page expression_filter="h"/>
<%namespace name='static' file='../static_content.html'/>
<%! from openedx.core.djangolib.js_utils import js_escaped_string %>
<%
from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string
enable_discussion_home_panel = settings.FEATURES.get('ENABLE_DISCUSSION_HOME_PANEL', False)
%>
<script type="text/javascript">
window.PLATFORM_NAME = "${settings.PLATFORM_NAME | n, js_escaped_string}";
% if settings.FEATURES.get('ENABLE_DISCUSSION_HOME_PANEL', False):
% if enable_discussion_home_panel:
window.ENABLE_DISCUSSION_HOME_PANEL = true;
% else:
window.ENABLE_DISCUSSION_HOME_PANEL = false;
% endif
% if enable_daily_digest:
window.ENABLE_FORUM_DAILY_DIGEST = true;
% else:
window.ENABLE_FORUM_DAILY_DIGEST = false;
% endif
</script>
<%static:include path="common/templates/discussion/templates.underscore" />

View File

@@ -2,7 +2,6 @@
URLs for LMS
"""
from config_models.views import ConfigurationModelCurrentAPIView
from django.conf import settings
from django.conf.urls import include, url
@@ -10,26 +9,29 @@ from django.conf.urls.static import static
from django.contrib.admin import autodiscover as django_autodiscover
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import RedirectView
from edx_api_doc_tools import make_docs_urls
from ratelimitbackend import admin
from edx_api_doc_tools import make_docs_urls
from branding import views as branding_views
from debug import views as debug_views
from lms.djangoapps.certificates import views as certificates_views
from lms.djangoapps.courseware.masquerade import handle_ajax as courseware_masquerade_handle_ajax
from lms.djangoapps.courseware.module_render import (
handle_xblock_callback, handle_xblock_callback_noauth, xblock_view, xqueue_callback,
handle_xblock_callback,
handle_xblock_callback_noauth,
xblock_view,
xqueue_callback
)
from lms.djangoapps.courseware.views import views as courseware_views
from lms.djangoapps.courseware.views.index import CoursewareIndex
from lms.djangoapps.courseware.views.views import CourseTabView, EnrollStaffView, StaticCourseTabView
from debug import views as debug_views
from lms.djangoapps.certificates import views as certificates_views
from lms.djangoapps.discussion import views as discussion_views
from lms.djangoapps.discussion.notification_prefs import views as notification_prefs_views
from lms.djangoapps.instructor.views import coupons as instructor_coupons_views
from lms.djangoapps.instructor.views import instructor_dashboard as instructor_dashboard_views
from lms.djangoapps.instructor.views import registration_codes as instructor_registration_codes_views
from lms.djangoapps.instructor_task import views as instructor_task_views
from openedx.core.apidocs import api_info
from openedx.core.djangoapps.auth_exchange.views import LoginWithAccessTokenView
from openedx.core.djangoapps.catalog.models import CatalogIntegration
from openedx.core.djangoapps.common_views.xblock import xblock_resource
@@ -47,7 +49,6 @@ from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_authn.views.login import redirect_to_lms_login
from openedx.core.djangoapps.verified_track_content import views as verified_track_content_views
from openedx.core.apidocs import api_info
from openedx.features.enterprise_support.api import enterprise_enabled
from static_template_view import views as static_template_view_views
from staticbook import views as staticbook_views
@@ -68,8 +69,28 @@ if settings.DEBUG or settings.FEATURES.get('ENABLE_DJANGO_ADMIN_SITE'):
handler404 = static_template_view_views.render_404
handler500 = static_template_view_views.render_500
notification_prefs_urls = [
url(r'^notification_prefs/enable/', notification_prefs_views.ajax_enable),
url(r'^notification_prefs/disable/', notification_prefs_views.ajax_disable),
url(r'^notification_prefs/status/', notification_prefs_views.ajax_status),
url(
r'^notification_prefs/unsubscribe/(?P<token>[a-zA-Z0-9-_=]+)/',
notification_prefs_views.set_subscription,
{'subscribe': False},
name='unsubscribe_forum_update',
),
url(
r'^notification_prefs/resubscribe/(?P<token>[a-zA-Z0-9-_=]+)/',
notification_prefs_views.set_subscription,
{'subscribe': True},
name='resubscribe_forum_update',
),
]
urlpatterns = [
url(r'^$', branding_views.index, name='root'), # Main marketing page, or redirect to courseware
url(r'^$', branding_views.index, name='root'), # Main marketing page, or redirect to courseware
url(r'', include('student.urls')),
# TODO: Move lms specific student views out of common code
@@ -108,7 +129,6 @@ urlpatterns = [
# subsumed by api/user listed above.
url(r'', include('openedx.core.djangoapps.user_api.legacy_urls')),
# Profile Images API endpoints
url(r'^api/profile_images/', include('openedx.core.djangoapps.profile_images.urls')),
@@ -164,7 +184,6 @@ urlpatterns += [
url(r'^openassessment/fileupload/', include('openassessment.fileupload.urls')),
]
# sysadmin dashboard, to see what courses are loaded, to delete & load courses
if settings.FEATURES.get('ENABLE_SYSADMIN_DASHBOARD'):
urlpatterns += [
@@ -299,7 +318,7 @@ urlpatterns += [
url(r'^courses/?$', branding_views.courses, name='courses'),
#About the course
# About the course
url(
r'^courses/{}/about$'.format(
settings.COURSE_ID_PATTERN,
@@ -320,7 +339,7 @@ urlpatterns += [
name='enroll_staff',
),
#Inside the course
# Inside the course
url(
r'^courses/{}/$'.format(
settings.COURSE_ID_PATTERN,
@@ -486,7 +505,6 @@ urlpatterns += [
name='instructor_dashboard',
),
url(
r'^courses/{}/set_course_mode_price$'.format(
settings.COURSE_ID_PATTERN,
@@ -714,36 +732,11 @@ if settings.FEATURES.get('ENABLE_DISCUSSION_SERVICE'):
),
include('lms.djangoapps.discussion.django_comment_client.urls')
),
url(
r'^notification_prefs/enable/',
notification_prefs_views.ajax_enable
),
url(
r'^notification_prefs/disable/',
notification_prefs_views.ajax_disable
),
url(
r'^notification_prefs/status/',
notification_prefs_views.ajax_status
),
url(
r'^notification_prefs/unsubscribe/(?P<token>[a-zA-Z0-9-_=]+)/',
notification_prefs_views.set_subscription,
{
'subscribe': False,
},
name='unsubscribe_forum_update',
),
url(
r'^notification_prefs/resubscribe/(?P<token>[a-zA-Z0-9-_=]+)/',
notification_prefs_views.set_subscription,
{
'subscribe': True,
},
name='resubscribe_forum_update',
),
]
if settings.FEATURES.get('ENABLE_FORUM_DAILY_DIGEST'):
urlpatterns += notification_prefs_urls
urlpatterns += [
url(r'^bulk_email/', include('bulk_email.urls')),
]
@@ -804,7 +797,6 @@ if configuration_helpers.get_value('ENABLE_BULK_ENROLLMENT_VIEW', settings.FEATU
url(r'^api/bulk_enroll/v1/', include('bulk_enroll.urls')),
]
# Shopping cart
urlpatterns += [
url(r'^shoppingcart/', include('shoppingcart.urls')),
@@ -842,7 +834,6 @@ if settings.FEATURES.get('ENABLE_OAUTH2_PROVIDER'):
url(r'^_o/', include('oauth2_provider.urls', namespace='oauth2_provider')),
]
if settings.FEATURES.get('ENABLE_SERVICE_STATUS'):
urlpatterns += [
url(r'^status/', include('openedx.core.djangoapps.service_status.urls')),
@@ -866,7 +857,6 @@ urlpatterns += [
url(r'^debug/show_parameters$', debug_views.show_parameters),
]
# Third-party auth.
if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH'):
urlpatterns += [
@@ -948,6 +938,7 @@ urlpatterns += [
if 'debug_toolbar' in settings.INSTALLED_APPS:
import debug_toolbar
urlpatterns += [
url(r'^__debug__/', include(debug_toolbar.urls)),
]