Changeset 378
- Timestamp:
- 07/13/09 14:26:21 (4 years ago)
- Location:
- collective.imstransport/trunk/collective/imstransport/utilities
- Files:
-
- 8 edited
-
bb/bbreader.py (modified) (5 diffs)
-
bb/configbb.py (modified) (1 diff)
-
bb/imsbbreader.py (modified) (3 diffs)
-
imsutility.py (modified) (2 diffs)
-
moodle/imsmoodlewriter.py (modified) (1 diff)
-
packagingio.py (modified) (2 diffs)
-
webct/imswebctreader.py (modified) (1 diff)
-
webct/webctreader.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
collective.imstransport/trunk/collective/imstransport/utilities/bb/bbreader.py
r325 r378 1 1 from xml.dom import minidom 2 from urlparse import urlparse 2 3 from collective.imstransport.IMS_exceptions import ManifestError 3 from configbb import LOM_BB_namespace, XML_namespace 4 from configbb import LOM_BB_namespace, XML_namespace, EMBEDDED_STRING 5 from Products.PageTemplates.PageTemplateFile import PageTemplateFile 6 from collective.imstransport.utilities.interfaces import IIMSTransportUtility 4 7 5 8 class BBReader(object): … … 53 56 resource.getAttributeNS(XML_namespace, 'base')) 54 57 55 def readFiles(self, resource ):58 def readFiles(self, resource, bbase): 56 59 files = [] 57 60 flns = resource.getElementsByTagName('file') … … 59 62 for fln in flns: 60 63 file = fln.getAttribute('href') 61 files.append(file) 64 if bbase: 65 files.append('%s/%s' %(bbase, file)) 66 else: 67 files.append(file) 62 68 return files 63 69 … … 93 99 value = isfolder_nodes[0].getAttribute('value') 94 100 if value == 'true': 95 md['type'] = 'Folder' 101 md['bbtype'] = 'Folder' 102 handler_nodes = content_node.getElementsByTagName('CONTENTHANDLER') 103 if handler_nodes: 104 value = handler_nodes[0].getAttribute('value') 105 if value == 'resource/x-bb-externallink': 106 url_nodes = content_node.getElementsByTagName('URL') 107 if url_nodes: 108 url = url_nodes[0].getAttribute('value') 109 if url: 110 md['bbtype'] = 'Link' 111 md['remoteUrl'] = url 96 112 97 113 def readTocItem(self, manifest, resid): … … 107 123 idref = item.getAttribute('identifierref') 108 124 if idref == resid: 109 childitems = item. getElementsByTagName('item')125 childitems = item.childNodes 110 126 for x in childitems: 111 itemid = x.getAttribute('identifierref') 112 tocitems.append(itemid) 127 if x.nodeName == 'item': 128 itemid = x.getAttribute('identifierref') 129 tocitems.append(itemid) 113 130 return tocitems 131 132 def readEmbeddedTags(self, soup): 133 """ Read embedded tags from a text file """ 134 prevlink = None 135 links = self.getDocumentHrefLinks(soup) 136 for link in links: 137 if 'embedded' in link['href']: 138 if prevlink and prevlink != link['href']: 139 return None 140 prevlink = link['href'] 141 links = self.getDocumentSrcLinks(soup) 142 for link in links: 143 if 'embedded' in link['src']: 144 if prevlink and prevlink != link['src']: 145 return None 146 return prevlink 147 148 def createTocPage(self, entries): 149 """ Create a table of links """ 150 text = '<table>' 151 for z in entries: 152 text += "<tr><td><a href='%s'>%s</a></td></tr>" %(z[0], z[1]) 153 text += '</table>' 154 return text 155 156 def runDocumentFilters(self, utils, soup, vars, base): 157 """ Run a filter over the links """ 158 links = [] 159 links = self.getDocumentHrefLinks(soup) 160 for link in links: 161 orig = link['href'] 162 link['href'] = self.filterDocumentLink(link['href'], utils, vars, base) 163 links = [] 164 links = self.getDocumentSrcLinks(soup) 165 for link in links: 166 orig = link['src'] 167 link['src'] = self.filterDocumentLink(link['src'], utils, vars, base) 168 return soup.prettify() 169 170 def getDocumentHrefLinks(self, soup): 171 links = [] 172 tags = soup.findAll(href=True) 173 from urlparse import urlparse 174 for tag in tags: 175 if tag.has_key('href'): 176 url = urlparse('href') 177 if not url[1] or 'localhost' in url[1]: 178 links.append(tag) 179 return links 180 181 def getDocumentSrcLinks(self, soup): 182 links = [] 183 tags = soup.findAll(src=True) 184 from urlparse import urlparse 185 for tag in tags: 186 if tag.has_key('src'): 187 url = urlparse('src') 188 if not url[1] or 'localhost' in url[1]: 189 links.append(tag) 190 return links 191 192 def _convertBBVariables(self, link, vars, base): 193 """ Convert BB variables to their counterparts """ 194 lnk = link 195 for var in vars: 196 if base: 197 replace = '%s/%s/' %(base, var[1]) 198 else: 199 replace = var[1] 200 lnk = link.replace(var[0], replace) 201 return lnk 202 203 def _convertURLEntities(self, link): 204 """ Convert BB variables to their counterparts """ 205 lnk = link 206 import urllib 207 lnk = urllib.unquote(lnk) 208 return lnk 209 210 def _convertToNormalizedLink(self, link, utils): 211 """ Normalize the link so it can be imported without errors """ 212 lnk = link 213 url = urlparse(lnk) 214 urlfile = url[2].split('/') 215 urlfile[-1] = utils.normalizeString(urlfile[-1]) 216 lnk = '/'.join(urlfile) 217 return lnk 218 219 def filterDocumentLink(self, link, utils, vars, base): 220 lnk = link 221 from urlparse import urlparse 222 url = urlparse(lnk) 223 if url[2] and not url[0]: 224 lnk = self._convertBBVariables(lnk, vars, base) 225 lnk = self._convertURLEntities(lnk) 226 lnk = self._convertToNormalizedLink(lnk, utils) 227 return lnk 228 229 def runFilters(self, text, filters, **kw): 230 rettext = text 231 for filter in filters: 232 if 'embed' == filter: 233 rettext = self.replaceEmbedVariables(rettext, kw['base']) 234 elif 'reflinks' == filter: 235 rettext = self.rewriteReferenceLinks(rettext) 236 return rettext 237 238 def replaceEmbedVariables(self, text, base): 239 """ Remove the proprietary embed variables and replace with proper path """ 240 if base: 241 rpath = '%s/embed/' %base 242 return text.replace(EMBEDDED_STRING, rpath) 243 244 def rewriteReferenceLinks(self, text): 245 """ Rewrite all reference links """ 246 247 def removeUrlEntities(self, href): 248 """ Remove the URL entities from the string """ 249 250 251 252 253 254 255 256 257 258 259 260 114 261 115 262 -
collective.imstransport/trunk/collective/imstransport/utilities/bb/configbb.py
r325 r378 4 4 LOM_BB_namespace = 'http://www.blackboard.com/content-packaging/' 5 5 XML_namespace = 'http://www.w3.org/XML/1998/namespace' 6 EMBEDDED_STRING = '@X@EmbeddedFile.location@X@' 6 7 7 8 namespaces = [('xmlns', 'http://www.imsglobal.org/xsd/imscp_v1p1'), -
collective.imstransport/trunk/collective/imstransport/utilities/bb/imsbbreader.py
r335 r378 6 6 from xml.parsers.expat import ExpatError 7 7 from collective.imstransport.IMS_exceptions import ManifestError 8 from BeautifulSoup import BeautifulSoup 9 from Products.CMFCore.interfaces import ISiteRoot 10 import htmlentitydefs 11 from configbb import EMBEDDED_STRING 8 12 import re 9 13 … … 30 34 for x in resources: 31 35 resid, restype, bbfile, bbtitle, bbase = bbreader.readResourceAttributes(x) 36 doctext = filetoc = restoc = '' 37 metadata = {} 32 38 if restype == 'resource/x-bb-document': 33 39 metadata = {} … … 37 43 resnode = bbreader.parseDataFile(dataxml) 38 44 metadata = bbreader.readMetadata(resnode) 39 files = bbreader.readFiles(x) 40 # If the resource is a file 41 if files: 42 hash = resid 43 objDict[hash] = metadata 44 excludeFromNav = True 45 file = '%s/%s' %(bbase, files[0]) 46 type = self.determineType(objDict[hash], files[0]) 47 id = self.createIdFromFile(files[0]) 48 path = '%s' %bbase 49 if orgs.has_key(resid): 50 title = orgs[resid] 45 if metadata.has_key('text') and metadata['text']: 46 mtext = metadata['text'] 47 if type(mtext) == type(u''): 48 mtext = mtext.encode('utf-8') 49 ptext = unquotehtml(mtext) 50 utils = getUtility(ISiteRoot).plone_utils 51 soup = BeautifulSoup(ptext) 52 doctext = bbreader.runDocumentFilters(utils, soup, [(EMBEDDED_STRING, 'embedded'),], bbase) 53 # Handle Files 54 files = bbreader.readFiles(x, bbase) 55 entries = [] 56 for y in files: 57 dhash = resid + y 58 objDict[dhash] = {} 59 dexcludeFromNav = True 60 dfile = y 61 dfileparts = y.split('/') 62 # File is embedded 63 if 'embedded' in y: 64 # Link is encrypted 65 if len(dfileparts) > 0 and dfileparts[-1][0] == '!' and doctext: 66 soup = BeautifulSoup(doctext) 67 embeddedpath = bbreader.readEmbeddedTags(soup) 68 if embeddedpath: 69 dfile = embeddedpath 70 dfilepath = self.createPathFromFile(dfile) 71 did = self.createIdFromFile(dfile) 72 dtype = self.determineType(objDict[dhash], dfile) 73 portal = getUtility(ISiteRoot) 74 utils = portal.plone_utils 75 did = utils.normalizeString(did) 76 dtitle = did 77 if dfilepath: 78 linkpath = '%s/%s' %(dfilepath, did) 51 79 else: 52 title = id 53 self.applyCoreMetadata(objDict, hash, id, path, excludeFromNav, type, title, file=file) 54 # If the resource is a document 55 else: 56 hash = resid 57 objDict[hash] = metadata 58 excludeFromNav = True 59 type = 'Document' 60 id = resid 61 path = '' 62 if orgs.has_key(resid): 63 title = orgs[resid] 64 else: 65 title = id 66 self.applyCoreMetadata(objDict, hash, id, path, excludeFromNav, type, title) 67 # The resource is a table of contents page. 68 elif restype == 'course/x-bb-coursetoc': 80 linkpath = did 81 binfile = y 82 folder_files = source.getFolderFiles(dfilepath) 83 if len(folder_files) == 1: 84 binfile = folder_files[0] 85 entries.append((linkpath, dtitle)) 86 self.applyCoreMetadata(objDict[dhash], did, dfilepath, dexcludeFromNav, dtype, dtitle, file=binfile) 87 if entries: 88 filetoc = bbreader.createTocPage(entries) 89 # Handle links 90 if metadata.has_key('bbtype') and metadata['bbtype'] == 'Link': 69 91 hash = resid 70 objDict[hash] = {} 71 excludeFromNav = False 72 tocpages.append(resid) 73 type = 'Document' 74 path = '' 75 id = resid 92 objDict[hash] = metadata 93 filepath = '' 94 id = resid + '.link' 95 excludeFromNav = True 96 ptype = metadata['bbtype'] 76 97 if orgs.has_key(resid): 77 title = re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', orgs[resid].split('.')[1])98 title = orgs[resid] 78 99 else: 79 100 title = id 80 self.applyCoreMetadata(objDict, hash, id, path, excludeFromNav, type, title) 81 82 # Build table of contents pages 101 self.applyCoreMetadata(objDict[hash], id, filepath, excludeFromNav, ptype, title) 102 elif restype in ['resource/x-bb-document', 'course/x-bb-coursetoc']: 103 # Handle normal bb-documents 104 hash = resid 105 objDict[hash] = metadata 106 filepath = '' 107 excludeFromNav = True 108 ptype = 'Document' 109 id = resid + '.html' 110 if orgs.has_key(resid): 111 title = orgs[resid] 112 else: 113 title = id 114 # It's a folder object: 115 isFolder = metadata.has_key('bbtype') and metadata['bbtype'] == 'Folder' 116 if isFolder or restype == 'course/x-bb-coursetoc': 117 tocpages.append(resid) 118 # It's a table of contents object 119 if restype == 'course/x-bb-coursetoc': 120 if orgs.has_key(resid): 121 excludeFromNav = False 122 orgstitle = orgs[resid].split('.') 123 # Rewrite label tag 124 if len(orgstitle) > 1 and orgstitle[-1] == 'label': 125 title = re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', orgs[resid].split('.')[1]) 126 text = doctext 127 if type(filetoc) == type(u''): 128 text += filetoc.encode('utf-8') 129 self.applyCoreMetadata(objDict[hash], id, filepath, excludeFromNav, ptype, title, text=text) 130 # Build table of contents pages 83 131 for z in tocpages: 84 text = '<table>'85 132 tocitems = bbreader.readTocItem(doc, z) 133 entries = [] 86 134 for titem in tocitems: 87 met = objDict[titem] 88 path = met['path'] 89 if path: 90 linkpath = '%s/%s' %(path, objDict[titem]['id']) 135 if objDict.has_key(titem): 136 met = objDict[titem] 137 path = met['path'] 138 if path: 139 linkpath = '%s/%s' %(path, objDict[titem]['id']) 140 else: 141 linkpath = objDict[titem]['id'] 142 entries.append((linkpath, met['title'])) 143 if entries: 144 if objDict[z].has_key('text') and objDict[z]['text']: 145 gtext = objDict[z]['text'] 146 if type(gtext) == type(u''): 147 gtext = gtext.encode('utf-8') 148 objDict[z]['text'] = bbreader.createTocPage(entries).encode('utf-8') + gtext 91 149 else: 92 linkpath = objDict[titem]['id'] 93 text += "<tr><td><a href='%s/view'>%s</a></td></tr>" %(linkpath, objDict[titem]['title']) 94 text += '</table>' 95 objDict[z]['text'] = text 96 150 objDict[z]['text'] = bbreader.createTocPage(entries).encode('utf-8') 151 else: 152 objDict[z]['excludeFromNav'] = True 97 153 objcreator = getUtility(IIMSObjectCreator) 98 154 objcreator.createObjects(objDict, context, source) 99 155 100 def applyCoreMetadata(self, objDict, hash, id, path, excludeFromNav, type, title, file=None, text=None):156 def applyCoreMetadata(self, metadata, id, path, excludeFromNav, type, title, file=None, text=None): 101 157 """ Helper function for applying metadata """ 102 objDict[hash]['id'] = id 103 objDict[hash]['path'] = path 104 objDict[hash]['excludeFromNav'] = excludeFromNav 105 if not (objDict[hash].has_key('type') and objDict[hash]['type']): 106 objDict[hash]['type'] = type 107 if not (objDict[hash].has_key('title') and objDict[hash]['title']): 108 objDict[hash]['title'] = title 158 portal = getUtility(ISiteRoot) 159 utils = portal.plone_utils 160 metadata['id'] = utils.normalizeString(id) 161 metadata['path'] = path 162 metadata['excludeFromNav'] = excludeFromNav 163 metadata['type'] = type 164 if not (metadata.has_key('title') and metadata['title']): 165 metadata['title'] = title 109 166 if file: 110 objDict[hash]['file'] = file167 metadata['file'] = file 111 168 if text: 112 objDict[hash]['text'] = text169 metadata['text'] = text 113 170 171 def convertentity(m): 172 """Convert a HTML entity into normal string (ISO-8859-1)""" 173 if m.group(1)=='#': 174 try: 175 return chr(int(m.group(2))) 176 except ValueError: 177 return '&#%s;' % m.group(2) 178 try: 179 return htmlentitydefs.entitydefs[m.group(2)] 180 except KeyError: 181 return '&%s;' % m.group(2) 182 183 def unquotehtml(s): 184 """Convert a HTML quoted string into normal string (ISO-8859-1). 185 186 Works with &#XX; and with > etc.""" 187 return re.sub(r'&(#?)(.+?);',convertentity,s) -
collective.imstransport/trunk/collective/imstransport/utilities/imsutility.py
r195 r378 3 3 from collective.imstransport.utilities.interfaces import IIMSTransportUtility, IIMSManifestWriter, IIMSManifestReader 4 4 from OFS.SimpleItem import SimpleItem 5 6 5 7 6 class IMSTransportUtility(SimpleItem): … … 30 29 values.append((x[1].getPackageName(), x[0])) 31 30 return values 32 -
collective.imstransport/trunk/collective/imstransport/utilities/moodle/imsmoodlewriter.py
r340 r378 120 120 path += '.html' 121 121 122 return path 122 return path 123 123 124 124 -
collective.imstransport/trunk/collective/imstransport/utilities/packagingio.py
r325 r378 52 52 return self.files.read(fn) 53 53 54 def getFolderFiles(self, path): 55 """ Returns the files within a specific folder """ 56 retfiles = [] 57 for fn in self.files.namelist(): 58 if path +'/' in fn: 59 retfiles.append(fn) 60 return retfiles 61 54 62 55 63 class ZipfileWriter: … … 62 70 self.archive = StringIO() 63 71 self.zipfile = ZipFile(self.archive, 'w', ZIP_DEFLATED) 64 65 72 66 73 def writeFile(self, path, data): -
collective.imstransport/trunk/collective/imstransport/utilities/webct/imswebctreader.py
r325 r378 27 27 for manifest in manifests: 28 28 orgs =[] 29 manifestmetadata = webctreader.read Metadata(manifest)29 manifestmetadata = webctreader.readPackageMetadata(manifest) 30 30 if manifestmetadata.has_key('webcttype') and manifestmetadata['webcttype'] == 'Course': 31 31 objDict['package'] = manifestmetadata -
collective.imstransport/trunk/collective/imstransport/utilities/webct/webctreader.py
r325 r378 24 24 if organizations: 25 25 organization_nodes = organizations[0].getElementsByTagName('organization') 26 if organization_nodes: 27 organization_node = organization_nodes[0] 28 item_nodes = organization_nodes[0].getElementsByTagName('item') 26 for organization_node in organization_nodes: 27 item_nodes = organization_node.getElementsByTagName('item') 29 28 for item in item_nodes: 30 29 idref = item.getAttribute('identifierref')
Note: See TracChangeset
for help on using the changeset viewer.
