Skip to content
This repository
Browse code

copy files referenced in superfluous manifest files

some vendors create a manifest file for each question and
related file, this makes it so that the files referenced
in there are copied and become part of the single manifest
when finished. It also grabs the expected output name from
the webct meta data.

refs #8051 #8671

Change-Id: I0e3f3211123dd5301335538f5f332717cc457746
Reviewed-on: https://gerrit.instructure.com/10936
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
  • Loading branch information...
commit 385548ab9e605f36ce652415a5d6e3c9b847a8bc 1 parent 805367b
Bracken Mosbacker bracken authored

Showing 2 changed files with 88 additions and 11 deletions. Show diff stats Hide diff stats

  1. +13 0 lib/imscp.py
  2. +75 11 lib/imsqtiv1.py
13 lib/imscp.py
@@ -196,10 +196,23 @@ def GetQTIMD (self):
196 196 return self.qtiMD
197 197
198 198 def AddFile (self,cpf,entryPoint=0):
  199 + for file in self.files:
  200 + if file.href == cpf.href:
  201 + return
199 202 self.files.append(cpf)
200 203 if entryPoint:
201 204 self.entryPoint=cpf
202 205
  206 + def update_file_path(self, uri, dest_path, data_path):
  207 + cpf = None
  208 + for file in self.files:
  209 + if file.href == uri or file.href == dest_path or file.dataPath == data_path:
  210 + cpf = file
  211 + break
  212 + if cpf:
  213 + cpf.href = dest_path
  214 + cpf.dataPath = data_path
  215 +
203 216 def DumpToDirectory (self,path,create_error_files=None):
204 217 for f in self.files:
205 218 f.DumpToDirectory(path,create_error_files)
86 lib/imsqtiv1.py
@@ -306,14 +306,14 @@ def __init__(self, name, attrs, parent):
306 306 self.cp=None
307 307
308 308 def SetPath (self,path):
309   - self.path=path
  309 + if self.path is None:
  310 + self.path=path
310 311
311 312 def SetCP(self,cp):
312 313 self.cp=cp
313 314 self.cp.AddResource(self.resource)
314 315
315 316 def AddCPFile (self,uri):
316   - print "\n\nHref: %s" % uri
317 317 if uri[-4:].lower() in ['.xml', '.dat', '.qti']:
318 318 return uri
319 319 if self.files.has_key(uri):
@@ -342,6 +342,13 @@ def ResolveURI (self,uri):
342 342 path=os.path.join(path,DecodePathSegment(segment))
343 343 return path
344 344
  345 + def update_file_path(self, path):
  346 + if len(self.files) == 1:
  347 + uri = self.files.values()[0]
  348 + if uri != path:
  349 + self.resource.update_file_path(uri, path, self.GetRoot().ResolveURI(uri))
  350 +
  351 +
345 352 class Resources(QTIObjectV1):
346 353 def __init__(self, name, attrs, parent):
347 354 self.parent = parent
@@ -779,6 +786,49 @@ def CloseObject (self):
779 786 self.parent.AppendElement(xhtml_text(self.data))
780 787
781 788
  789 +# webct:ContentObject
  790 +# -------------
  791 +#
  792 +class WCTContentObject(QTIObjectV1):
  793 + def __init__(self,name,attrs,parent):
  794 + QTIObjectV1.__init__(self,name,attrs,parent)
  795 + self.file_name = None
  796 + self.file_path = None
  797 + self.co_type
  798 + self.in_manifest = self.CheckLocation((Manifest),"<webct:ContentObject>", False)
  799 + self.ParseAttributes(attrs)
  800 +
  801 + def SetAttribute_webct_coType (self,type):
  802 + self.co_type = type
  803 +
  804 + def CloseObject(self):
  805 + if self.in_manifest and self.co_type == "webct.file" and self.file_name and self.file_path:
  806 + self.parent.update_file_path(os.path.join(self.file_path, self.file_name))
  807 +
  808 +# webct:Name
  809 +# -------------
  810 +#
  811 +class WCTName(QTIObjectV1):
  812 + def __init__(self,name,attrs,parent):
  813 + QTIObjectV1.__init__(self,name,attrs,parent)
  814 + self.in_content_object = self.CheckLocation((WCTContentObject),"<webct:WCTName>", False)
  815 +
  816 + def AddData (self,data):
  817 + if self.in_content_object:
  818 + self.parent.file_name = data
  819 +
  820 +# webct:Path
  821 +# -------------
  822 +#
  823 +class WCTPath(QTIObjectV1):
  824 + def __init__(self,name,attrs,parent):
  825 + QTIObjectV1.__init__(self,name,attrs,parent)
  826 + self.in_content_object = self.CheckLocation((WCTContentObject),"<webct:WCTPath>", False)
  827 +
  828 + def AddData (self,data):
  829 + if self.in_content_object:
  830 + self.parent.file_path = data
  831 +
782 832 # material_table
783 833 # -------------
784 834 #
@@ -788,7 +838,7 @@ class WCTMaterialTable(QTIObjectV1):
788 838 def __init__(self,name,attrs,parent):
789 839 QTIObjectV1.__init__(self,name,attrs,parent)
790 840 self.PrintWarning('Warning: material_table not supported, looking inside for needed data')
791   -
  841 +
792 842 def SetAttribute_label (self,id):
793 843 pass
794 844
@@ -3564,7 +3614,7 @@ def SetAttribute_label (self,value):
3564 3614 self.label=value
3565 3615
3566 3616 def SetAttribute_uri (self,value):
3567   - self.uri=value
  3617 + self.uri=value.lstrip('/')
3568 3618
3569 3619 def SetAttribute_entityref (self,value):
3570 3620 self.entityRef=value
@@ -6071,15 +6121,18 @@ def CloseObject (self):
6071 6121 'varsubset':VarSubset,
6072 6122 'varsubstring':VarSubstring,
6073 6123 'vocabulary':Vocabulary,
  6124 + 'webct:answer':CalculatedAnswer,
6074 6125 'webct:calculated':CalculatedNode,
6075   - 'webct:formula':CalculatedFormula,
6076   - 'webct:var':WCTVar,
  6126 + 'webct:calculated_answer':WCTCalculatedAnswer,
6077 6127 'webct:calculated_set':CalculatedVarSet,
6078 6128 'webct:calculated_var':WCTVar,
6079   - 'webct:answer':CalculatedAnswer,
6080   - 'webct:calculated_answer':WCTCalculatedAnswer,
  6129 + 'webct:ContentObject':WCTContentObject,
  6130 + 'webct:Name':WCTName,
  6131 + 'webctfl:Path':WCTPath,
  6132 + 'webct:formula':CalculatedFormula,
6081 6133 'webct:matching_ext_flow':WCTMatchingExtFlow,
6082   - 'webct:matching_text_ext':WCTMatchingTextExt
  6134 + 'webct:matching_text_ext':WCTMatchingTextExt,
  6135 + 'webct:var':WCTVar,
6083 6136 }
6084 6137
6085 6138 class QTIParserV1(handler.ContentHandler, handler.ErrorHandler):
@@ -6093,6 +6146,8 @@ def __init__(self,options):
6093 6146 self.parser.setErrorHandler(self)
6094 6147 self.parser.setEntityResolver(self)
6095 6148 self.elements=QTIASI_ELEMENTS
  6149 + self.manifest=None
  6150 + self.manifest_path=None
6096 6151 if self.options.qmdExtensions:
6097 6152 self.elements['qmd_keywords']=QMDKeywords
6098 6153 self.elements['qmd_domain']=QMDDomain
@@ -6168,8 +6223,17 @@ def startElement(self, name, attrs):
6168 6223 self.cObject.SetPath(self.currPath)
6169 6224 self.cObject.SetParser(self)
6170 6225 if isinstance(self.cObject,Manifest):
6171   - self.cObject.SetCP(self.cp)
6172   - self.cObject.SetPath(self.currPath)
  6226 + if self.currPath.endswith("imsmanifest.xml"):
  6227 + self.cObject.SetCP(self.cp)
  6228 + self.cObject.SetPath(self.currPath)
  6229 + self.manifest = self.cObject
  6230 + self.manifest_path = self.currPath.replace("imsmanifest.xml", '')
  6231 + else:
  6232 + if self.manifest:
  6233 + self.cObject.SetCP(self.manifest.cp)
  6234 + self.cObject.SetPath(self.manifest.path)
  6235 + self.cObject.resource = self.manifest.resource
  6236 +
6173 6237 if self.options.prepend_path and isinstance(self.cObject,(MatThing)):
6174 6238 self.cObject.prepend_path = self.options.prepend_path
6175 6239 else:

0 comments on commit 385548a

Please sign in to comment.
Something went wrong with that request. Please try again.