Newer
Older
"""
Unified course experience settings and helper methods.
"""
import crum
from django.conf import settings
from django.utils.translation import ugettext as _
from edx_django_utils.monitoring import set_custom_metric
from waffle import flag_is_active
from lms.djangoapps.experiments.flags import ExperimentWaffleFlag
from openedx.core.djangoapps.util.user_messages import UserMessageCollection
Kyle Mulka
committed
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag, WaffleFlag, WaffleFlagNamespace
# Namespace for course experience waffle flags.
WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name='course_experience')
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# .. toggle_name: USE_DEFAULT_TRUE_NAMESPACE
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: When True, uses the new default_true namespace to help deprecate flag_undefined_default.
# .. toggle_category: course_experience
# .. toggle_use_cases: monitored_rollout
# .. toggle_creation_date: 2020-06-30
# .. toggle_expiration_date: 2020-07
# .. toggle_warnings: n/a
# .. toggle_tickets: n/a
# .. toggle_status: supported
_USE_DEFAULT_TRUE_NAMESPACE = 'USE_DEFAULT_TRUE_NAMESPACE'
class DefaultTrueWaffleFlagNamespace(WaffleFlagNamespace):
"""
This is a temporary class to help deprecate/remove ``flag_undefined_default``.
TODO: TNL-7061: Perform the actual clean-up required to remove these flags
and refactor/fix any tests that shouldn't be removed.
"""
def _is_flag_active(self, flag_name):
"""
Returns and caches whether the provided flag is active.
If the flag value is already cached in the request, it is returned.
If the flag doesn't exist, always returns default of True.
Note: This is a similified version of the method it overrides, that
hard codes the default to True, and skips the call back used for
course overrides:
https://github.com/edx/edx-platform/blob/df9be8c678f8266e2e5710513c74deca14c4527c/openedx/core/djangoapps/waffle_utils/__init__.py#L229-L305
"""
# Import is placed here to avoid model import at project startup.
from waffle.models import Flag
# validate arguments
namespaced_flag_name = self._namespaced_name(flag_name)
value = self._cached_flags.get(namespaced_flag_name)
if value is None:
# determine if the flag is undefined in waffle
try:
Flag.objects.get(name=namespaced_flag_name)
except Flag.DoesNotExist:
# default to True if not defined
value = True
if value is None:
request = crum.get_current_request()
if request:
value = flag_is_active(request, namespaced_flag_name)
else:
set_custom_metric('warn_flag_no_request', True)
# Return the default value if not in a request context.
# Same as the original implementation
self._set_waffle_flag_metric(namespaced_flag_name, value)
return True
self._cached_flags[namespaced_flag_name] = value
self._set_waffle_flag_metric(namespaced_flag_name, value)
return value
def is_flag_active(self, flag_name, check_before_waffle_callback=None, flag_undefined_default=None):
"""
Overrides is_flag_active if setting USE_DEFAULT_TRUE_NAMESPACE is True.
"""
use_default_true_namespace = getattr(settings, _USE_DEFAULT_TRUE_NAMESPACE, False)
set_custom_metric('temp_use_default_true_namespace', use_default_true_namespace)
if use_default_true_namespace:
return self._is_flag_active(flag_name)
else:
return super().is_flag_active(flag_name, check_before_waffle_callback, flag_undefined_default=True)
DEFAULT_TRUE_WAFFLE_FLAG_NAMESPACE = DefaultTrueWaffleFlagNamespace(name='course_experience')
# Waffle flag to enable the separate course outline page and full width content.
# NOTE: The special namespace makes the default True and skips checking course overrides.
# TODO: TNL-7061: Perform the actual clean-up required to remove this flag.
COURSE_OUTLINE_PAGE_FLAG = CourseWaffleFlag(DEFAULT_TRUE_WAFFLE_FLAG_NAMESPACE, 'course_outline_page')
# Waffle flag to enable a single unified "Course" tab.
# NOTE: The special namespace makes the default True and skips checking course overrides.
# TODO: TNL-7061: Perform the actual clean-up required to remove this flag.
UNIFIED_COURSE_TAB_FLAG = CourseWaffleFlag(DEFAULT_TRUE_WAFFLE_FLAG_NAMESPACE, 'unified_course_tab')
# Waffle flag to enable the sock on the footer of the home and courseware pages.
DISPLAY_COURSE_SOCK_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'display_course_sock')
# Waffle flag to let learners access a course before its start date.
COURSE_PRE_START_ACCESS_FLAG = WaffleFlag(WAFFLE_FLAG_NAMESPACE, 'pre_start_access')
# Waffle flag to enable a review page link from the unified home page.
# .. toggle_name: course_experience.show_reviews_tool
# .. toggle_implementation: CourseWaffleFlag
# .. toggle_default: False
# .. toggle_description: Used with our integration with CourseTalk to display reviews for a course.
# .. toggle_category: course_experience
# .. toggle_use_cases: monitored_rollout
# .. toggle_creation_date: 2017-06-19
# .. toggle_expiration_date: ???
# .. toggle_warnings: We are no longer integrating with CourseTalk, so this probably should be deprecated and the code for reviews should be removed.
# .. toggle_tickets: DEPR-48
# .. toggle_status: unsupported
SHOW_REVIEWS_TOOL_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'show_reviews_tool')
# Waffle flag to enable the setting of course goals.
# .. toggle_name: course_experience.enable_course_goals
# .. toggle_implementation: CourseWaffleFlag
# .. toggle_default: False
# .. toggle_description: Used to determine whether or not to use course goals for the particular course.
# .. toggle_category: course_experience
# .. toggle_use_cases: opt_out, monitored_rollout
# .. toggle_creation_date: 2017-09-11
# .. toggle_expiration_date: ???
# .. toggle_warnings: N/A
# .. toggle_tickets: N/A
# .. toggle_status: supported
ENABLE_COURSE_GOALS = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'enable_course_goals')
# Waffle flag to control the display of the hero
SHOW_UPGRADE_MSG_ON_COURSE_HOME = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'show_upgrade_msg_on_course_home')
# Waffle flag to control the display of the upgrade deadline message
UPGRADE_DEADLINE_MESSAGE = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'upgrade_deadline_message')
# Waffle flag to switch between the 'welcome message' and 'latest update' on the course home page.
# .. toggle_name: course_experience.latest_update
# .. toggle_implementation: CourseWaffleFlag
# .. toggle_default: False
# .. toggle_description: Used to switch between 'welcome message' and 'latest update' on the course home page.
# .. toggle_category: course_experience
# .. toggle_use_cases: opt_out
# .. toggle_creation_date: 2017-09-11
# .. toggle_expiration_date: ???
# .. toggle_warnings: This is meant to be configured using waffle_utils course override only. Either do not create the actual waffle flag, or be sure to unset the flag even for Superusers.
# .. toggle_tickets: N/A
# .. toggle_status: supported
LATEST_UPDATE_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'latest_update')
Paulo Viadanna
committed
# Waffle flag to enable anonymous access to a course
SEO_WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name='seo')
COURSE_ENABLE_UNENROLLED_ACCESS_FLAG = CourseWaffleFlag(SEO_WAFFLE_FLAG_NAMESPACE, 'enable_anonymous_courseware_access')
# Waffle flag to enable relative dates for course content
RELATIVE_DATES_FLAG = ExperimentWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'relative_dates', experiment_id=17)
# Waffle flag to enable user calendar syncing
CALENDAR_SYNC_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'calendar_sync')
def course_home_page_title(course): # pylint: disable=unused-argument
"""
Returns the title for the course home page.
"""
return _('Course')
def default_course_url_name(course_id):
"""
Returns the default course URL name for the current user.
Arguments:
course_id (CourseKey): The course id of the current course.
if COURSE_OUTLINE_PAGE_FLAG.is_enabled(course_id):
return 'openedx.course_experience.course_home'
else:
return 'courseware'
def course_home_url_name(course_key):
"""
Returns the course home page's URL name for the current user.
Arguments:
course_key (CourseKey): The course key for which the home url is being
requested.
if UNIFIED_COURSE_TAB_FLAG.is_enabled(course_key):
return 'openedx.course_experience.course_home'
else:
return 'info'
class CourseHomeMessages(UserMessageCollection):
"""
This set of messages appear above the outline on the course home page.
"""
NAMESPACE = 'course_home_level_messages'
@classmethod
def get_namespace(cls):
"""
Returns the namespace of the message collection.
"""