Changeset 306
- Timestamp:
- 06/26/09 15:57:22 (4 years ago)
- Location:
- collective.imstransport/trunk/collective/imstransport/utilities/imscp
- Files:
-
- 1 added
- 4 edited
-
configcp.py (added)
-
cpreader.py (modified) (2 diffs)
-
cpwriter.py (modified) (4 diffs)
-
imscpreader.py (modified) (2 diffs)
-
imscpwriter.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
collective.imstransport/trunk/collective/imstransport/utilities/imscp/cpreader.py
r197 r306 1 1 from xml.dom import minidom 2 2 from collective.imstransport.IMS_exceptions import ManifestError 3 from configcp import LOM_IMSCP_namespace 3 4 4 5 class CPReader(object): 5 6 def __init__(self, context, source):7 """8 """9 self.context = context10 self.document = None11 self.orgdata = {}12 self.resids = []13 self.objdict = {}14 6 15 7 def parseManifest(self, manifest): 16 8 """ parse the manifest """ 17 self.document = minidom.parseString(manifest) 18 19 def readManifests(self): 9 return minidom.parseString(manifest) 10 11 def readPackageMetadata(self, manifest): 12 """ Read the package metadata """ 13 return self.readMetadata(manifest) 14 15 def readOrganizations(self, manifest): 20 16 """ Read the organizations section of the manifest. """ 21 self.org= {}22 organizations = self.document.getElementsByTagName('organizations')17 orgs = {} 18 organizations = manifest.getElementsByTagName('organizations') 23 19 if organizations: 24 self._readItems(self.context, organizations[0]) 25 else: 26 raise ManifestError, 'Manifest file has no "organizations" section.' 27 28 def readOrganizations(self): 29 """ Read the organizations section of the manifest. """ 30 self.org = {} 31 organizations = self.document.getElementsByTagName('manifest') 32 if organizations: 33 return self._readItems(self.context, organizations[0]) 34 else: 35 raise ManifestError, 'Manifest file has no "organizations" section.' 36 37 def _readItems(self, object, orgs): 38 """ Read items from the manifest. """ 39 40 organization_nodes = orgs.getElementsByTagName('organization') 41 if organization_nodes: 42 organization_node = organization_nodes[0] 43 44 item_nodes = organization_nodes[0].getElementsByTagName('item') 45 itemnum = 1 46 for item in item_nodes: 47 idref = item.getAttribute('identifierref') 48 title_nodes = item.getElementsByTagName('title') 49 if title_nodes: 50 self.orgdata[idref] = self.getTextValue(title_nodes[0]) 20 organization_nodes = organizations[0].getElementsByTagName('organization') 21 if organization_nodes: 22 organization_node = organization_nodes[0] 23 item_nodes = organization_nodes[0].getElementsByTagName('item') 24 itemnum = 1 25 for item in item_nodes: 26 idref = item.getAttribute('identifierref') 27 titlenodes = item.getElementsByTagName('title') 28 if titlenodes: 29 orgs[idref] = (itemnum, self.getTextValue(titlenodes[0])) 30 else: 31 orgs[idref] = (itemnum, None) 51 32 itemnum += 1 52 53 return self.orgdata 54 55 def readResources(self): 33 return orgs 34 35 def readResources(self, manifest): 56 36 """ Read all resources. """ 57 resources = self.document.getElementsByTagName('resources') 37 reslist = [] 38 resources = manifest.getElementsByTagName('resources') 58 39 if resources: 59 for res in resources[0].getElementsByTagName('resource'): 60 id = res.getAttribute('identifier') 61 self.resids.append(id) 62 63 return self.resids 64 65 def getResourceIds(self): 66 """ Get a list of resource identifiers """ 67 return self.resids 40 reslist = resources[0].getElementsByTagName('resource') 41 return reslist 68 42 69 43 def getTextValue(self, node): … … 74 48 return None 75 49 76 77 def getVcardValues(self, node, resid): 50 def readResourceAttributes(self, resource): 51 """ Return attributes on resource node. """ 52 return (resource.getAttribute('identifier'), 53 resource.getAttribute('type'), 54 resource.getAttribute('href')) 55 56 def readMetadata(self, metadata): 57 md = {} 58 self.readGeneral(metadata, md) 59 self.readLifecycle(metadata, md) 60 self.readMetaMetadata(metadata, md) 61 self.readTechnical(metadata, md) 62 self.readRights(metadata, md) 63 return md 64 65 def readFiles(self, resource): 66 files = [] 67 flns = resource.getElementsByTagName('file') 68 if flns: 69 for fln in flns: 70 file = fln.getAttribute('href') 71 files.append(file) 72 return files 73 74 def readGeneral(self, metadata, md): 75 """ Read general node """ 76 gen_node = None 77 gen_nodes = metadata.getElementsByTagNameNS(LOM_IMSCP_namespace, 'general') 78 if gen_nodes: 79 gen_node = gen_nodes[0] 80 title_nodes = gen_node.getElementsByTagNameNS(LOM_IMSCP_namespace, 'title') 81 if title_nodes: 82 langstring_nodes = title_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace,'langstring') 83 if langstring_nodes: 84 title = self.getTextValue(langstring_nodes[0]) 85 if title: 86 md['title'] = title 87 if not md.has_key('title'): 88 raise ManifestError, 'Required tag "title" missing in lom/general metadata section for resource.' 89 language_nodes = metadata.getElementsByTagNameNS(LOM_IMSCP_namespace, 'language') 90 if language_nodes: 91 lang = self.getTextValue(language_nodes[0]) 92 if lang: 93 md['language'] = lang 94 desc_nodes = metadata.getElementsByTagNameNS(LOM_IMSCP_namespace, 'description') 95 if desc_nodes: 96 langstring_nodes = desc_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace,'langstring') 97 if langstring_nodes: 98 description = self.getTextValue(langstring_nodes[0]) 99 if description: 100 md['description'] = description 101 kw_nodes = metadata.getElementsByTagNameNS(LOM_IMSCP_namespace, 'keyword') 102 if kw_nodes: 103 kw_list = [] 104 for kw_node in kw_nodes: 105 kw_lang_nodes = kw_node.getElementsByTagNameNS(LOM_IMSCP_namespace,'langstring') 106 if kw_lang_nodes: 107 for lang_node in kw_lang_nodes: 108 kw = self.getTextValue(lang_node) 109 if kw: 110 kw_list.append(kw) 111 if kw_list: 112 md['subject'] = kw_list 113 114 def readLifecycle(self, metadata, md): 115 """ Read Lifecycle node """ 116 lc_node = None 117 lc_nodes = metadata.getElementsByTagNameNS(LOM_IMSCP_namespace, 'lifecycle') 118 if lc_nodes: 119 lc_node = lc_nodes[0] 120 if lc_node: 121 # Lifecycle Node 122 contribute_nodes = lc_node.getElementsByTagNameNS(LOM_IMSCP_namespace, 'contribute') 123 # For each contribute node there is a role node, a centity node, and possibly a date node 124 for contribute_node in contribute_nodes: 125 source = '' 126 value = '' 127 vlist = [] 128 datetime = '' 129 role_nodes = contribute_node.getElementsByTagNameNS(LOM_IMSCP_namespace, 'role') 130 if role_nodes: 131 source_nodes = role_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace, 'source') 132 if source_nodes: 133 langstring_nodes = source_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace, 'langstring') 134 if langstring_nodes: 135 source = self.getTextValue(langstring_nodes[0]) 136 value_nodes = role_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace, 'value') 137 if value_nodes: 138 langstring_nodes = value_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace, 'langstring') 139 if langstring_nodes: 140 value = self.getTextValue(langstring_nodes[0]) 141 entity_nodes = contribute_node.getElementsByTagNameNS(LOM_IMSCP_namespace, 'centity') 142 for entity_node in entity_nodes: 143 vcard = entity_node.getElementsByTagNameNS(LOM_IMSCP_namespace, 'vcard') 144 if vcard: 145 name, email = self.getVcardValues(vcard[0]) 146 if value: 147 vlist.append((name, email)) 148 date_nodes = contribute_node.getElementsByTagNameNS(LOM_IMSCP_namespace, 'date') 149 if date_nodes: 150 datetime_nodes = date_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace, 'datetime') 151 if datetime_nodes: 152 datetime = self.getTextValue(datetime_nodes[0]) 153 # Creator 154 if 'author' == value.lower() and vlist: 155 md['creators'] = [x[0] for x in vlist] 156 if datetime: 157 md['creation_date'] = datetime 158 # Contributors 159 if 'unknown' == value.lower() and vlist: 160 md['contributors'] = [x[0] for x in vlist] 161 162 def readMetaMetadata(self, metadata, md): 163 """ Read MetaMetadata node """ 164 165 def readTechnical(self, metadata, md): 166 """ Read the Technical node """ 167 tec_node = None 168 tec_nodes = metadata.getElementsByTagNameNS(LOM_IMSCP_namespace, 'technical') 169 if tec_nodes: 170 tec_node = tec_nodes[0] 171 format_nodes = tec_node.getElementsByTagNameNS(LOM_IMSCP_namespace, 'format') 172 if format_nodes: 173 format = self.getTextValue(format_nodes[0]) 174 if format: 175 md['Format'] = format 176 177 def readRights(self, metadata, md): 178 """ Read Rights node """ 179 rights_node = None 180 rights_nodes = metadata.getElementsByTagNameNS(LOM_IMSCP_namespace, 'rights') 181 if rights_nodes: 182 rights_node = rights_nodes[0] 183 description_nodes = rights_node.getElementsByTagNameNS(LOM_IMSCP_namespace,'description') 184 if description_nodes: 185 langstring_nodes = description_nodes[0].getElementsByTagNameNS(LOM_IMSCP_namespace,'langstring') 186 if langstring_nodes: 187 description = self.getTextValue(langstring_nodes[0]) 188 if description: 189 md['rights'] = description 190 191 def getVcardValues(self, node): 78 192 """ 79 Looks for the full name and email values in a VCARD 80 value. 81 82 Added some whitespace stripping, and case 83 insensitive tag searching, so that we could parse the 84 default IMS example package. 85 193 Looks for the full name and email values in a VCARD value. 86 194 """ 87 195 text = self.getTextValue(node) 88 196 textlines = text.strip().split('\n') 89 90 value = self._getVcardValue('BEGIN', [textlines[0]]) 197 value = self.getVcardValue('BEGIN', [textlines[0]]) 91 198 if 'VCARD' != value.strip().upper(): 92 raise ManifestError, 'Missing VCARD BEGIN tag for resource "%s"' %resid 93 94 value = self._getVcardValue('END', [textlines[-1]]) 199 raise ManifestError, 'Missing VCARD BEGIN tag' 200 value = self.getVcardValue('END', [textlines[-1]]) 95 201 if 'VCARD' != value.strip().upper(): 96 raise ManifestError, 'Missing VCARD END tag for resource "%s"' %resid 97 98 name = self._getVcardValue('FN', textlines) 99 email = self._getVcardValue('EMAIL;INTERNET', textlines) 100 202 raise ManifestError, 'Missing VCARD END tag' 203 name = self.getVcardValue('FN', textlines) 204 email = self.getVcardValue('EMAIL;INTERNET', textlines) 101 205 return name, email 102 103 206 104 def _getVcardValue(self, field, text):207 def getVcardValue(self, field, text): 105 208 """ Try to get a value for a VCARD field. """ 106 209 for textline in text: 107 # If the line is not folded108 #if textline[0] != ' ':109 # Look for the Colon delimiter110 210 textline = textline.strip() 111 211 if textline.find(':'): -
collective.imstransport/trunk/collective/imstransport/utilities/imscp/cpwriter.py
r188 r306 3 3 import md5 4 4 import os 5 6 7 LOM_version = 'LOMv1.0' 8 LOM_namespace = 'http://ltsc.ieee.org/xsd/LOM' 5 from configcp import LOM_IMSCP_namespace, namespaces, schema_locations, LOM_version, IMS_schema, IMS_version 9 6 10 7 class CPWriter(object): 11 8 12 def __init__(self, context): 13 self.context = context 9 def __init__(self): 14 10 self.document = minidom.Document() 15 self.destination = None 16 self.manifest_node = None 17 self.custom_namespaces = None 18 self.extensionMetadata = None 19 self.itemDict = {} 20 21 def setExtensionNamespaces(self, extension_ns): 22 """ Set any extension namespaces """ 23 self.namespaces += extension_ns 24 25 def setDestination(self, destination): 26 """ Set the output object for the writer. """ 27 self.destination = destination 28 29 def setExtensionMetadataMethod(self, extensionMetadata): 30 """ Set the extension metadata method """ 31 self.extensionMetadata = extensionMetadata 32 11 12 def createManifest(self, id, ver): 13 """ Create a new empty manifest. """ 14 doc = minidom.Document() 15 manifest = self._createNode(doc, '', 'manifest', 16 attrs=[('identifier', id), 17 ('xmlns:version', ver),]) 18 self.addNamespaces(manifest, namespaces) 19 self.addSchemaLocations(manifest, schema_locations) 20 return doc 21 22 def writeTopLevelMetadata(self, doc, id, title, urlbase, lang, desc=None, keywords=None): 23 """ Write top level metadata into the manifest. """ 24 manifest = doc.getElementsByTagName('manifest') 25 if manifest: 26 md = self._createNode(manifest[0], '', 'metadata') 27 self._createNode(md, '', 'schema', IMS_schema) 28 self._createNode(md, '', 'schemaversion', IMS_version) 29 lom = self._createNode(md, LOM_IMSCP_namespace, 'lom') 30 self.writeGeneralNode(lom, id, title, lang, desc, keywords) 31 32 def createOrganizations(self, doc, orgId): 33 """ Create an organizations section in the manifest """ 34 manifest = doc.getElementsByTagName('manifest') 35 if manifest: 36 orgs = self._createNode(manifest[0], '', 'organizations', attrs=[('default', orgId),]) 37 org = self._createNode(orgs, '', 'organization', attrs=[('identifier', orgId),]) 38 return org 39 return None 40 41 def createResources(self, doc): 42 manifest = doc.getElementsByTagName('manifest') 43 if manifest: 44 return self._createNode(manifest[0], '', 'resources') 45 return None 46 47 def writeItem(self, orgs, itemId, refId, title): 48 """ Write an item in the organizations section """ 49 itn = self._createNode(orgs, '', 'item', attrs=[('identifier', itemId), 50 ('identifierref', refId), 51 ('isvisible', 'true')]) 52 tn = self._createNode(itn, '', 'title', title) 53 return tn 54 55 def writeResource(self, res, refid, type, path): 56 """ Write a resource object in the resources section """ 57 attrs = [('identifier', refid)] 58 attrs.append(('type', 'webcontent')) 59 attrs.append(('href', path)) 60 rn = self._createNode(res, '', 'resource', attrs=attrs) 61 return rn 62 63 def createResourceMetadata(self, res): 64 """ Create a resource metadat node """ 65 md = self._createNode(res, '', 'metadata') 66 return self._createNode(md, LOM_IMSCP_namespace, 'lom') 33 67 34 def write ManifestNode(self, manifestId, manifestVer, namespaces, schema_locations):35 """ Write the manifest node."""36 self.manifest_node = self._createNode(self.document,37 '',38 'manifest',39 attrs=[('identifier', manifestId),40 ('xmlns:version', manifestVer),])41 self. addNamespaces(namespaces)42 self. addSchemaLocations(schema_locations)43 44 45 def writeLOMCPMetadata(self, id, title, urlbase, imsschema, imsversion, lang=None, description=None, keywords=None):46 """ Write the lom imscc metadata node for the top level object """47 48 # Create the top level Metadata node49 self.metadata_node = self._createNode(self.manifest_node, '', 'metadata')50 51 52 self.schema_node = self._createNode(self.metadata_node,53 '',54 'schema',55 imsschema)56 57 self.schema_node = self._createNode(self.metadata_node,58 '',59 'schemaversion',60 imsversion) 61 62 63 def writeManifest():64 65 # Create the Organizations node66 defaultId = self._createPathId(self.context.virtual_url_path(), 'ORG')67 organizations_node = self._createNode(self.manifest_node,68 '',69 'organizations',)70 71 72 # Write out organizations information.73 self. writeOrganizations(self.context, organizations_node, self)74 75 resources_node = self._createNode(self.manifest_node, '', 'resources') 76 77 allObjects = self._getAllObjects()78 79 for obj in allObjects:80 # Handle the case where an object might be folderish, but81 # also has a text attribute.82 if not obj.isPrincipiaFolderish or hasattr(obj.aq_explicit,'getText'): 83 path = self._getObjectPath(obj)84 self._writeResource(obj, resources_node, path, extensionMetadata=self.extensionMetadata)85 self._writeObjectData(obj, path)86 87 self._writeObjectData(self.getManifest(), 'imsmanifest.xml')88 89 if self.destination:90 return self.destination.getOutput()91 else:92 return None, None93 94 def writeOrganizationsNode(self, id):95 """ Common Cartridge requires organization to specify rooted-hierarchy as structure """96 self.organizations_node = self._createNode(self.manifest_node, 97 '', 98 'organizations',99 attrs=[('default',id)])100 101 102 s elf.organization_node = self._createNode(self.organizations_node,103 '',104 'organization',105 attrs=[('identifier',id)])106 107 108 def writeItem(self, itemId, title, refId=None):109 """ Write out a single item and its title. Folder nodes include containing objects """110 111 attrs = [('identifier', itemId),]112 if refId:113 attrs.append(('identifierref', refId))114 115 item_node = self._createNode(self.organization_node, 116 '',117 'item',118 attrs=attrs)119 120 self._createNode(item_node, '', 'title', title)121 122 123 def writeResources(self):124 """ Resources node """125 self.resources_node = self._createNode(self.manifest_node, '', 'resources')126 127 128 def getResourceMetadataWriter(self, writer):129 """ ResourceMetadataWriter objects create the resource node along with all metadata therein"""130 return ResourceMetadataWriter(writer)131 132 133 def getManifest(self ):68 def writeGeneralNode(self, lom, id, title, lang, desc=None, kw=None): 69 """ Write the general Node """ 70 if not lang: 71 lang = 'x-none' 72 gen = self._createNode(lom, '', 'general') 73 idn = self._createNode(gen, '', 'identifier', id) 74 tn = self._createNode(gen, '', 'title') 75 self._createNode(tn, '', 'langstring', title, [('xml:lang', lang)]) 76 self._createNode(gen, '', 'language', lang) 77 if desc: 78 dn = self._createNode(gen, '', 'description') 79 self._createNode(dn, '', 'langstring', desc, [('xml:lang', lang)]) 80 if kw: 81 kn = self._createNode(gen, '', 'keyword') 82 for k in kw: 83 self._createNode(kn, '', 'langstring', k, [('xml:lang', lang)]) 84 85 def writeLifeCycleNode(self, lom, creators, contrib, mod, lang): 86 """ Write the lifecycle Node """ 87 if not lang: 88 lang = 'x-none' 89 ln = self._createNode(lom, '', 'lifecycle') 90 if creators: 91 self._createContributeElement(ln, '', LOM_version, 'author', lang, creators, mod) 92 if contrib: 93 self._createContributeElement(ln, '', LOM_version, 'unknown', lang, contrib, mod) 94 95 def writeMetaMetadataNode(self, lom, id, urlbase, email, modtime, lang, contrib): 96 """ write the metaMetadata Node """ 97 if not lang: 98 lang = 'x-none' 99 mmd = self._createNode(lom, '', 'metametadata') 100 idn = self._createNode(mmd, '', 'catalogentry') 101 catentry = urlbase 102 if email: 103 catentry += ',%s' %email 104 self._createNode(idn, '', 'catalog', catentry) 105 entry = self._createNode(idn, '', 'entry') 106 self._createNode(entry, '', 'langstring', id, attrs=[('xml:lang',lang)]) 107 self._createNode(mmd, '', 'metadatascheme', LOM_version) 108 self._createNode(mmd, '', 'language', lang) 109 110 def writeTechnicalNode(self, lom, format, size, location): 111 """ Write the Technical Node """ 112 tech = self._createNode(lom, '', 'technical') 113 self._createNode(tech, '', 'format', format) 114 self._createNode(tech, '', 'size', size) 115 self._createNode(tech, '', 'location', location) 116 117 def writeRightsNode(self, lom, value, copyright, lang): 118 """ Write the Rights Node """ 119 if not lang: 120 lang = 'x-none' 121 rights = self._createNode(lom, '', 'rights') 122 cwn = self._createNode(rights, '', 'copyrightandotherrestrictions') 123 source_node = self._createNode(cwn, '', 'source') 124 self._createNode(source_node, '', 'langstring', LOM_version, attrs=[('xml:lang', lang)]) 125 value_node = self._createNode(cwn, '', 'value') 126 self._createNode(value_node, '', 'langstring', value, attrs=[('xml:lang', lang)]) 127 if copyright: 128 desc = self._createNode(rights, '', 'description') 129 self._createNode(desc, '', 'langstring', copyright, [('xml:lang', lang)]) 130 131 132 def _createContributeElement(self, node, ns, source, value, lang, entities=[], date=None, email=None): 133 """ writes out a Contribute Element """ 134 cn = self._createNode(node, ns, 'contribute') 135 role = self._createNode(cn, '', 'role') 136 source_node = self._createNode(role, '', 'source') 137 self._createNode(source_node, '', 'langstring', source, attrs=[('xml:lang', lang)]) 138 value_node = self._createNode(role, '', 'value') 139 self._createNode(value_node, '', 'langstring', value, attrs=[('xml:lang', lang)]) 140 if entities: 141 if type(entities) not in [type([]), type(())]: 142 entities = [entities] 143 for e in entities: 144 centity_node = self._createNode(cn, '', 'centity') 145 self._createNode(centity_node, '', 'vcard', self._createVCard(e,email)) 146 if date: 147 dn = self._createNode(cn, '', 'date') 148 self._createNode(dn, '', 'datetime', date) 149 150 def _createVCard(self, name, email=None): 151 """ 152 Writes out a VCard entry for a contribute element 153 Note: Should replace this with the python vcard library. 154 """ 155 vCard = 'BEGIN:VCARD\n' 156 vCard += 'FN:'+name+'\n' 157 if email: 158 vCard += 'EMAIL;INTERNET:'+email+'\n' 159 vCard += 'END:VCARD' 160 return vCard 161 162 def writeResourceFile(self, res, path): 163 """ Write a file node """ 164 self._createNode(res, '', 'file', attrs=[('href', path)]) 165 166 167 def getManifest(self, manifest): 134 168 """ Get the manifest expressed in XML. """ 135 return self.document.toxml(encoding='utf-8') 136 169 return manifest.toxml(encoding='utf-8') 137 170 138 171 def _createNode(self, parent, nspace, ename, value=None, attrs=None): 139 172 """ Create a node in the document. """ 140 173 newnode = self.document.createElementNS(nspace, ename) 174 if nspace: 175 newnode.setAttribute('xmlns', nspace) 141 176 parent.appendChild(newnode) 142 177 if value and value != '': … … 144 179 newnode.appendChild(self.document.createTextNode(value.decode('utf-8'))) 145 180 else: 146 newnode.appendChild(self.document.createTextNode(value)) 181 newnode.appendChild(self.document.createTextNode(value)) 147 182 if attrs: 148 183 for x in attrs: … … 150 185 return newnode 151 186 152 153 def addNamespaces(self, namespaces): 154 """ Add a list of namespace to the manifest. """ 187 def addNamespaces(self, manifest, namespaces): 188 """ Add a namespace to the manifest. """ 155 189 for namespace in namespaces: 156 self.manifest_node.setAttribute(namespace[0], namespace[1]) 157 158 def addSchemaLocations(self, schema_locations): 159 self.manifest_node.setAttribute('xsi:schemaLocation', join(schema_locations, ' ')) 160 190 manifest.setAttribute(namespace[0], namespace[1]) 191 192 def addSchemaLocations(self, manifest, schema_locations): 193 manifest.setAttribute('xsi:schemaLocation', join(schema_locations, ' ')) 161 194 162 195 def getTextValue(self, node): … … 165 198 if x.nodeType == x.TEXT_NODE: 166 199 return x.nodeValue.strip() 167 return None 200 return None 201 202 def getLinkXml(self, title, link): 203 """ Return text for a file that stores the link in an xml file """ 204 doc = minidom.Document() 205 link_node = self._createNode(doc, '', 'a', title, attrs=[('href',link),]) 206 return doc.toxml() 207 -
collective.imstransport/trunk/collective/imstransport/utilities/imscp/imscpreader.py
r197 r306 1 from zope.interface import implements 2 from collective.imstransport.utilities.interfaces import IIMSObjectCreator 3 from zope.component import getUtility 4 from collective.imstransport.utilities.imsinterchange import IMSInterchangeReader 1 from collective.imstransport.utilities.imsinterchange import IMSReader 5 2 from collective.imstransport.utilities.packagingio import ZipfileReader 6 3 from collective.imstransport.utilities.imscp.cpreader import CPReader 7 from collective.imstransport.utilities.imscp.cpresourcereader import CPResourceReader 8 import re 9 from collective.imstransport import IMSTransportMessageFactory as _ 10 from xml.dom import minidom 4 from zope.component import getUtility 5 from collective.imstransport.utilities.interfaces import IIMSObjectCreator 11 6 12 LOM_namespace = 'http://ltsc.ieee.org/xsd/LOM' 13 14 class IMSCPReader(IMSInterchangeReader): 7 class IMSCPReader(IMSReader): 15 8 """ Create objects from IMS manifest. """ 16 17 name = _(u'IMS Content Package')18 19 XML = 'http://www.w3.org/XML/1998/namespace'20 IMSCP = 'http://www.imsglobal.org/xsd/imscc/imscp_v1p1'21 LOM = 'http://ltsc.ieee.org/xsd/LOM'22 9 23 10 def readPackage(self, file, context): 24 11 """ Read the manifest """ 25 12 26 source = ZipfileReader( input)13 source = ZipfileReader(file) 27 14 objDict = {} 28 15 … … 30 17 return False, 'Internal error. No source object specified' 31 18 32 cpreader = CPReader(context, source) 33 19 cpreader = CPReader() 34 20 manifest = source.readManifest() 35 21 if not manifest: 36 return False, \ 37 'Manifest', \ 38 'Could not locate manifest file "imsmanifest.xml" in the zip archive.' 22 raise ManifestError, 'Could not locate manifest file "imsmanifest.xml" in the zip archive.' 39 23 40 cpreader.parseManifest(manifest) 41 orgdata = cpreader.readOrganizations() 42 resourceids = cpreader.readResources() 24 try: 25 doc = cpreader.parseManifest(manifest) 26 except ExpatError, e: 27 raise ManifestError, str(e) 28 objDict['package'] = cpreader.readPackageMetadata(doc) 29 orgs = cpreader.readOrganizations(doc) 30 resources = cpreader.readResources(doc) 43 31 44 for resourceid in resourceids: 45 cpresourcereader = CPResourceReader(cpreader, resourceid, 'http://www.imsglobal.org/xsd/imsmd_v1p2') 46 resdata = self.parseResourceMetadata(cpresourcereader, resourceid, context) 47 reshref = cpresourcereader.getHref() 48 files = cpresourcereader.readFiles() 32 for x in resources: 33 resid, restype, reshref = cpreader.readResourceAttributes(x) 34 metadata = cpreader.readMetadata(x) 35 files = cpreader.readFiles(x) 49 36 50 hashref = '' 51 if files: 52 for file in files: 53 hashref = '%s%s' %(resourceid, file) 54 id = self.createIdFromFile(file) 55 path = self.createPathFromFile(file) 37 # If the type is a file 38 if restype == 'webcontent': 39 if not files and reshref: 40 files = [reshref,] 41 for y in files: 42 hash = resid + y 43 # If there is only one file, or it matches the reshref 44 # add the metadata to it if it exists 45 if y == reshref or len(files) == 1: 46 objDict[hash] = metadata 47 # If it is listed in the org section 48 if orgs.has_key(resid): 49 objDict[hash]['position'] = orgs[resid][0] 50 objDict[hash]['excludeFromNav'] = False 51 # Use 'and' as opposed to 'or' to avoid KeyError 52 if not (objDict[hash].has_key('title') and objDict[hash]['title']): 53 objDict[hash]['title'] = orgs[resid][1] 54 else: 55 objDict[hash]['excludeFromNav'] = True 56 objDict[hash]['file'] = y 57 objDict[hash]['type'] = self.determineType(objDict[hash], y) 58 # If it is just a lowly file 59 else: 60 objDict[hash] = {} 61 objDict[hash]['excludeFromNav'] = True 62 objDict[hash]['file'] = y 63 objDict[hash]['type'] = self.determineType(objDict[hash], y) 64 # Add to all files 65 id = self.createIdFromFile(y) 66 objDict[hash]['id'] = id 67 if not (objDict[hash].has_key('title') and objDict[hash]['title']): 68 objDict[hash]['title'] = id 69 objDict[hash]['path'] = self.createPathFromFile(y) 56 70 57 if reshref == file or len(files) == 1:58 hashref = resourceid59 objDict[hashref] = resdata60 61 62 # Check if item is in organizations section63 orgs = [org for org in orgdata if org]64 if hashref in orgs:65 objDict[hashref]['excludeFromNav'] = False66 objDict[hashref]['title'] = orgdata[hashref]67 else:68 objDict[hashref]['excludeFromNav'] = True69 70 else:71 hashref = '%s%s' %(resourceid, file)72 objDict[hashref] = {}73 objDict[hashref]['excludeFromNav'] = True74 75 self.parseFile(context, file, objDict, hashref, id, path)76 if objDict[hashref]['type'] == 'Link':77 path_to_file = objDict[hashref]['file']78 objDict['remoteUrl'] = cpresourcereader.readLink(source.readFile(path_to_file))79 80 71 objcreator = getUtility(IIMSObjectCreator) 81 72 objcreator.createObjects(objDict, context, source) 82 return83 84 85 86 87 -
collective.imstransport/trunk/collective/imstransport/utilities/imscp/imscpwriter.py
r197 r306 4 4 from collective.imstransport.utilities.imscp.cpwriter import CPWriter 5 5 from collective.imstransport.utilities.imscp.cpresourcewriter import CPResourceWriter 6 from collective.imstransport.utilities.imsinterchange import IMS InterchangeWriter6 from collective.imstransport.utilities.imsinterchange import IMSWriter 7 7 from collective.imstransport import IMSTransportMessageFactory as _ 8 8 9 IMS_schema = 'IMS Content Package' 10 IMS_version = '1.2' 11 LOM_version = 'LOMv1.0' 12 LOM_namespace = 'http://www.imsglobal.org/xsd/imsmd_v1p2' 13 14 class IMSCPWriter(IMSInterchangeWriter): 9 class IMSCPWriter(IMSWriter): 15 10 """ Write an IMS content package manifest file. """ 16 17 name = _(u'IMS Content Package')18 11 19 12 def createPackage(self, filename, context): 20 13 """ Creates an IMS Package """ 21 14 22 self.context = context15 destination = ZipfileWriter(context, file) 23 16 17 cpw = CPWriter() 24 18 25 namespaces = [('xmlns', 'http://www.imsglobal.org/xsd/imscp_v1p1'), 26 ('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'),] 27 schema_locations = ['http://www.imsglobal.org/xsd/imscp_v1p1 http://www.imsglobal.org/xsd/imscp_v1p2.xsd',] 28 29 self.destination = ZipfileWriter(context,filename) 30 cpwriter = CPWriter(context) 31 cpwriter.writeManifestNode(self._createPathId(context.virtual_url_path(), 'MAN'), 32 context.ModificationDate(), 33 namespaces, 34 schema_locations) 19 # Create the Manifest 20 manId = self._createPathId(context.virtual_url_path(), 'MAN') 21 manVer = context.ModificationDate() 22 doc = cpw.createManifest(manId, manVer) 23 24 # Add top level metadata 35 25 lang = context.Language() 36 26 if not lang: 37 27 lang = context.portal_properties.site_properties.getProperty('default_language') 38 cpwriter.writeLOMCPMetadata(context.getId(), context.Title(), context.portal_url(), IMS_schema, IMS_version, lang, context.Description(), context.Subject()) 28 cpw.writeTopLevelMetadata(doc, 29 context.getId(), 30 context.Title(), 31 context.portal_url(), 32 lang, 33 context.Description(), 34 context.Subject()) 39 35 40 cpwriter.writeOrganizationsNode(self._createPathId(context.virtual_url_path(), 'ORG')) 36 # Write Organizations and Resources 37 orgId = self._createPathId(context.virtual_url_path(), 'ORG') 38 orgs = cpw.createOrganizations(doc, orgId) 39 res = cpw.createResources(doc) 41 40 42 cpwriter.writeResources() 41 if orgs and res: 42 objs = self._getAllObjects(context) 43 for obj in objs: 44 # Need to consider excluding folders 45 # Get resource info 46 path = self._getObjectPath(obj, context) 47 vpath = obj.virtual_url_path() 48 refid = self._createPathId(vpath, 'RES') 49 # Check if we need to add to the organizations section 50 if not obj.getExcludeFromNav(): 51 itemId = self._createPathId(vpath, 'ITM') 52 cpw.writeItem(orgs, itemId, refid, obj.title) 53 rn = cpw.writeResource(res, refid, obj.Type(), path) 43 54 55 id = obj.getId() 56 title = obj.Title() 57 urlbase = obj.portal_url() 58 lang = obj.Language() 59 if not lang: 60 lang = obj.portal_properties.site_properties.getProperty('default_language') 61 desc = obj.Description() 62 kw = obj.Subject() 63 creators = obj.Creators() 64 contrib = obj.Contributors() 65 mod = obj.ModificationDate() 66 email = obj.portal_url.getPortalObject().getProperty('email_from_address') 67 format = obj.Format() 68 size = self.getObjSize(obj) 69 location = obj.renderBase() 70 value = 'yes' 71 rights_holder = obj.portal_properties.site_properties.getProperty('rights_holder') 72 rights_holder_email = obj.portal_properties.site_properties.getProperty('rights_holder_email') 73 copyright = self._getCopyrightString(obj.Rights(), rights_holder, rights_holder_email) 74 75 md = cpw.createResourceMetadata(rn) 76 cpw.writeGeneralNode(md, id, title, 'en', desc, kw) 77 cpw.writeLifeCycleNode(md, creators, contrib, mod, None) 78 cpw.writeMetaMetadataNode(md, id, urlbase, email, mod, None, contrib) 79 cpw.writeTechnicalNode(md, format, size, location) 80 cpw.writeRightsNode(md, value, copyright, None) 44 81 45 objects = self._getAllObjects(context) 82 if obj.Type() == 'Link': 83 link = cpw.getLinkXml(title, obj.getRemoteUrl()) 84 rpath = '%s' %path 85 self._writeObjectData(link, rpath, destination) 86 cpw.writeResourceFile(rn, rpath) 87 else: 88 self._writeObjectData(obj, path, destination) 89 cpw.writeResourceFile(rn, path) 46 90 47 for object in objects: 48 path = self._getObjectPath(object, context) 49 itemId = self._createPathId(object.virtual_url_path(), 'ITM') 50 refId = self._createPathId(object.virtual_url_path(), 'RES') 91 self._writeObjectData(cpw.getManifest(doc), 'imsmanifest.xml', destination) 51 92 52 if not object.isPrincipiaFolderish or getattr(object, 'getText', None): 53 if not object.getExcludeFromNav(): 54 cpwriter.writeItem(itemId, object.title, refId) 55 56 path = self._getObjectPath(object, context) 57 rlomwriter = CPResourceWriter(cpwriter) 58 rlomwriter.writeResource(refId, 'webcontent', path) 59 rlomwriter.writeLOMMetadata() 60 rlomwriter.writeLOMNode(LOM_namespace) 61 62 lang = object.Language() 63 if not lang: 64 lang = context.portal_properties.site_properties.getProperty('default_language') 65 if not lang: 66 lang = "x-none" 67 68 rlomwriter.writeGeneralNode(object.getId(), object.Title(), object.portal_url(), lang, object.Description(), object.Subject()) 69 70 rlomwriter.writeLifeCycleNode(object.Creators(), object.Contributors(), object.ModificationDate(), lang) 71 72 email = object.portal_url.getPortalObject().getProperty('email_from_address') 73 74 date = object.ModificationDate().decode('utf-8') 75 contributors = object.Contributors() 76 77 rlomwriter.writeMetaMetadata(object.id, object.portal_url(), email, date, LOM_version, lang, contributors) 78 rlomwriter.writeTechnical(object.Format(), self.getObjSize(object), object.renderBase()) 79 rights_holder = object.portal_properties.site_properties.getProperty('rights_holder') 80 rights_holder_email = object.portal_properties.site_properties.getProperty('rights_holder_email') 81 rlomwriter.writeRights(LOM_version, 'yes', self._getCopyrightString(object.Rights(), rights_holder, rights_holder_email), lang) 82 rlomwriter.writeCustomMetadata(object) 83 84 rlomwriter.writeFileNode(path) 85 86 self._writeObjectData(object, path) 87 88 self._writeObjectData(cpwriter.getManifest(), 'imsmanifest.xml') 89 90 if self.destination: 91 return self.destination.getOutput() 93 if destination: 94 return destination.getOutput() 92 95 else: 93 96 return None, None
Note: See TracChangeset
for help on using the changeset viewer.
