Make the i18n service available everywhere.
To get all dates localized, we need all runtimes to have the i18n service, and since runtimes are made by the modulestores, we need to pass it to them. Soon (fingers crossed), modulestores won't be involved in making runtimes, and many of these changes will go away.
This commit is contained in:
@@ -11,7 +11,7 @@ from edxmako.shortcuts import render_to_string
|
||||
from xmodule_modifiers import replace_static_urls, wrap_xblock
|
||||
from xmodule.error_module import ErrorDescriptor
|
||||
from xmodule.exceptions import NotFoundError, ProcessingError
|
||||
from xmodule.modulestore.django import modulestore, loc_mapper
|
||||
from xmodule.modulestore.django import modulestore, loc_mapper, ModuleI18nService
|
||||
from xmodule.modulestore.locator import Locator
|
||||
from xmodule.x_module import ModuleSystem
|
||||
from xblock.runtime import KvsFieldData
|
||||
@@ -132,6 +132,9 @@ def _preview_module_system(request, descriptor):
|
||||
# If descriptor.location is a CourseLocator, course_id is unused.
|
||||
get_user_role=lambda: get_user_role(request.user, descriptor.location, course_id),
|
||||
descriptor_runtime=descriptor.runtime,
|
||||
services={
|
||||
"i18n": ModuleI18nService(),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -408,7 +408,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
|
||||
# set the due_date_display_format to what would have been shown previously (with no timezone).
|
||||
# Then remove show_timezone so that if the user clears out the due_date_display_format,
|
||||
# they get the default date display.
|
||||
self.due_date_display_format = u"%b %d, %Y at %H:%M"
|
||||
self.due_date_display_format = "DATE_TIME"
|
||||
delattr(self, 'show_timezone')
|
||||
|
||||
# NOTE: relies on the modulestore to call set_grading_policy() right after
|
||||
|
||||
@@ -6,15 +6,17 @@ Passes settings.MODULESTORE as kwargs to MongoModuleStore
|
||||
|
||||
from __future__ import absolute_import
|
||||
from importlib import import_module
|
||||
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import get_cache, InvalidCacheBackendError
|
||||
from django.dispatch import Signal
|
||||
import django.utils
|
||||
|
||||
from xmodule.modulestore.loc_mapper_store import LocMapperStore
|
||||
from xmodule.util.django import get_current_request_hostname
|
||||
|
||||
|
||||
# We may not always have the request_cache module available
|
||||
try:
|
||||
from request_cache.middleware import RequestCache
|
||||
@@ -38,7 +40,7 @@ def load_function(path):
|
||||
return getattr(import_module(module_path), name)
|
||||
|
||||
|
||||
def create_modulestore_instance(engine, doc_store_config, options):
|
||||
def create_modulestore_instance(engine, doc_store_config, options, i18n_service=None):
|
||||
"""
|
||||
This will return a new instance of a modulestore given an engine and options
|
||||
"""
|
||||
@@ -68,6 +70,7 @@ def create_modulestore_instance(engine, doc_store_config, options):
|
||||
xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
|
||||
xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
|
||||
doc_store_config=doc_store_config,
|
||||
i18n_service=i18n_service or ModuleI18nService(),
|
||||
**_options
|
||||
)
|
||||
|
||||
@@ -186,3 +189,33 @@ def editable_modulestore(name='default'):
|
||||
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class ModuleI18nService(object):
|
||||
"""
|
||||
Implement the XBlock runtime "i18n" service.
|
||||
|
||||
Mostly a pass-through to Django's translation module.
|
||||
django.utils.translation implements the gettext.Translations interface (it
|
||||
has ugettext, ungettext, etc), so we can use it directly as the runtime
|
||||
i18n service.
|
||||
|
||||
"""
|
||||
def __getattr__(self, name):
|
||||
return getattr(django.utils.translation, name)
|
||||
|
||||
def strftime(self, *args, **kwargs):
|
||||
"""
|
||||
A locale-aware implementation of strftime.
|
||||
"""
|
||||
# This is the wrong place to import this function. I'm putting it here
|
||||
# because the xmodule test suite can't import this module, because
|
||||
# Django is not available in that suite. This function isn't called in
|
||||
# that suite, so this hides the import so the test won't fail.
|
||||
#
|
||||
# As I said, this is wrong. But Cale says this code will soon be
|
||||
# refactored to a place that will be right, and the code can be made
|
||||
# right there. If you are reading this comment after April 1, 2014,
|
||||
# then Cale was a liar.
|
||||
from util.date_utils import strftime_localized
|
||||
return strftime_localized(*args, **kwargs)
|
||||
|
||||
@@ -23,7 +23,7 @@ class MixedModuleStore(ModuleStoreWriteBase):
|
||||
ModuleStore knows how to route requests to the right persistence ms and how to convert any
|
||||
references in the xblocks to the type required by the app and the persistence layer.
|
||||
"""
|
||||
def __init__(self, mappings, stores, reference_type=None, **kwargs):
|
||||
def __init__(self, mappings, stores, reference_type=None, i18n_service=None, **kwargs):
|
||||
"""
|
||||
Initialize a MixedModuleStore. Here we look into our passed in kwargs which should be a
|
||||
collection of other modulestore configuration informations
|
||||
@@ -55,7 +55,8 @@ class MixedModuleStore(ModuleStoreWriteBase):
|
||||
store['ENGINE'],
|
||||
# XMLModuleStore's don't have doc store configs
|
||||
store.get('DOC_STORE_CONFIG', {}),
|
||||
store['OPTIONS']
|
||||
store['OPTIONS'],
|
||||
i18n_service=i18n_service,
|
||||
)
|
||||
|
||||
def _get_modulestore_for_courseid(self, course_id):
|
||||
|
||||
@@ -263,6 +263,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
|
||||
def __init__(self, doc_store_config, fs_root, render_template,
|
||||
default_class=None,
|
||||
error_tracker=null_error_tracker,
|
||||
i18n_service=None,
|
||||
**kwargs):
|
||||
"""
|
||||
:param doc_store_config: must have a host, db, and collection entries. Other common entries: port, tz_aware.
|
||||
@@ -312,6 +313,8 @@ class MongoModuleStore(ModuleStoreWriteBase):
|
||||
self.fs_root = path(fs_root)
|
||||
self.error_tracker = error_tracker
|
||||
self.render_template = render_template
|
||||
self.i18n_service = i18n_service
|
||||
|
||||
self.ignore_write_events_on_courses = []
|
||||
|
||||
def compute_metadata_inheritance_tree(self, location):
|
||||
@@ -498,6 +501,10 @@ class MongoModuleStore(ModuleStoreWriteBase):
|
||||
if apply_cached_metadata:
|
||||
cached_metadata = self.get_cached_metadata_inheritance_tree(location)
|
||||
|
||||
services = {}
|
||||
if self.i18n_service:
|
||||
services["i18n"] = self.i18n_service
|
||||
|
||||
# TODO (cdodge): When the 'split module store' work has been completed, we should remove
|
||||
# the 'metadata_inheritance_tree' parameter
|
||||
system = CachingDescriptorSystem(
|
||||
@@ -510,6 +517,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
|
||||
cached_metadata=cached_metadata,
|
||||
mixins=self.xblock_mixins,
|
||||
select=self.xblock_select,
|
||||
services=services,
|
||||
)
|
||||
return system.load_item(location)
|
||||
|
||||
@@ -631,6 +639,10 @@ class MongoModuleStore(ModuleStoreWriteBase):
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
if system is None:
|
||||
services = {}
|
||||
if self.i18n_service:
|
||||
services["i18n"] = self.i18n_service
|
||||
|
||||
system = CachingDescriptorSystem(
|
||||
modulestore=self,
|
||||
module_data={},
|
||||
@@ -641,6 +653,7 @@ class MongoModuleStore(ModuleStoreWriteBase):
|
||||
cached_metadata={},
|
||||
mixins=self.xblock_mixins,
|
||||
select=self.xblock_select,
|
||||
services=services,
|
||||
)
|
||||
xblock_class = system.load_block_type(location.category)
|
||||
if definition_data is None:
|
||||
|
||||
@@ -105,6 +105,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
|
||||
default_class=None,
|
||||
error_tracker=null_error_tracker,
|
||||
loc_mapper=None,
|
||||
i18n_service=None,
|
||||
**kwargs):
|
||||
"""
|
||||
:param doc_store_config: must have a host, db, and collection entries. Other common entries: port, tz_aware.
|
||||
@@ -129,6 +130,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
|
||||
self.fs_root = path(fs_root)
|
||||
self.error_tracker = error_tracker
|
||||
self.render_template = render_template
|
||||
self.i18n_service = i18n_service
|
||||
|
||||
# TODO: Don't have a runtime just to generate the appropriate mixin classes (cpennington)
|
||||
# This is only used by _partition_fields_by_scope, which is only needed because
|
||||
@@ -180,6 +182,10 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
|
||||
'''
|
||||
system = self._get_cache(course_entry['structure']['_id'])
|
||||
if system is None:
|
||||
services = {}
|
||||
if self.i18n_service:
|
||||
services["i18n"] = self.i18n_service
|
||||
|
||||
system = CachingDescriptorSystem(
|
||||
modulestore=self,
|
||||
course_entry=course_entry,
|
||||
@@ -191,6 +197,7 @@ class SplitMongoModuleStore(ModuleStoreWriteBase):
|
||||
resources_fs=None,
|
||||
mixins=self.xblock_mixins,
|
||||
select=self.xblock_select,
|
||||
services=services,
|
||||
)
|
||||
self._add_cache(course_entry['structure']['_id'], system)
|
||||
self.cache_items(system, block_ids, depth, lazy)
|
||||
|
||||
@@ -347,8 +347,10 @@ class XMLModuleStore(ModuleStoreReadBase):
|
||||
"""
|
||||
An XML backed ModuleStore
|
||||
"""
|
||||
def __init__(self, data_dir, default_class=None, course_dirs=None, course_ids=None,
|
||||
load_error_modules=True, **kwargs):
|
||||
def __init__(
|
||||
self, data_dir, default_class=None, course_dirs=None, course_ids=None,
|
||||
load_error_modules=True, i18n_service=None, **kwargs
|
||||
):
|
||||
"""
|
||||
Initialize an XMLModuleStore from data_dir
|
||||
|
||||
@@ -382,6 +384,8 @@ class XMLModuleStore(ModuleStoreReadBase):
|
||||
# All field data will be stored in an inheriting field data.
|
||||
self.field_data = inheriting_field_data(kvs=DictKeyValueStore())
|
||||
|
||||
self.i18n_service = i18n_service
|
||||
|
||||
# If we are specifically asked for missing courses, that should
|
||||
# be an error. If we are asked for "all" courses, find the ones
|
||||
# that have a course.xml. We sort the dirs in alpha order so we always
|
||||
@@ -522,6 +526,10 @@ class XMLModuleStore(ModuleStoreReadBase):
|
||||
"""
|
||||
return policy.get(policy_key(usage_id), {})
|
||||
|
||||
services = {}
|
||||
if self.i18n_service:
|
||||
services['i18n'] = self.i18n_service
|
||||
|
||||
system = ImportSystem(
|
||||
xmlstore=self,
|
||||
course_id=course_id,
|
||||
@@ -534,6 +542,7 @@ class XMLModuleStore(ModuleStoreReadBase):
|
||||
default_class=self.default_class,
|
||||
select=self.xblock_select,
|
||||
field_data=self.field_data,
|
||||
services=services,
|
||||
)
|
||||
|
||||
course_descriptor = system.process_xml(etree.tostring(course_data, encoding='unicode'))
|
||||
|
||||
@@ -37,7 +37,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2014-02-19 15:39-0500\n"
|
||||
"POT-Creation-Date: 2014-02-20 13:02-0500\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
||||
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2014-02-19 15:38-0500\n"
|
||||
"PO-Revision-Date: 2014-02-19 20:39:50.876422\n"
|
||||
"POT-Creation-Date: 2014-02-20 13:01-0500\n"
|
||||
"PO-Revision-Date: 2014-02-20 18:02:05.375610\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
||||
@@ -13,7 +13,6 @@ from django.core.cache import cache
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import Http404, HttpResponse
|
||||
import django.utils
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from capa.xqueue_interface import XQueueInterface
|
||||
@@ -33,14 +32,13 @@ from xblock.django.request import django_to_webob_request, webob_to_django_respo
|
||||
from xmodule.error_module import ErrorDescriptor, NonStaffErrorDescriptor
|
||||
from xmodule.exceptions import NotFoundError, ProcessingError
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.django import modulestore, ModuleI18nService
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.util.duedate import get_extended_due_date
|
||||
from xmodule_modifiers import replace_course_urls, replace_jump_to_id_urls, replace_static_urls, add_staff_debug_info, wrap_xblock
|
||||
from xmodule.lti_module import LTIModule
|
||||
from xmodule.x_module import XModuleDescriptor
|
||||
|
||||
from util.date_utils import strftime_localized
|
||||
from util.json_request import JsonResponse
|
||||
from util.sandboxing import can_execute_unsafe_code
|
||||
|
||||
@@ -651,20 +649,3 @@ def _check_files_limits(files):
|
||||
return msg
|
||||
|
||||
return None
|
||||
|
||||
|
||||
class ModuleI18nService(object):
|
||||
"""
|
||||
Implement the XBlock runtime "i18n" service.
|
||||
|
||||
Mostly a pass-through to Django's translation module.
|
||||
django.utils.translation implements the gettext.Translations interface (it
|
||||
has ugettext, ungettext, etc), so we can use it directly as the runtime
|
||||
i18n service.
|
||||
|
||||
"""
|
||||
def __getattr__(self, name):
|
||||
return getattr(django.utils.translation, name)
|
||||
|
||||
def strftime(self, *args, **kwargs):
|
||||
return strftime_localized(*args, **kwargs)
|
||||
|
||||
@@ -7,6 +7,8 @@ from django.conf import settings
|
||||
from xmodule.open_ended_grading_classes import peer_grading_service
|
||||
from xmodule.open_ended_grading_classes.controller_query_service import ControllerQueryService
|
||||
|
||||
from xmodule.modulestore.django import ModuleI18nService
|
||||
|
||||
from courseware.access import has_access
|
||||
from lms.lib.xblock.runtime import LmsModuleSystem
|
||||
from edxmako.shortcuts import render_to_string
|
||||
@@ -70,6 +72,9 @@ def peer_grading_notifications(course, user):
|
||||
render_template=render_to_string,
|
||||
replace_urls=None,
|
||||
descriptor_runtime=None,
|
||||
services={
|
||||
'i18n': ModuleI18nService(),
|
||||
},
|
||||
)
|
||||
peer_gs = peer_grading_service.PeerGradingService(settings.OPEN_ENDED_GRADING_INTERFACE, system)
|
||||
pending_grading = False
|
||||
@@ -131,6 +136,9 @@ def combined_notifications(course, user):
|
||||
render_template=render_to_string,
|
||||
replace_urls=None,
|
||||
descriptor_runtime=None,
|
||||
services={
|
||||
'i18n': ModuleI18nService(),
|
||||
},
|
||||
)
|
||||
#Initialize controller query service using our mock system
|
||||
controller_qs = ControllerQueryService(settings.OPEN_ENDED_GRADING_INTERFACE, system)
|
||||
|
||||
@@ -11,6 +11,7 @@ from django.utils.translation import ugettext as _
|
||||
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from xmodule.open_ended_grading_classes.grading_service_module import GradingService, GradingServiceError
|
||||
from xmodule.modulestore.django import ModuleI18nService
|
||||
|
||||
from courseware.access import has_access
|
||||
from lms.lib.xblock.runtime import LmsModuleSystem
|
||||
@@ -84,6 +85,9 @@ class StaffGradingService(GradingService):
|
||||
render_template=render_to_string,
|
||||
replace_urls=None,
|
||||
descriptor_runtime=None,
|
||||
services={
|
||||
'i18n': ModuleI18nService(),
|
||||
},
|
||||
)
|
||||
super(StaffGradingService, self).__init__(config)
|
||||
self.url = config['url'] + config['staff_grading']
|
||||
|
||||
@@ -2,7 +2,7 @@ import json
|
||||
import logging
|
||||
|
||||
from xmodule.modulestore import search
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.django import modulestore, ModuleI18nService
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem
|
||||
from xmodule.open_ended_grading_classes.controller_query_service import ControllerQueryService
|
||||
from xmodule.open_ended_grading_classes.grading_service_module import GradingServiceError
|
||||
@@ -34,6 +34,9 @@ SYSTEM = LmsModuleSystem(
|
||||
render_template=render_to_string,
|
||||
replace_urls=None,
|
||||
descriptor_runtime=None,
|
||||
services={
|
||||
'i18n': ModuleI18nService(),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user