| 1 | from collective.imstransport.utilities.imsinterchange import IMSReader |
|---|
| 2 | from collective.imstransport.utilities.packagingio import ZipfileReader |
|---|
| 3 | from collective.imstransport.utilities.webct.webctreader import WebCTReader |
|---|
| 4 | from zope.component import getUtility |
|---|
| 5 | from collective.imstransport.utilities.interfaces import IIMSObjectCreator |
|---|
| 6 | |
|---|
| 7 | class IMSWebCTReader(IMSReader): |
|---|
| 8 | """ Create objects from IMS manifest. """ |
|---|
| 9 | |
|---|
| 10 | def readPackage(self, file, context): |
|---|
| 11 | """ Read the manifest """ |
|---|
| 12 | |
|---|
| 13 | source = ZipfileReader(file) |
|---|
| 14 | objDict = {} |
|---|
| 15 | if not source: |
|---|
| 16 | return False, 'Internal error. No source object specified' |
|---|
| 17 | webctreader = WebCTReader() |
|---|
| 18 | manifest = source.readManifest() |
|---|
| 19 | if not manifest: |
|---|
| 20 | raise ManifestError, 'Could not locate manifest file "imsmanifest.xml" in the zip archive.' |
|---|
| 21 | try: |
|---|
| 22 | doc = webctreader.parseManifest(manifest) |
|---|
| 23 | except ExpatError, e: |
|---|
| 24 | raise ManifestError, str(e) |
|---|
| 25 | manifests = webctreader.readManifests(doc) |
|---|
| 26 | |
|---|
| 27 | for manifest in manifests: |
|---|
| 28 | orgs =[] |
|---|
| 29 | manifestmetadata = webctreader.readPackageMetadata(manifest) |
|---|
| 30 | if manifestmetadata.has_key('webcttype') and manifestmetadata['webcttype'] == 'Course': |
|---|
| 31 | objDict['package'] = manifestmetadata |
|---|
| 32 | else: |
|---|
| 33 | orgs = webctreader.readOrganizations(manifest) |
|---|
| 34 | resources = webctreader.readResources(manifest) |
|---|
| 35 | for x in resources: |
|---|
| 36 | resid, restype, reshref = webctreader.readResourceAttributes(x) |
|---|
| 37 | files = webctreader.readFiles(x) |
|---|
| 38 | # If the type is a link |
|---|
| 39 | if manifestmetadata.has_key('webcttype') and manifestmetadata['webcttype'] == 'URL': |
|---|
| 40 | for y in files: |
|---|
| 41 | hash = resid + y |
|---|
| 42 | objDict[hash] = manifestmetadata |
|---|
| 43 | id = self.createIdFromFile(y) |
|---|
| 44 | objDict[hash]['id'] = id |
|---|
| 45 | objDict[hash]['path'] = '' |
|---|
| 46 | objDict[hash]['type'] = 'Link' |
|---|
| 47 | objDict[hash]['remoteUrl'] = y |
|---|
| 48 | elif restype == 'webcontent': |
|---|
| 49 | if not files and reshref: |
|---|
| 50 | files = [reshref,] |
|---|
| 51 | for y in files: |
|---|
| 52 | hash = resid + y |
|---|
| 53 | objDict[hash] = {} |
|---|
| 54 | # Can apply manifest metadata if single file and single resource |
|---|
| 55 | if len(resources) == 1 and len(files) == 1: |
|---|
| 56 | objDict[hash] = manifestmetadata |
|---|
| 57 | if len(files) == 1: |
|---|
| 58 | # If it is listed in the org section |
|---|
| 59 | if orgs.has_key(resid): |
|---|
| 60 | objDict[hash]['excludeFromNav'] = False |
|---|
| 61 | # Use 'and' as opposed to 'or' to avoid KeyError |
|---|
| 62 | if not (objDict[hash].has_key('title') and objDict[hash]['title']): |
|---|
| 63 | objDict[hash]['title'] = orgs[resid] |
|---|
| 64 | else: |
|---|
| 65 | objDict[hash]['excludeFromNav'] = True |
|---|
| 66 | objDict[hash]['file'] = y |
|---|
| 67 | objDict[hash]['type'] = self.determineType(objDict[hash], y) |
|---|
| 68 | # If it is just a lowly file |
|---|
| 69 | else: |
|---|
| 70 | objDict[hash]['excludeFromNav'] = True |
|---|
| 71 | objDict[hash]['file'] = y |
|---|
| 72 | objDict[hash]['type'] = self.determineType(objDict[hash], y) |
|---|
| 73 | # Add to all files |
|---|
| 74 | id = self.createIdFromFile(y) |
|---|
| 75 | objDict[hash]['id'] = id |
|---|
| 76 | if not (objDict[hash].has_key('title') and objDict[hash]['title']): |
|---|
| 77 | objDict[hash]['title'] = id |
|---|
| 78 | objDict[hash]['path'] = self.createPathFromFile(y) |
|---|
| 79 | objcreator = getUtility(IIMSObjectCreator) |
|---|
| 80 | objcreator.createObjects(objDict, context, source) |
|---|