""" Module for code that should run during LMS startup """ # pylint: disable=unused-argument from django.conf import settings # Force settings to run so that the python path is modified settings.INSTALLED_APPS # pylint: disable=pointless-statement from openedx.core.lib.django_startup import autostartup import edxmako import logging from monkey_patch import django_utils_translation import analytics from util import keyword_substitution log = logging.getLogger(__name__) def run(): """ Executed during django startup """ django_utils_translation.patch() autostartup() add_mimetypes() if settings.FEATURES.get('USE_CUSTOM_THEME', False): enable_theme() if settings.FEATURES.get('USE_MICROSITES', False): enable_microsites() if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH', False): enable_third_party_auth() # Initialize Segment.io analytics module. Flushes first time a message is received and # every 50 messages thereafter, or if 10 seconds have passed since last flush if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr(settings, 'SEGMENT_IO_LMS_KEY'): analytics.init(settings.SEGMENT_IO_LMS_KEY, flush_at=50) # Monkey patch the keyword function map if keyword_substitution.keyword_function_map_is_empty(): keyword_substitution.add_keyword_function_map(get_keyword_function_map()) # Once keyword function map is set, make update function do nothing keyword_substitution.add_keyword_function_map = lambda x: None def add_mimetypes(): """ Add extra mimetypes. Used in xblock_resource. If you add a mimetype here, be sure to also add it in cms/startup.py. """ import mimetypes mimetypes.add_type('application/vnd.ms-fontobject', '.eot') mimetypes.add_type('application/x-font-opentype', '.otf') mimetypes.add_type('application/x-font-ttf', '.ttf') mimetypes.add_type('application/font-woff', '.woff') def enable_theme(): """ Enable the settings for a custom theme, whose files should be stored in ENV_ROOT/themes/THEME_NAME (e.g., edx_all/themes/stanford). """ # Workaround for setting THEME_NAME to an empty # string which is the default due to this ansible # bug: https://github.com/ansible/ansible/issues/4812 if settings.THEME_NAME == "": settings.THEME_NAME = None return assert settings.FEATURES['USE_CUSTOM_THEME'] settings.FAVICON_PATH = 'themes/{name}/images/favicon.ico'.format( name=settings.THEME_NAME ) # Calculate the location of the theme's files theme_root = settings.ENV_ROOT / "themes" / settings.THEME_NAME # Include the theme's templates in the template search paths settings.TEMPLATE_DIRS.insert(0, theme_root / 'templates') edxmako.paths.add_lookup('main', theme_root / 'templates', prepend=True) # Namespace the theme's static files to 'themes/<theme_name>' to # avoid collisions with default edX static files settings.STATICFILES_DIRS.append( (u'themes/{}'.format(settings.THEME_NAME), theme_root / 'static') ) # Include theme locale path for django translations lookup settings.LOCALE_PATHS = (theme_root / 'conf/locale',) + settings.LOCALE_PATHS def enable_microsites(): """ Enable the use of microsites, which are websites that allow for subdomains for the edX platform, e.g. foo.edx.org """ microsites_root = settings.MICROSITE_ROOT_DIR microsite_config_dict = settings.MICROSITE_CONFIGURATION for ms_name, ms_config in microsite_config_dict.items(): # Calculate the location of the microsite's files ms_root = microsites_root / ms_name ms_config = microsite_config_dict[ms_name] # pull in configuration information from each # microsite root if ms_root.isdir(): # store the path on disk for later use ms_config['microsite_root'] = ms_root template_dir = ms_root / 'templates' ms_config['template_dir'] = template_dir ms_config['microsite_name'] = ms_name log.info('Loading microsite {0}'.format(ms_root)) else: # not sure if we have application logging at this stage of # startup log.error('Error loading microsite {0}. Directory does not exist'.format(ms_root)) # remove from our configuration as it is not valid del microsite_config_dict[ms_name] # if we have any valid microsites defined, let's wire in the Mako and STATIC_FILES search paths if microsite_config_dict: settings.TEMPLATE_DIRS.append(microsites_root) edxmako.paths.add_lookup('main', microsites_root) settings.STATICFILES_DIRS.insert(0, microsites_root) def enable_third_party_auth(): """ Enable the use of third_party_auth, which allows users to sign in to edX using other identity providers. For configuration details, see common/djangoapps/third_party_auth/settings.py. """ from third_party_auth import settings as auth_settings auth_settings.apply_settings(settings.THIRD_PARTY_AUTH, settings) def get_keyword_function_map(): """ Define the mapping of keywords and filtering functions The functions are used to filter html, text and email strings before rendering them. The generated map will be monkey-patched onto the keyword_substitution module so that it persists along with the running server. Each function must take: user & course as parameters """ from student.models import anonymous_id_for_user from util.date_utils import get_default_time_display def user_id_sub(user, course): """ Gives the anonymous id for the given user For compatibility with the existing anon_ids, return anon_id without course_id """ return anonymous_id_for_user(user, None) def user_fullname_sub(user, course=None): """ Returns the given user's name """ return user.profile.name def course_display_name_sub(user, course): """ Returns the course's display name """ return course.display_name def course_end_date_sub(user, course): """ Returns the course end date in the default display """ return get_default_time_display(course.end) # Define keyword -> function map # Take care that none of these functions return %% encoded keywords kf_map = { '%%USER_ID%%': user_id_sub, '%%USER_FULLNAME%%': user_fullname_sub, '%%COURSE_DISPLAY_NAME%%': course_display_name_sub, '%%COURSE_END_DATE%%': course_end_date_sub } return kf_map