Files
edx-platform/lms/startup.py
David Ormsbee 9b88bdb072 Changes to handler URL generation
* The LMS now also monkey-patches
  xmodule.x_module.descriptor_global_handler_url and
  xmodule.x_module.descriptor_global_local_resource_url so that we can
  get LMS XBlock URLs from the DescriptorSystem. That functionality is
  needed in the block transforms collect() phase for certain XModules
  like Video. For instance, say we want to generate the transcripts
  URLs. The collect phase is run asynchronously, without a user context.

* The URL handler monkey-patching is now done in the startup.py files
  for LMS and Studio. Studio used to do this in the import of
  cms/djangoapps/contentstore/views/item.py. This was mostly just
  because it seemed like a sane and consistent place to put it.

* LmsHandlerUrls was removed, its handler_url and local_resource_url
  methods were moved to be top level functions. The only reason that
  class existed seems to be to give a place to store course_id state,
  and that can now be derived from the block location.

* To avoid the Module -> Descriptor ProxyAttribute magic that we do
  (which explodes with an UndefinedContext error because there is no
  user involved), when examining the block's handler method in
  handler_url, I made a few changes:

** Check the .__class__ to see if the handler was defined, instead of the
   block itself.

** The above required me to relax the check for _is_xblock_handler on the
   function, since that will no longer be defined.

90% of this goes away when we kill XModules and do the refactoring we've
wanted to do for a while.
2015-10-28 09:42:59 -04:00

166 lines
5.8 KiB
Python

"""
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
import xmodule.x_module
import lms_xblock.runtime
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_stanford_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 analytics module by setting the write_key.
if settings.LMS_SEGMENT_KEY:
analytics.write_key = settings.LMS_SEGMENT_KEY
# register any dependency injections that we need to support in edx_proctoring
# right now edx_proctoring is dependent on the openedx.core.djangoapps.credit
# as well as the instructor dashboard (for deleting student attempts)
if settings.FEATURES.get('ENABLE_PROCTORED_EXAMS'):
# Import these here to avoid circular dependencies of the form:
# edx-platform app --> DRF --> django translation --> edx-platform app
from edx_proctoring.runtime import set_runtime_service
from instructor.services import InstructorService
from openedx.core.djangoapps.credit.services import CreditService
set_runtime_service('credit', CreditService())
set_runtime_service('instructor', InstructorService())
# In order to allow modules to use a handler url, we need to
# monkey-patch the x_module library.
# TODO: Remove this code when Runtimes are no longer created by modulestores
# https://openedx.atlassian.net/wiki/display/PLAT/Convert+from+Storage-centric+runtimes+to+Application-centric+runtimes
xmodule.x_module.descriptor_global_handler_url = lms_xblock.runtime.handler_url
xmodule.x_module.descriptor_global_local_resource_url = lms_xblock.runtime.local_resource_url
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_stanford_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 getattr(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 %s', ms_root)
else:
# not sure if we have application logging at this stage of
# startup
log.error('Error loading microsite %s. Directory does not exist', 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)