module_info_model.py 3.87 KB
Newer Older
1
from static_replace import replace_static_urls
2 3
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore import Location
4
from django.http import Http404
5 6


Calen Pennington committed
7
def get_module_info(store, location, parent_location=None, rewrite_static_links=False):
8 9 10 11 12 13 14 15 16
    try:
        if location.revision is None:
            module = store.get_item(location)
        else:
            module = store.get_item(location)
    except ItemNotFoundError:
        # create a new one
        template_location = Location(['i4x', 'edx', 'templates', location.category, 'Empty'])
        module = store.clone_item(template_location, location)
17

18
    data = module.data
19 20
    if rewrite_static_links:
        data = replace_static_urls(
21
            module.data,
22
            None,
23 24 25 26 27 28 29 30
            course_namespace=Location([
                module.location.tag,
                module.location.org,
                module.location.course,
                None,
                None
            ])
        )
31

Calen Pennington committed
32
    return {
33
        'id': module.location.url(),
34
        'data': data,
Calen Pennington committed
35 36
        # TODO (cpennington): This really shouldn't have to do this much reaching in to get the metadata
        'metadata': module._model_data._kvs._metadata
37 38
    }

Calen Pennington committed
39

40
def set_module_info(store, location, post_data):
Calen Pennington committed
41 42 43 44 45 46 47 48
    module = None
    try:
        if location.revision is None:
            module = store.get_item(location)
        else:
            module = store.get_item(location)
    except:
        pass
49

Calen Pennington committed
50 51 52 53 54
    if module is None:
        # new module at this location
        # presume that we have an 'Empty' template
        template_location = Location(['i4x', 'edx', 'templates', location.category, 'Empty'])
        module = store.clone_item(template_location, location)
55

Calen Pennington committed
56 57 58
    if post_data.get('data') is not None:
        data = post_data['data']
        store.update_item(location, data)
59

Calen Pennington committed
60 61 62 63 64 65
    # cdodge: note calling request.POST.get('children') will return None if children is an empty array
    # so it lead to a bug whereby the last component to be deleted in the UI was not actually
    # deleting the children object from the children collection
    if 'children' in post_data and post_data['children'] is not None:
        children = post_data['children']
        store.update_children(location, children)
66

Calen Pennington committed
67 68 69 70 71 72 73
    # cdodge: also commit any metadata which might have been passed along in the
    # POST from the client, if it is there
    # NOTE, that the postback is not the complete metadata, as there's system metadata which is
    # not presented to the end-user for editing. So let's fetch the original and
    # 'apply' the submitted metadata, so we don't end up deleting system metadata
    if post_data.get('metadata') is not None:
        posted_metadata = post_data['metadata']
74

Calen Pennington committed
75 76
        # update existing metadata with submitted metadata (which can be partial)
        # IMPORTANT NOTE: if the client passed pack 'null' (None) for a piece of metadata that means 'remove it'
77
        for metadata_key, value in posted_metadata.items():
78

Calen Pennington committed
79 80 81 82 83 84 85 86 87 88 89
            # let's strip out any metadata fields from the postback which have been identified as system metadata
            # and therefore should not be user-editable, so we should accept them back from the client
            if metadata_key in module.system_metadata_fields:
                del posted_metadata[metadata_key]
            elif posted_metadata[metadata_key] is None:
                # remove both from passed in collection as well as the collection read in from the modulestore
                if metadata_key in module._model_data:
                    del module._model_data[metadata_key]
                del posted_metadata[metadata_key]
            else:
                module._model_data[metadata_key] = value
90

Calen Pennington committed
91 92
        # commit to datastore
        # TODO (cpennington): This really shouldn't have to do this much reaching in to get the metadata
93
        store.update_metadata(location, module._model_data._kvs._metadata)