Skip to content

Commit 698a26d

Browse files
committed
chore: add functionality to export LTI in the pointer tag format
1 parent 9b1c2d2 commit 698a26d

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

xblocks_contrib/lti/lti_2_util.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@
1010
import json
1111
import logging
1212
import math
13+
import os
1314
import re
1415
from unittest import mock
1516
from urllib import parse
1617

1718
from django.conf import settings
1819
from lxml import etree
20+
from lxml.etree import ElementTree
1921
from oauthlib.oauth1 import Client
2022
from webob import Response
21-
from xblock.core import XBlock
23+
from xblock.core import XML_NAMESPACES, XBlock
2224
from xblock.fields import Dict, Scope, ScopeIds
2325

2426
from xblocks_contrib.common.xml_utils import (
@@ -533,7 +535,6 @@ def parse_xml(cls, node, runtime, keys):
533535
Returns (XBlock): The newly parsed XBlock
534536
535537
"""
536-
import pdb ; pdb.set_trace()
537538
if keys is None:
538539
# Passing keys=None is against the XBlock API but some platform tests do it.
539540
def_id = runtime.id_generator.create_definition(node.tag, node.get("url_name"))
@@ -616,3 +617,58 @@ def add_applicable_asides_to_block(cls, block, runtime, aside_children):
616617
for aside in asides:
617618
if aside.scope_ids.block_type in asides_tags:
618619
block.add_aside(aside)
620+
621+
def export_to_file(self):
622+
"""If this returns True, write the definition of this block to a separate
623+
file.
624+
"""
625+
return True
626+
627+
def add_xml_to_node(self, node):
628+
"""For exporting, set data on `node` from ourselves."""
629+
if self.data:
630+
xml_object = etree.fromstring(self.data)
631+
else:
632+
xml_object = etree.Element(self.category)
633+
634+
if xml_object is None:
635+
return
636+
637+
for aside in self.runtime.get_asides(self):
638+
if aside.needs_serialization():
639+
aside_node = etree.Element("unknown_root", nsmap=XML_NAMESPACES)
640+
aside.add_xml_to_node(aside_node)
641+
xml_object.append(aside_node)
642+
643+
self.clean_metadata_from_xml(xml_object)
644+
xml_object.tag = self.category
645+
node.tag = self.category
646+
647+
for attr in sorted(own_metadata(self)):
648+
if attr not in self.metadata_to_strip:
649+
# pylint: disable=unsubscriptable-object
650+
val = serialize_field(self.fields[attr].to_json(getattr(self, attr)))
651+
try:
652+
xml_object.set(attr, val)
653+
except Exception: # pylint: disable=broad-exception-caught
654+
logging.exception("Failed to serialize metadata attribute %s in module %s.", attr, self.url_name)
655+
656+
for key, value in self.xml_attributes.items():
657+
if key not in self.metadata_to_strip:
658+
xml_object.set(key, serialize_field(value))
659+
660+
if self.export_to_file():
661+
url_path = name_to_pathname(self.url_name)
662+
filepath = format_filepath(self.category, url_path)
663+
self.runtime.export_fs.makedirs(os.path.dirname(filepath), recreate=True)
664+
with self.runtime.export_fs.open(filepath, "wb") as fileobj:
665+
ElementTree(xml_object).write(fileobj, pretty_print=True, encoding="utf-8")
666+
else:
667+
node.clear()
668+
node.tag = xml_object.tag
669+
node.text = xml_object.text
670+
node.tail = xml_object.tail
671+
node.attrib.update(xml_object.attrib)
672+
node.extend(xml_object)
673+
674+
apply_pointer_attributes(node, self)

0 commit comments

Comments
 (0)