Files
edx-platform/xmodule/modulestore/modulestore_settings.py
2022-06-20 18:20:06 +05:00

137 lines
5.5 KiB
Python

"""
This file contains helper functions for configuring module_store_setting settings and support for backward compatibility with older formats. # lint-amnesty, pylint: disable=line-too-long
"""
import copy
import warnings
def convert_module_store_setting_if_needed(module_store_setting):
"""
Converts old-style module_store_setting configuration settings to the new format.
"""
def convert_old_stores_into_list(old_stores):
"""
Converts and returns the given stores in old (unordered) dict-style format to the new (ordered) list format
"""
new_store_list = []
for store_name, store_settings in old_stores.items():
store_settings['NAME'] = store_name
if store_name == 'default':
new_store_list.insert(0, store_settings)
else:
new_store_list.append(store_settings)
# migrate request for the old 'direct' Mongo store to the Draft store
if store_settings['ENGINE'] == 'xmodule.modulestore.mongo.MongoModuleStore':
warnings.warn("MongoModuleStore is deprecated! Please use DraftModuleStore.", DeprecationWarning)
store_settings['ENGINE'] = 'xmodule.modulestore.mongo.draft.DraftModuleStore'
return new_store_list
if module_store_setting is None:
return None
# Convert to Mixed, if needed
if module_store_setting['default']['ENGINE'] != 'xmodule.modulestore.mixed.MixedModuleStore':
warnings.warn("Direct access to a modulestore is deprecated. Please use MixedModuleStore.", DeprecationWarning)
# convert to using mixed module_store
new_module_store_setting = {
"default": {
"ENGINE": "xmodule.modulestore.mixed.MixedModuleStore",
"OPTIONS": {
"mappings": {},
"stores": []
}
}
}
# copy the old configurations into the new settings
new_module_store_setting['default']['OPTIONS']['stores'] = convert_old_stores_into_list(
module_store_setting
)
module_store_setting = new_module_store_setting
# Convert from dict, if needed
elif isinstance(get_mixed_stores(module_store_setting), dict):
warnings.warn(
"Using a dict for the Stores option in the MixedModuleStore is deprecated. Please use a list instead.",
DeprecationWarning
)
# convert old-style (unordered) dict to (an ordered) list
module_store_setting['default']['OPTIONS']['stores'] = convert_old_stores_into_list(
get_mixed_stores(module_store_setting)
)
assert isinstance(get_mixed_stores(module_store_setting), list)
# Add Split, if needed
# If Split is not defined but the DraftMongoModuleStore is configured, add Split as a copy of Draft
mixed_stores = get_mixed_stores(module_store_setting)
is_split_defined = any((store['ENGINE'].endswith('.DraftVersioningModuleStore')) for store in mixed_stores)
if not is_split_defined:
# find first setting of mongo store
mongo_store = next(
(store for store in mixed_stores if (
store['ENGINE'].endswith('.DraftMongoModuleStore') or store['ENGINE'].endswith('.DraftModuleStore')
)),
None
)
if mongo_store:
# deepcopy mongo -> split
split_store = copy.deepcopy(mongo_store)
# update the ENGINE and NAME fields
split_store['ENGINE'] = 'xmodule.modulestore.split_mongo.split_draft.DraftVersioningModuleStore'
split_store['NAME'] = 'split'
# add split to the end of the list
mixed_stores.append(split_store)
return module_store_setting
def update_module_store_settings(
module_store_setting,
doc_store_settings=None,
module_store_options=None,
xml_store_options=None,
default_store=None,
mappings=None,
):
"""
Updates the settings for each store defined in the given module_store_setting settings
with the given doc store configuration and options, overwriting existing keys.
If default_store is specified, the given default store is moved to the top of the
list of stores.
"""
for store in module_store_setting['default']['OPTIONS']['stores']:
if store['NAME'] == 'xml':
xml_store_options and store['OPTIONS'].update(xml_store_options) # lint-amnesty, pylint: disable=expression-not-assigned
else:
module_store_options and store['OPTIONS'].update(module_store_options) # lint-amnesty, pylint: disable=expression-not-assigned
doc_store_settings and store['DOC_STORE_CONFIG'].update(doc_store_settings) # lint-amnesty, pylint: disable=expression-not-assigned
if default_store:
mixed_stores = get_mixed_stores(module_store_setting)
for store in mixed_stores:
if store['NAME'] == default_store:
# move the found store to the top of the list
mixed_stores.remove(store)
mixed_stores.insert(0, store)
return
raise Exception(f"Could not find setting for requested default store: {default_store}")
if mappings and 'mappings' in module_store_setting['default']['OPTIONS']:
module_store_setting['default']['OPTIONS']['mappings'] = mappings
def get_mixed_stores(mixed_setting):
"""
Helper for accessing stores in a configuration setting for the Mixed modulestore.
"""
return mixed_setting["default"]["OPTIONS"]["stores"]