Show
Ignore:
Timestamp:
07/03/09 10:26:36 (3 years ago)
Author:
jon
Message:

Adding back old imports without transform

Files:
1 modified

Legend:

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

    r177 r325  
    1 from zope.interface import implements 
    2 from collective.imstransport.utilities.interfaces import IIMSManifestReader, IIMSTransportUtility, IIMSObjectCreator 
    3 from collective.imstransport import IMSTransportMessageFactory as _ 
    4 from zipfile import ZipFile 
     1from collective.imstransport.utilities.imsinterchange import IMSReader 
     2from collective.imstransport.utilities.packagingio import ZipfileReader 
     3from collective.imstransport.utilities.bb.bbreader import BBReader 
    54from zope.component import getUtility 
    6 from Products.CMFCore.interfaces import ISiteRoot 
    7 from elementtree import ElementTree 
     5from collective.imstransport.utilities.interfaces import IIMSObjectCreator 
     6from xml.parsers.expat import ExpatError 
    87import re 
    9 from zope.component import getUtility 
    10 from collective.imstransport.utilities.packagingio import ZipfileReader 
    11 from collective.imstransport.utilities.imsinterchange import IMSInterchangeReader 
    128 
     9class IMSBBReader(IMSReader): 
     10    """ Create objects from IMS manifest. """ 
    1311 
    14 class IMSBBReader(IMSInterchangeReader): 
    15     """ Read an IMS CC package """ 
     12    def readPackage(self, file, context): 
     13        """ Read the manifest """ 
     14        source = ZipfileReader(file) 
     15        objDict = {} 
     16        if not source: 
     17             return False, 'Internal error. No source object specified' 
     18        bbreader = BBReader() 
     19        manifest = source.readManifest() 
     20        if not manifest: 
     21            raise ManifestError, 'Could not locate manifest file "imsmanifest.xml" in the zip archive.' 
     22        try: 
     23            doc = bbreader.parseManifest(manifest) 
     24        except ExpatError, e: 
     25            raise ManifestError, str(e) 
     26        tocpages = [] 
     27        orgs = bbreader.readOrganizations(doc) 
     28        resources = bbreader.readResources(doc) 
     29        for x in resources: 
     30            resid, restype, bbfile, bbtitle, bbase = bbreader.readResourceAttributes(x) 
     31            if restype == 'resource/x-bb-document': 
     32                metadata = {} 
     33                # read the data file 
     34                if bbfile: 
     35                    dataxml = source.readFile(bbfile) 
     36                    resnode = bbreader.parseDataFile(dataxml) 
     37                    metadata = bbreader.readMetadata(resnode) 
     38                files = bbreader.readFiles(x) 
     39                # If the resource is a file 
     40                if files: 
     41                    hash = resid 
     42                    objDict[hash] = metadata 
     43                    excludeFromNav = True 
     44                    file = '%s/%s' %(bbase, files[0]) 
     45                    type = self.determineType(objDict[hash], files[0]) 
     46                    id = self.createIdFromFile(files[0]) 
     47                    path = '%s' %bbase 
     48                    if orgs.has_key(resid): 
     49                        title = orgs[resid] 
     50                    else: 
     51                        title = id 
     52                    self.applyCoreMetadata(objDict, hash, id, path, excludeFromNav, type, title, file=file) 
     53                # If the resource is a document 
     54                else: 
     55                    hash = resid  
     56                    objDict[hash] = metadata 
     57                    excludeFromNav = True 
     58                    type = 'Document' 
     59                    id = resid 
     60                    path = '' 
     61                    if orgs.has_key(resid): 
     62                        title = orgs[resid] 
     63                    else: 
     64                        title = id 
     65                    self.applyCoreMetadata(objDict, hash, id, path, excludeFromNav, type, title) 
     66            # The resource is a table of contents page. 
     67            elif restype == 'course/x-bb-coursetoc': 
     68                hash = resid 
     69                objDict[hash] = {} 
     70                excludeFromNav = False 
     71                tocpages.append(resid) 
     72                type = 'Document' 
     73                path = '' 
     74                id = resid 
     75                if orgs.has_key(resid): 
     76                    title = re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', orgs[resid].split('.')[1]) 
     77                else: 
     78                    title = id 
     79                self.applyCoreMetadata(objDict, hash, id, path, excludeFromNav, type, title) 
    1680 
     81            # Build table of contents pages 
     82        for z in tocpages: 
     83            text = '<table>' 
     84            tocitems = bbreader.readTocItem(doc, z) 
     85            for titem in tocitems: 
     86                met = objDict[titem] 
     87                path = met['path'] 
     88                if path: 
     89                    linkpath = '%s/%s' %(path, objDict[titem]['id']) 
     90                else: 
     91                    linkpath = objDict[titem]['id'] 
     92                text += "<tr><td><a href='%s/view'>%s</a></td></tr>" %(linkpath, objDict[titem]['title']) 
     93            text += '</table>' 
     94            objDict[z]['text'] = text 
     95                 
     96        objcreator = getUtility(IIMSObjectCreator) 
     97        objcreator.createObjects(objDict, context, source) 
    1798 
    18     name = _(u'Blackboard') 
     99    def applyCoreMetadata(self, objDict, hash, id, path, excludeFromNav, type, title, file=None, text=None): 
     100        """ Helper function for applying metadata """ 
     101        objDict[hash]['id'] = id 
     102        objDict[hash]['path'] = path 
     103        objDict[hash]['excludeFromNav'] = excludeFromNav 
     104        if not (objDict[hash].has_key('type') and objDict[hash]['type']): 
     105            objDict[hash]['type'] = type 
     106        if not (objDict[hash].has_key('title') and objDict[hash]['title']): 
     107            objDict[hash]['title'] = title 
     108        if file: 
     109            objDict[hash]['file'] =  file 
     110        if text: 
     111            objDict[hash]['text'] = text 
    19112 
    20     BBNS = 'http://www.blackboard.com/content-packaging/' 
    21     XML = 'http://www.w3.org/XML/1998/namespace' 
    22  
    23     def getPackageName(self): 
    24         return self.name 
    25  
    26     def readPackage(self, context, input): 
    27         self.zf = ZipFile(input, 'r') 
    28         imsdoc = self.zf.read('imsmanifest.xml') 
    29          
    30         # Read in resources section 
    31         self.tree = ElementTree.XML(imsdoc) 
    32  
    33         # Enter resource data into a dictionary 
    34         resource_dictionary = self.readResources({}, self.tree) 
    35  
    36         self.zf.close() 
    37  
    38         objcreator = getUtility(IIMSObjectCreator) 
    39         objcreator.createObjects(resource_dictionary, context, ZipfileReader(input)) 
    40  
    41  
    42     def readResources(self, resDict, tree): 
    43  
    44         resourceNodes = tree.findall('resources/resource') 
    45          
    46         for resourceNode in resourceNodes: 
    47             self.readFiles(resDict, resourceNode) 
    48  
    49         return  resDict 
    50  
    51     def readFiles(self, resDict, resourceNode): 
    52  
    53         # Get information about the resource. 
    54         # 
    55         res_title = resourceNode.get('{%s}title' %(self.BBNS)) 
    56         # Determining which section it is in (e.g., Assignments, CourseInformation, ExternalLinks...) 
    57         res_title_parts = res_title.split(".") 
    58         if len(res_title_parts) == 4: 
    59             if res_title_parts[0] == 'COURSE_DEFAULT' and res_title_parts[2] == 'CONTENT_LINK' and res_title_parts[3] == 'label': 
    60                 # Converts camel case section title (e.g., CourseInformation) to its non-camelcase alternative and sets as title 
    61                 res_title = re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', res_title_parts[1]).strip(' ') 
    62         # Hash datfile information 
    63         datfile = resourceNode.get('{%s}file' %(self.BBNS)) 
    64         xmlbase = resourceNode.get('{%s}base' %(self.XML)) 
    65         # Hash the blackboard type information for the resource 
    66         bbtype = resourceNode.get('type') 
    67         # Hash the file information 
    68         fileNodes = resourceNode.findall('file') 
    69         id = resourceNode.get('identifier') 
    70          
    71      
    72         # Parse dat file 
    73         if datfile: 
    74             datText = self.readContentFile(datfile) 
    75         else: 
    76             datText = '' 
    77  
    78  
    79         # Show in navigation? 
    80         item_nodes_all = self.tree.findall("organizations//item") 
    81         targetItems = [node for node in item_nodes_all if node.get("identifierref") == id] 
    82         if targetItems: 
    83             excludeFromNav = False 
    84             # Are there any children? 
    85             child_nodes = targetItems[0].findall('item') 
    86         else: 
    87             excludeFromNav = True 
    88             child_nodes = [] 
    89  
    90  
    91         if len(fileNodes): 
    92             # Process resource with file nodes 
    93             files = [] 
    94             for fileNode in fileNodes: 
    95                 ## create the file object based on mimetype 
    96                 fileid = fileNode.get('href') 
    97                 files.append(('%s/%s/view' %(id, fileid),fileid)) 
    98                 type = self.determineFileMimetype(fileid) 
    99                 resDict[fileid] = {'file':fileid, 'path':id, 'title':fileid, 'id':fileid, 'type':type} 
    100             resText = self.TocPage('Table of Contents', files) 
    101         elif len(child_nodes): 
    102             # Create table of contents pages. 
    103             if not datText: 
    104                 items = [] 
    105                 for child_node in child_nodes: 
    106                     title_nodes = child_node.findall('title') 
    107                     if title_nodes: 
    108                         title = title_nodes[0].text 
    109                     else: 
    110                         title = '' 
    111                     items.append(('%s.html' %(child_node.get('identifierref')), title)) 
    112                 resText = self.TocPage('Table of Contents', items) 
    113             else: 
    114                 resText = datText 
    115         elif datText: 
    116             resText = datText 
    117         else: 
    118             resText = '' 
    119  
    120         resDict[id] = {'text':resText, 'path':'', 'title':res_title, 'id':'%s.html' %id, 'type':'Document'} 
    121  
    122  
    123     def TocPage(self, tabletitle, tocitems): 
    124          
    125         text = '' 
    126         text += '<table class="documentTable" style="width: 499px;" border="0" cellpadding="0" cellspacing="0">' 
    127         text += '<thead>' 
    128         text += '   <tr>' 
    129         text += '     <td>%s</td>' %tabletitle 
    130         text += '   </tr>' 
    131         text += '</thead>' 
    132         text += '<tbody>' 
    133         for tocitem in tocitems: 
    134             text += '     <tr tal:define="oddrow repeat/item/odd;" ' 
    135             text += '         tal:attributes="class oddrow)">' 
    136             text += '       <td ><a href="%s"' %tocitem[0]  
    137             text += '       >%s</a></td>' %tocitem[1] 
    138             text += '     </tr>' 
    139         text += '  </tbody>' 
    140         text += '</table>' 
    141  
    142         return text 
    143  
    144     def readContentFile(self, datfile): 
    145  
    146         # Read the proprietary blackboard.dat file 
    147         datdoc = self.zf.read(datfile)             
    148  
    149         # Parsing the dat file 
    150         contenttree = ElementTree.XML(datdoc) 
    151         text_nodes = contenttree.findall("BODY/TEXT") 
    152         resText = '' 
    153  
    154         # Get text information 
    155         if text_nodes: 
    156             resText = text_nodes[0].text 
    157  
    158         return resText 
    159  
    160