Changeset 378


Ignore:
Timestamp:
07/13/09 14:26:21 (5 years ago)
Author:
jon
Message:

Changing blackboard import to accomodate tufts blackboard packages

Location:
collective.imstransport/trunk/collective/imstransport/utilities
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • collective.imstransport/trunk/collective/imstransport/utilities/bb/bbreader.py

    r325 r378  
    11from xml.dom import minidom 
     2from urlparse import urlparse 
    23from collective.imstransport.IMS_exceptions import ManifestError 
    3 from configbb import LOM_BB_namespace, XML_namespace 
     4from configbb import LOM_BB_namespace, XML_namespace, EMBEDDED_STRING 
     5from Products.PageTemplates.PageTemplateFile import PageTemplateFile 
     6from collective.imstransport.utilities.interfaces import IIMSTransportUtility 
    47 
    58class BBReader(object): 
     
    5356                resource.getAttributeNS(XML_namespace, 'base')) 
    5457 
    55     def readFiles(self, resource): 
     58    def readFiles(self, resource, bbase): 
    5659        files = [] 
    5760        flns = resource.getElementsByTagName('file') 
     
    5962            for fln in flns: 
    6063                file = fln.getAttribute('href') 
    61                 files.append(file) 
     64                if bbase: 
     65                    files.append('%s/%s' %(bbase, file)) 
     66                else: 
     67                    files.append(file) 
    6268        return files 
    6369 
     
    9399                    value = isfolder_nodes[0].getAttribute('value') 
    94100                    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         
    96112 
    97113    def readTocItem(self, manifest, resid): 
     
    107123                    idref = item.getAttribute('identifierref') 
    108124                    if idref == resid: 
    109                         childitems = item.getElementsByTagName('item') 
     125                        childitems = item.childNodes 
    110126                        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) 
    113130        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         
    114261 
    115262         
  • collective.imstransport/trunk/collective/imstransport/utilities/bb/configbb.py

    r325 r378  
    44LOM_BB_namespace = 'http://www.blackboard.com/content-packaging/' 
    55XML_namespace = 'http://www.w3.org/XML/1998/namespace' 
     6EMBEDDED_STRING = '@X@EmbeddedFile.location@X@' 
    67 
    78namespaces = [('xmlns', 'http://www.imsglobal.org/xsd/imscp_v1p1'), 
  • collective.imstransport/trunk/collective/imstransport/utilities/bb/imsbbreader.py

    r335 r378  
    66from xml.parsers.expat import ExpatError 
    77from collective.imstransport.IMS_exceptions import ManifestError 
     8from BeautifulSoup import BeautifulSoup 
     9from Products.CMFCore.interfaces import ISiteRoot 
     10import htmlentitydefs 
     11from configbb import EMBEDDED_STRING 
    812import re 
    913 
     
    3034        for x in resources: 
    3135            resid, restype, bbfile, bbtitle, bbase = bbreader.readResourceAttributes(x) 
     36            doctext = filetoc = restoc = '' 
     37            metadata = {} 
    3238            if restype == 'resource/x-bb-document': 
    3339                metadata = {} 
     
    3743                    resnode = bbreader.parseDataFile(dataxml) 
    3844                    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) 
    5179                    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': 
    6991                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'] 
    7697                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] 
    7899                else: 
    79100                    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 
    83131        for z in tocpages: 
    84             text = '<table>' 
    85132            tocitems = bbreader.readTocItem(doc, z) 
     133            entries = [] 
    86134            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 
    91149                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 
    97153        objcreator = getUtility(IIMSObjectCreator) 
    98154        objcreator.createObjects(objDict, context, source) 
    99155 
    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): 
    101157        """ 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 
    109166        if file: 
    110             objDict[hash]['file'] =  file 
     167            metadata['file'] =  file 
    111168        if text: 
    112             objDict[hash]['text'] = text 
     169            metadata['text'] = text 
    113170 
     171def 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 
     183def unquotehtml(s): 
     184    """Convert a HTML quoted string into normal string (ISO-8859-1). 
     185 
     186    Works with &#XX; and with &nbsp; &gt; etc.""" 
     187    return re.sub(r'&(#?)(.+?);',convertentity,s)  
  • collective.imstransport/trunk/collective/imstransport/utilities/imsutility.py

    r195 r378  
    33from collective.imstransport.utilities.interfaces import IIMSTransportUtility, IIMSManifestWriter, IIMSManifestReader 
    44from OFS.SimpleItem import SimpleItem 
    5  
    65 
    76class IMSTransportUtility(SimpleItem): 
     
    3029            values.append((x[1].getPackageName(), x[0])) 
    3130        return values 
    32  
  • collective.imstransport/trunk/collective/imstransport/utilities/moodle/imsmoodlewriter.py

    r340 r378  
    120120                    path += '.html' 
    121121 
    122         return path 
     122        return path  
    123123 
    124124 
  • collective.imstransport/trunk/collective/imstransport/utilities/packagingio.py

    r325 r378  
    5252        return self.files.read(fn) 
    5353 
     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 
    5462 
    5563class ZipfileWriter: 
     
    6270        self.archive = StringIO() 
    6371        self.zipfile = ZipFile(self.archive, 'w', ZIP_DEFLATED) 
    64  
    6572 
    6673    def writeFile(self, path, data): 
  • collective.imstransport/trunk/collective/imstransport/utilities/webct/imswebctreader.py

    r325 r378  
    2727        for manifest in manifests: 
    2828            orgs =[] 
    29             manifestmetadata = webctreader.readMetadata(manifest) 
     29            manifestmetadata = webctreader.readPackageMetadata(manifest) 
    3030            if manifestmetadata.has_key('webcttype') and manifestmetadata['webcttype'] == 'Course': 
    3131                objDict['package'] = manifestmetadata 
  • collective.imstransport/trunk/collective/imstransport/utilities/webct/webctreader.py

    r325 r378  
    2424        if organizations: 
    2525            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') 
    2928                for item in item_nodes: 
    3029                    idref = item.getAttribute('identifierref') 
Note: See TracChangeset for help on using the changeset viewer.