view MetaDataFolder.py @ 5:c1dbf78cc036

more MetaDataFolder
author casties
date Wed, 27 Jul 2011 14:48:56 +0200
parents 8291255b1868
children 00147a1ab4ac
line wrap: on
line source

from OFS.Folder import Folder
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Globals import package_home
from AccessControl import ClassSecurityInfo
import os.path
import logging

from MetaDataMapping import MetaDataMapping
from MetaData import MetaData

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):
    """returns dict with all elements from bib-tag"""
    bibinfo = {}
    bib = dom.find(".//meta/bib")
    if bib is not None:
        # put type in @type
        type = bib.get('type')
        bibinfo['@type'] = normalizeBibField(type)
        # put all subelements in dict
        for e in bib:
            bibinfo[normalizeBibField(e.tag)] = getText(e)
            
    return bibinfo

class MetaDataFolder(Folder):
    """provides methods for managing complete metadata structures"""
    meta_type='MetaDataFolder'
    security=ClassSecurityInfo()
    manage_options = Folder.manage_options+(
        {'label':'Main Config','action':'changeMetaDataFolderForm'},
        )

    def __init__(self,id,title='',metaDataServerUrl=''):
        """initialize a new instance"""
        self.id = id
        self.title = title
        self.metaDataServerUrl = metaDataServerUrl

        
    def getMDFromPathOrUrl(self,path):
        parsedurl = urlparse.urlparse(path)
        if parsedurl[0] != "":
            # has schema (e.g. http)
            url=path
        else:
            # path only
            if path.endswith("index.meta"):
                url =self.metaDataServerUrl%path
            else:
                url=os.path.join(self.metaDataServerUrl%path,'index.meta')
            
        #logging.debug("get Metadata: %s"%url)
        md = getHttpData(url)
        return md

    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
        mapping = self.getBibMapping(bibtype)
        if mapping is None:
            logging.error("getBibFields: no mapping for type: %s"%bibtype)
            return bibfields
            
        # get field descriptions (copy so we can change it)
        bibfields = mapping.getFields().copy()
        # add field list
        bibfields['@fieldList'] = mapping.getFieldList()            
        
        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, 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))
            
            if dom is None and bibdata is None:
                # get from server
                md = self.getMDFromPathOrUrl(path.replace("/mpiwg/online",""))
                #logging.debug("md:"+md)
                #dom = amara.parse(md)
                dom = ET.fromstring(md)
                
            # get contents of bib tag
            if bibdata is None:
                bibdata = getBibdataFromDom(dom)

            bibtype = bibdata['@type']
           
            # get template
            tp=getattr(self,"%s_%s"%(template, bibtype.lower()), None)
            if tp is None:
                logging.warning("getFormatted: no template for: %s_%s"%(template, bibtype))
                # try generic
                tp=getattr(self,"%s_generic"%(template), None)
                if tp is None:
                    logging.error("getFormatted: no generic template either: %s"%(template))
                    return ""
            
            # put bib field descriptions in mdHash        
            bibfields = self.getBibMappedData(bibdata, allFields=allFields)
                
            return tp(mdmap=bibfields, md=bibdata)

                
    def getFormattedMetaData(self, path=None, dom=None, bibdata=None):
            """get the metadafrom server"""
            logging.debug("getFormattedMetaData(path=%s)"%path)
            return self.getFormatted('metadata_template', path=path, dom=dom, bibdata=bibdata)
                
    def getFormattedMetaDataShort(self, path=None, dom=None, bibdata=None):
            """get the metadafrom server"""
            logging.debug("getFormattedMetaDataShort(path=%s)"%path)
            return self.getFormatted('metadata_template', path=path, dom=dom, bibdata=bibdata)
                
    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, allFields=True)
            
    def getFormattedLabel(self,path=None, dom=None, bibdata=None):
            """get the metadafrom server"""
            logging.debug("getFormattedLabel(%s)"%path)
            return self.getFormatted('label_template', path=path, dom=dom, bibdata=bibdata)
                        
    def getFormattedMetaDataShortFromServer(self,path):
            """get the metadafrom server"""
            logging.debug("getFormattedMetaDataShortFromServer(path=%s)"%path)
            return self.getFormatted('metadata_template', path)
                
    def getFormattedMetaDataExtendedFromServer(self,path):
            """get the metadafrom server"""
            logging.debug("getFormattedMetaDataExtendedFromServer(path=%s)"%path)
            return self.getFormatted('metadata_extended_template', path=path, allFields=True)
            
    def getFormattedLabelFromServer(self,path):
            """get the metadafrom server"""
            logging.debug("getFormattedLabelFromServer(%s)"%path)
            return self.getFormatted('label_template', path)

                        
    changeMetaDataFolderForm = PageTemplateFile('zpt/changeMetaDataFolder',globals())
    
    security.declarePublic('changeMetaDataFolder')
    def changeMetaDataFolder(self,title,metaDataServerUrl,RESPONSE=None):
        """Change MetaDataFolder"""
        self.title = title
        self.metaDataServerUrl=metaDataServerUrl
        if RESPONSE is not None:
            RESPONSE.redirect('manage_main')


manage_addMetaDataFolderForm = PageTemplateFile('zpt/addMetaDataFolderForm',globals())

def manage_addMetaDataFolder(self,id,title,RESPONSE=None):
    """a MetaDataFolder objekt"""
    newObj=MetaDataFolder(id,title)
    self.Destination()._setObject(id,newObj)
    if RESPONSE is not None:
        RESPONSE.redirect('manage_main')