diff MetaData.py @ 3:3dadf0d89261

more renovation
author casties
date Tue, 26 Jul 2011 20:08:11 +0200
parents ac8e119b25ec
children 8291255b1868
line wrap: on
line diff
--- a/MetaData.py	Tue Jul 26 11:55:19 2011 +0200
+++ b/MetaData.py	Tue Jul 26 20:08:11 2011 +0200
@@ -35,9 +35,12 @@
     return rc
 
 
-def normalizeBibtype(bt):
+def normalizeBibField(bt, underscore=True):
     """returns normalised bib type for looking up mappings"""
     bt = bt.strip().replace(' ', '-').lower()
+    if underscore:
+        bt = bt.replace('_', '-')
+        
     return bt
 
 def getBibdataFromDom(dom):
@@ -47,10 +50,10 @@
     if bib is not None:
         # put type in @type
         type = bib.get('type')
-        bibinfo['@type'] = normalizedBibtype(type)
+        bibinfo['@type'] = normalizeBibField(type)
         # put all subelements in dict
         for e in bib:
-            bibinfo[e.tag] = getText(e)
+            bibinfo[normalizeBibField(e.tag)] = getText(e)
             
     return bibinfo
 
@@ -102,7 +105,7 @@
     manage_options = Folder.manage_options+(
         {'label':'Main Config','action':'changeMetadataForm'},
         {'label':'Import XML Schema','action':'importMetaDataExportXML'},
-        {'label':'Select Fields for Display','action':'indicateDisplayFieldsForm'},
+        #{'label':'Select Fields for Display','action':'indicateDisplayFieldsForm'},
         )
     
     def __init__(self,id,shortDescription='',description='',fields=''):
@@ -116,7 +119,6 @@
         
     def correctPath(self,path,remove=None,prefix=None,cut=0):
         """convinience method um einen pfad zu veraendern"""
-        
         if remove is not None:
             path=path.replace(remove,'')
         if prefix is not None:
@@ -131,11 +133,15 @@
         """imports metadata from the metadataexportxml file"""
         
         if importFile is None:
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','importMetaDataExportXML.zpt')).__of__(self)
+            pt=PageTemplateFile('zpt/importMetaDataExportXML', globals()).__of__(self)
             return pt()
         
-        dom=xml.dom.minidom.parse(importFile)
-        self.createMappingFromDom(dom.getElementsByTagName("metadataExport")[0])
+        dom=ET.parse(importFile)
+        node = dom.getroot()
+        if node.tag != 'metadataExport':
+            node = dom.find("metadataExport")
+            
+        self.createMappingFromDom(node)
         
         if RESPONSE is not None:
             RESPONSE.redirect('manage_main')
@@ -147,39 +153,43 @@
         if metadata is None:
             metadata=self
         
-        nodes=metadatanode.childNodes
+        nodes=metadatanode
         
-        #erster schritt: anlegen der fieldlist
         for node in nodes:
             logging.debug("node: %s"%repr(node))
-            if node.tagName=="set":
+            if node.tag=="set":
                 set=node
-                if set.getAttribute('name')=='generic':
-                   list=[]
-                   for entry in set.getElementsByTagName('entry'):
-                       list.append(entry.getAttribute('genericName'))
-                   metadata.fieldList=list[0:]
-                   
-                else:
-                   id=set.getAttribute('name').encode('utf-8')
-                   list=[]
-                   argList={}
-                   for entry in set.getElementsByTagName('entry'):
-                       genericName=entry.getAttribute('genericName')
-                       tag=entry.getAttribute('tag')
-                       label=entry.getAttribute('label')
-                       description=getTextFromNode(entry.childNodes) #TODO: clean
-                       argList[genericName]=(tag,label,description)
-                   metadata._setObject(id,MetaDataMapping(id,id,argList))
-   
-            elif node.tagName=="metadata":
+                id=set.get('name')
+                list=[]
+                argList={}
+                for entry in set:
+                    genericName=entry.get('genericName')
+                    if set.get('name')=='generic':
+                        # generic mapping doesn't have labels
+                        tag = genericName
+                        label = genericName
+                    else:
+                        tag=entry.get('tag')
+                        label=entry.get('label')
+                        
+                    if not tag:
+                        # ignore empty tags
+                        continue
+                    
+                    description=getText(entry)
+                    argList[tag]={'tag':tag,'label':label,'explanation':description,'status':'optional'}
+                    
+                logging.debug("createMappingFromDom: new mapping=%s"%repr(argList))
+                metadata._setObject(id,MetaDataMapping(id,id,argList))
+
+            elif node.tag=="metadata":
                mn=node
-               name=mn.getAttribute('name').encode('utf-8')
+               name=mn.get('name')
+               logging.debug("createMappingFromDom: new metadata=%s"%repr(name))
                metadata._setObject(name,MetaData(name,name))
                mdObj=getattr(metadata,name)
                mdObj.createMappingFromDom(mn)
     
-    
     def getMDFromPathOrUrl(self,path):
         parsedurl = urlparse.urlparse(path)
         if parsedurl[0] != "":
@@ -273,26 +283,75 @@
         ret+="</bib>"
         return ret
 
+
+    def getBibMapping(self, bibtype):
+        """returns MetaDataMapping for bibtype"""
+        # try type as id
+        mapping = getattr(self.main.meta.bib, bibtype, None)
+        if mapping is None:
+            # try manually
+            mapFolder = self.main.meta.bib
+            for obj in mapFolder.objectValues():
+                if obj.meta_type == "MetadataMapping":
+                    # real type is in title
+                    mapType = obj.title
+                    if mapType == bibtype:
+                        # try type as is
+                        return obj
+                    
+                    if normalizeBibField(mapType, underscore=True) == normalizeBibField(bibtype, underscore=True):
+                        # try normalized type without underscore
+                        return obj
+ 
+        return mapping
     
     def getBibFields(self, bibdata):
         """returns dict with metadata description for bibdata"""
+        bibfields = {}
         bibtype = bibdata['@type']
         # get mapping from main/meta/bib
-        try:
-            mapping=getattr(self.main.meta.bib, bibtype.lower())
-        except:
-            logging.error("getStdMappedHash: no mapping for type: %s"%bibtype)
-            return mdHash
+        mapping = self.getBibMapping(bibtype)
+        if mapping is None:
+            logging.error("getBibFields: no mapping for type: %s"%bibtype)
+            return bibfields
             
-        # get field descriptions
-        bibFields = mapping.getFields.copy()
+        # get field descriptions (copy so we can change it)
+        bibfields = mapping.getFields().copy()
         # add field list
-        bibFields['@fieldList'] = mapping.getFieldList()
+        bibfields['@fieldList'] = mapping.getFieldList()            
         
-        return bibFields
+        return bibfields
 
+    def getBibMappedData(self, bibdata, allFields=False):
+        """returns dict with metadata descriptions and data for bibdata"""
+        bibfields = self.getBibFields(bibdata)
+        mappedData = {}
+        mappedList = []
+        for bk in bibfields.keys():
+            # ignore descriptions without data
+            if not bibdata.get(bk, None):
+                continue
+            
+            # field description (copy so we can change it)
+            bf = bibfields[bk].copy()
+            # add value
+            bf['value'] = bibdata[bk]
+            mappedData[bk] = bf
+            mappedList.append(bk)
+        
+        if allFields and len(mappedData) < len(bibdata):
+            # add fields that were not in bibfields
+            for bk in bibdata.keys():
+                if bk in mappedData or not bibdata[bk]:
+                    continue
+                
+                mappedData[bk] = {'tag':bk, 'label':bk, 'value':bibdata[bk]}
+                mappedList.append(bk)
+                
+        mappedData['@fieldList'] = mappedList
+        return mappedData
     
-    def getFormatted(self, template, path=None, dom=None, bibdata=None):
+    def getFormatted(self, template, path=None, dom=None, bibdata=None, allFields=False):
             """returns string with document data formatted according to template.
                gets data from server or dom or pre-parsed bibdata."""
             logging.debug("getFormatted(template=%s)"%(template))
@@ -321,9 +380,9 @@
                     return ""
             
             # put bib field descriptions in mdHash        
-            bibFields = self.getBibFields(bibdata)
+            bibfields = self.getBibMappedData(bibdata, allFields=allFields)
                 
-            return tp(bibFields=bibFields, md=bibdata)
+            return tp(mdmap=bibfields, md=bibdata)
 
                 
     def getFormattedMetaData(self, path=None, dom=None, bibdata=None):
@@ -339,7 +398,7 @@
     def getFormattedMetaDataExtended(self,path=None, dom=None, bibdata=None):
             """get the metadafrom server"""
             logging.debug("getFormattedMetaDataExtended(path=%s)"%path)
-            return self.getFormatted('metadata_extended_template', path=path, dom=dom, bibdata=bibdata)
+            return self.getFormatted('metadata_extended_template', path=path, dom=dom, bibdata=bibdata, allFields=True)
             
     def getFormattedLabel(self,path=None, dom=None, bibdata=None):
             """get the metadafrom server"""
@@ -354,7 +413,7 @@
     def getFormattedMetaDataExtendedFromServer(self,path):
             """get the metadafrom server"""
             logging.debug("getFormattedMetaDataExtendedFromServer(path=%s)"%path)
-            return self.getFormatted('metadata_extended_template', path)
+            return self.getFormatted('metadata_extended_template', path=path, allFields=True)
             
     def getFormattedLabelFromServer(self,path):
             """get the metadafrom server"""