Annotation of OSA_system2/OSAS_metadata.py, revision 1.6
1.1 dwinter 1: """ Classes for managing metadata"""
2:
3: from OFS.SimpleItem import SimpleItem
4: from Globals import InitializeClass,package_home
5: from OFS.Folder import Folder
6: from AccessControl import ClassSecurityInfo
7: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
8: import os.path
1.5 dwinter 9: import sys
1.1 dwinter 10: import xml.dom.minidom
1.4 dwinter 11: import xml.dom.pulldom
1.1 dwinter 12: import OSAS_helpers
13: import zLOG
1.4 dwinter 14: import string
15: import xml.xpath
16: import xmlrpclib
17:
18: from types import *
1.1 dwinter 19:
20: class OSAS_MetadataMapping(SimpleItem):
21: """Einfaches Mapping Object"""
22:
23: meta_type="OSAS_MetadataMapping__neu"
24:
25: def readFieldsFromParent(self):
26: """read all elements from root"""
27:
28: return self.aq_parent.fieldList
29:
30: def __init__(self,id,title,arglist):
31: """init
32: @param id: id
33: @param title: title fuer zope navigation
34: @param arglist: dictionary mit Namen der zugelassenen generische Metadaten als key und Tripel als Werte (human readable, tag version,explanation
35: """
36: self.id=id
37: self.title=title
38: for fieldName in arglist.keys():
39: setattr(self,"md_"+fieldName,arglist[fieldName])
40:
41:
42: manage_options = SimpleItem.manage_options+(
43: {'label':'Main Config','action':'changeMetadataMappingForm'},
44: )
45:
46:
47: def showSetXML(self,RESPONSE=None):
48: """prints out the mapping as XML"""
49: ret="""<set name="%s">"""%self.title
50: for fieldName in self.readFieldsFromParent():
51: entry=getattr(self,"md_"+fieldName)
52: if entry[2]=="": # no explanation of this field
53: ret+="""<entry genericName="%s" tag="%s" label="%s"/>"""%(fieldName,entry[0],entry[1])
54: else:
55: ret+="""<entry genericName="%s" tag="%s" label="%s">%s</entry>"""%(fieldName,entry[0],entry[1],entry[2])
56: ret+="</set>"
57:
58: if not RESPONSE:
59: return ret
60: else:
61: self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
62: return ret
63:
64: def getValue(self,fieldName):
65: """get md value
66: @param fieldName: Bezeichnung des gesuchten Metadatums
67: @retunr: Value des Metadatums"""
1.4 dwinter 68:
69: ret= getattr(self,"md_"+fieldName,(None,None,None,None,None))
70: if len(ret)!= 4: # alte MD haben keine info ueber optional/required und listen werte
71: ret=ret+("","")
72: return ret
73:
1.1 dwinter 74:
75: def isEmptyValue(self,fieldName):
76: """teste ob fielname in diesem Metadatenschema definiert ist"""
77: field=getattr(self,"md_"+fieldName,'')
78: if field[1]=='':
79: return 0
80: else:
81: return 1
82:
83: def generateMappingHash(self):
84: """erzeugen des dictionaries: generisches Feld -> Definition in diesem Schema"""
85: hash={}
86: for field in self.fieldList:
87: hash[field]=getattr(self,"md_"+field)
88: return hash
89:
90:
91:
92: def changeMetadataMappingForm(self):
93: """change"""
94: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeMetadataMapping.zpt')).__of__(self)
95: return pt()
96:
97: def changeMetadataMapping(self,titleOfObject,RESPONSE=None):
98: """change"""
99:
100: self.title=titleOfObject
101: arglist=self.REQUEST.form
102:
103: for fieldName in self.readFieldsFromParent():
1.4 dwinter 104: setattr(self,"md_"+fieldName,(arglist[fieldName],arglist['label_'+fieldName],arglist['explanation_'+fieldName],arglist['status_'+fieldName],arglist['values_'+fieldName]))
1.1 dwinter 105:
106:
107: if RESPONSE is not None:
108: RESPONSE.redirect('manage_main')
109:
110:
111:
112: def manage_addMetadataMappingForm(self):
113: """interface for adding the OSAS_root"""
114: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMetadataMappingForm.zpt')).__of__(self)
115:
116: return pt()
117:
118: def manage_addMetadataMapping(self,idOfObject,titleOfObject,RESPONSE=None):
119: """add the OSAS_root"""
120:
121: argList={}
122: for arg in self.fieldList:
123: if not (arg in ['idOfObject','titleOfObject']):
1.4 dwinter 124: argList[arg]=(self.REQUEST.form[arg],self.REQUEST.form['label_'+arg],self.REQUEST.form['explanation_'+arg],arglist['status_'+fieldName],arglist['values_'+fieldName])
1.1 dwinter 125:
126: newObj=OSAS_MetadataMapping(idOfObject,titleOfObject,argList)
127: self._setObject(idOfObject,newObj)
128: if RESPONSE is not None:
129: RESPONSE.redirect('manage_main')
130:
131:
132:
133: class OSAS_Metadata(Folder):
134: """Foldertype enthält methoden zur Halbautomatischen Erstellung von Metadatenfiles"""
135: security=ClassSecurityInfo()
136:
1.4 dwinter 137: def __init__(self,id,shortDescription,description,fields):
1.1 dwinter 138: """initialize a new instance"""
139: self.id = id
1.4 dwinter 140: self.shortDescription =shortDescription #label fuer link auf add page
1.1 dwinter 141: self.description=description #description of the method for link page
142: self.fieldList=fields.split(",")[0:]
143:
144: meta_type='OSAS_Metadata__neu'
145:
146: manage_options = Folder.manage_options+(
147: {'label':'Main Config','action':'changeMetadataForm'},
148: {'label':'Import XML Schema','action':'importXMLSchemaForm'},
149: {'label':'Select Fields for Display','action':'indicateDisplayFieldsForm'},
150: )
151:
152: def showGenericXML(self,RESPONSE=None):
153: """show generic fields as XML"""
154: ret="""<set name="%s">"""%"generic"
155: for field in self.fieldList:
156: ret+="""<entry genericName="%s"/>"""%field
157:
158: ret+="</set>"
159:
160: if not RESPONSE:
161: return ret
162: else:
163: self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
164: return ret
165:
166: def showOverviewXML(self,RESPONSE):
167: """gives an overview over the Metadata stored in this folder"""
168: ret="""<metadata name="%s">"""%self.getId()
169: ret+=self.showGenericXML()
170: for entry in self.ZopeFind(self,obj_metatypes=['OSAS_MetadataMapping']):
171: ret+=entry[1].showSetXML()
172:
173: ret+="</metadata>"
174:
175: if not RESPONSE:
176: return ret
177: else:
178: self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
179: return ret
180:
181: def generateMappingList(self):
182: """Erzeuge Mapping"""
183: mapping={}
184: for dict in self.__dict__:
185: #print dict
186: obj=getattr(self,dict)
187: if hasattr(obj,'meta_type'):
188: if obj.meta_type=="OSAS_MetadataMapping":
189: mapping[obj.getId()]=obj.generateMappingHash()
190: return mapping
191:
192: def generateMappingForType(self,type,clean="yes"):
193: """erzeuge spezifisches Mapping"""
194: hash=self.generateMappingList()
195: if hash.has_key(type):
196: if clean=="yes":
197: temp={}
198: for x in hash[type].keys():
199: if not hash[type][x]=="":
200: temp[x]=hash[type][x]
201: return temp
202: else:
203: return hash[type]
204:
205: else:
206: return {}
207:
208: def getFieldList(self):
209: """erzeuge string aus fields"""
210: try:
211: return string.join(self.fieldList,",")
212: except:
213: return ""
214:
215: def getFields(self):
216: """ausgabe der Felder"""
217: return self.fieldList
218:
219: def getTypeTitle(self,id):
220: """Title von ID"""
221: try:
222: obj=getattr(self,id)
223: return obj.title
224: except:
225: return id
1.4 dwinter 226:
227: def getType(self,type):
228: """gib metadataobject type zurueck"""
229:
230: for obj in self.ZopeFind(self,obj_metatypes=['OSAS_MetadataMapping__neu']):
231: if obj[0]==type:
232: return obj
233: return (self.id,self)
234:
235:
1.1 dwinter 236:
237: def getStoredTypes(self):
238: """Gebe gespeicherte typen zurück"""
239:
240: types=[]
241:
242: for obj in self.ZopeFind(self,obj_metatypes=['OSAS_MetadataMapping_neu']):
243: if obj.title=="":
244: title=obj.id
245: else:
246: title=obj.title
1.4 dwinter 247: types.append((obj.id,title,obj))
1.1 dwinter 248:
249: return types
250:
251: def indicateDisplayFieldsForm(self):
252: """form zur Makierung der Felder die in der Browserumgebung angezeigt werden"""
253: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','indicateDisplayFieldsForm.zpt')).__of__(self)
254: return pt()
255:
256: def indicateDisplayFields(self,displayFields,RESPONSE=None):
257: """set Displayfields
258: @param displayFields: Liste von Felder die im Browserenvironment angezeigt werden
259: """
260: self.displayFields=OSAS_helpers.toList(displayFields)
261: if RESPONSE is not None:
262: RESPONSE.redirect('manage_main')
263:
1.3 dwinter 264: def getDisplayFieldsAsStr(self,indexMeta):
1.4 dwinter 265: ret=[]
1.6 ! dwinter 266: try:
! 267: if indexMeta and not (indexMeta==""):
1.5 dwinter 268: dom=xml.dom.pulldom.parseString(indexMeta)
1.4 dwinter 269:
1.5 dwinter 270: for (event,node) in dom:
1.4 dwinter 271:
1.5 dwinter 272: if event == xml.dom.pulldom.START_ELEMENT and node.tagName=="bib":
273: dom.expandNode(node)
1.4 dwinter 274:
1.5 dwinter 275: try:
276: type=node.getAttribute('type')
277: mapping=getattr(self,type).generateMappingHash()
278: except:
279: type='generic'
280: mapping=getattr(self,type).generateMappingHash()
1.4 dwinter 281:
1.5 dwinter 282: for field in self.displayFields:
283: try:
284: ret.append(OSAS_helpers.getText(node.getElementsByTagName(mapping[field][0])[0].childNodes))
285: except:
286: """nothing"""
1.4 dwinter 287:
1.5 dwinter 288: return "; ".join(ret)
1.6 ! dwinter 289: else:
1.5 dwinter 290: return ""
1.6 ! dwinter 291: except:
! 292: return ""
1.4 dwinter 293: def getDisplayFieldsAsStrOLD(self,indexMeta):
1.1 dwinter 294: """Gebe display fields als string zurück
295: @param path: Pfad zum Object
296: """
297: ret=[]
298: try:
1.3 dwinter 299: dom=xml.dom.minidom.parseString(indexMeta)
1.1 dwinter 300: except:
1.3 dwinter 301: zLOG.LOG("OSAS_metadata (getDisplayFieldsAsStr)",zLOG.INFO,"Cannot parse: %s"%indexMeta)
1.1 dwinter 302: try:
303: bib = dom.getElementsByTagName("meta")[0].getElementsByTagName("bib")[0]
304: except:
305: return ""
306: try:
307: type=bib.getAttribute('type')
308: mapping=getattr(self,type).generateMappingHash()
309: except:
310: type='generic'
311: mapping=getattr(self,type).generateMappingHash()
312:
313: for field in self.displayFields:
314: try:
315: ret.append(OSAS_helpers.getText(bib.getElementsByTagName(mapping[field][0])[0].childNodes))
316: except:
317: """nothing"""
318:
319: return "; ".join(ret)
320:
321: security.declarePublic('changeMetadataForm')
322: def changeMetadataForm(self):
323: """Main configuration"""
324: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeMetadata.zpt')).__of__(self)
325: return pt()
326:
327: security.declarePublic('changeMetadata')
1.4 dwinter 328: def changeMetadata(self,shortDescription,description,fields,RESPONSE=None):
1.1 dwinter 329: """Change Metadata"""
1.4 dwinter 330: self.shortDescription=shortDescription
1.1 dwinter 331: self.description=description
332: self.fieldList=fields.split(",")[0:]
333: if RESPONSE is not None:
334: RESPONSE.redirect('manage_main')
335:
336: security.declarePublic('index_html')
337:
338: def importXMLSchemaForm(self):
339: """form"""
340: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','importXMLSchemaForm.zpt')).__of__(self)
341: return pt()
342:
1.4 dwinter 343:
1.1 dwinter 344: def importXMLSchema(self,file,RESPONSE=None):
345: """import xmlschema, Metadatenschema wird eingelesen und entsprechende Metadatenmappings angelegt."""
346:
347: dom=xml.dom.minidom.parse(file)
348: sets=dom.getElementsByTagName('set')
349: #erster schritt: anlegen der fieldlist
350: for set in sets:
351: if set.getAttribute('name')=='generic':
352: list=[]
353: for entry in set.getElementsByTagName('entry'):
354: list.append(entry.getAttribute('genericName'))
355: self.fieldList=list[0:]
356:
357: #zweiter schritt: anlegen der mapping
358: for set in sets:
359: id=set.getAttribute('name').encode('utf-8')
360: list=[]
361: argList={}
362: for entry in set.getElementsByTagName('entry'):
363: genericName=entry.getAttribute('genericName')
364: tag=entry.getAttribute('tag')
365: label=entry.getAttribute('label')
366: description=OSAS_helpers.getText(entry.childNodes)
367: argList[genericName]=(tag,label,description)
368: self._setObject(id,OSAS_MetadataMapping(id,id,argList))
369: if RESPONSE:
370: RESPONSE.write("Wrote: %s"%id)
1.4 dwinter 371:
372:
373: def createMetadataFragment(self,type,path,prefix="",presets={}):
374: """fragment"""
375: self.REQUEST.SESSION['MDF_type']=type
376: self.REQUEST.SESSION['MDF_path']=path
377: self.REQUEST.SESSION['MDF_prefix']=prefix
378: self.REQUEST.SESSION['MDF_presets']=presets
379:
380: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMetadataForm_fragment.zpt')).__of__(self)
381: return pt()
382:
383: def createMetadataForm(self,type="",path=""):
384: """createMetadataForm"""
385: self.REQUEST.SESSION['MDF_type']=type
386: self.REQUEST.SESSION['MDF_path']=path
387:
388:
389: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMetadataForm_template.zpt')).__of__(self)
390: return pt()
391:
392: def writeMetadata(self,MDF_path,MDF_type,form,MDF_prefix="",MDF_xpathStart="", MDF_addPath=None,MDF_identifyFields=None,newdoc=None,actualNode=None):
393: """writeMetadata"""
394: #MDF_path="/tmp/index.meta"
395: if type(MDF_path)==ListType:
396: MDF_path=MDF_path[0]
397:
398: indexFile=os.path.join(MDF_path,'index.meta')
1.5 dwinter 399:
1.4 dwinter 400: server=xmlrpclib.Server(self.serverUrl)
401: if newdoc:
402: if not actualNode: actualNode=newdoc
403: dom=newdoc
404: else:
405: documentStr=server.getFile(indexFile)
1.5 dwinter 406:
1.4 dwinter 407: if documentStr:
1.5 dwinter 408:
1.4 dwinter 409: newdoc=xml.dom.minidom.parseString(documentStr)
410: dom=newdoc.documentElement
411: actualNode=dom
412:
413:
414: else:
1.5 dwinter 415:
1.4 dwinter 416: impl=xml.dom.minidom.getDOMImplementation()
417: newdoc=None
418:
419:
420: if self.containerTag=="":
421: containerTag="doc"
422: else:
423: containerTag=self.containerTag
424:
425: create=None
426: if MDF_xpathStart=="":
427: if not newdoc:
428: newdoc=impl.createDocument(None,containerTag,None)
429: dom=newdoc.documentElement
430: actualNode=dom
431: else:
432:
433: #try to find xpath
434: if MDF_identifyFields:
435: query=[]
436: for field in MDF_identifyFields:
437:
438: query.append("""(%s="%s")"""%(field,form[MDF_prefix+"MD_"+field]))
439: querystr=" and ".join(query)
440: xpathStr=MDF_xpathStart+"[%s]"%querystr
441:
442: else:
443: xpathStr=MDF_xpathStart
444:
1.5 dwinter 445:
1.4 dwinter 446: xpathNodes=xml.xpath.Evaluate(xpathStr,actualNode)
447:
448:
449:
450:
451: if len(xpathNodes)>0:
452: actualNode=xpathNodes[0]
453:
454: else:
455: #existiert nicht dann neue erzeugen
456:
457: if len(xml.xpath.Evaluate(MDF_xpathStart,dom))>0:
458:
459: create=True
460:
461: splitted=MDF_xpathStart.split("/")
462: base=""
463: for element in splitted:
464:
465: if not (element=="") and not (element==containerTag):
466: base="/".join([base,element])
467:
468: if not newdoc:
469: newdoc=impl.createDocument(None,element,None)
470: actualNode=newdoc.documentElement
471: dom=actualNode
472: else:
473: changed=None
474:
475: if not (MDF_addPath==base):
476:
477:
478: for childNode in actualNode.childNodes:
479: if getattr(childNode,'tagName','')==element:
480: actualNode=childNode
481: changed=1
482:
483: if (os.path.normpath("/".join(["",containerTag,base]))==MDF_xpathStart) and create:
484: actualNode=actualNode.parentNode
485: changed=None
486:
487: if not changed:
488: namenode=newdoc.createElement(element)
489:
490: actualNode.appendChild(namenode)
491: actualNode=namenode
492:
493:
494:
495:
496: for name in self.REQUEST.form.keys():
497: length=len(MDF_prefix)
498: if MDF_type and not (MDF_type == ""):
499: actualNode.setAttribute("type",MDF_type)
500: if name[0:3+length]==MDF_prefix+"MD_":
501: tagName=name[3+length:]
502:
503: #CHECK if element exists
504: for childNode in actualNode.childNodes:
505: if getattr(childNode,'tagName','')==tagName:
506: actualNode.removeChild(childNode).unlink()
507:
508: namenode=newdoc.createElement(tagName)
509: namenodetext=newdoc.createTextNode(self.REQUEST.form[name])
510: namenode.appendChild(namenodetext)
511: actualNode.appendChild(namenode)
512:
513: ret=newdoc.toxml(encoding='utf-8')
514:
515: server.writeMetaDataFile(indexFile,ret)
516:
517:
518: return newdoc,actualNode
519:
520: def writeMetadataFile(self,MDF_path,MDF_type,MDF_xpathStart="",newdoc=None,actualNode=None):
521: """writeMetaFile"""
522:
523: return self.writeMetadata(MDF_path,MDF_type,self.REQUEST.form,MDF_xpathStart=MDF_xpathStart,newdoc=newdoc,actualNode=actualNode)
524:
1.1 dwinter 525:
1.4 dwinter 526: def isEmptyValue(self,fieldName):
527: """im generischen fall stets falsch"""
528: return 1
529:
530: def getValue(self,fieldName):
531: """im generischen fall gleich fieldname"""
532: return fieldName,fieldName,"","",""
533:
534: def getList(self,list):
535: """return list"""
536:
537: if list=="":
538: return None
539: listsplit=list.split("\n")
540: return listsplit
541:
542: def showHelp(self,refType,genericTag):
543: """helptext"""
544: for reference in self.ZopeFind(self):
545: if reference[1].title==refType:
546: text=getattr(reference[1],'md_'+genericTag)[2]
547: return text
548: return "NO EXPLANATION"
549:
550: def showHelpTag(self,url,reftype,item):
551: """gen javascript for showhelp"""
552: url2=url+'/showHelp?refType=%s&genericTag=%s'%(reftype,item)
553: ret="""javascript:wd=window.open(\'%s\',\'Help\',\'width=300,height=250\');void(\'\');wd.focus();"""%url2
554: return ret
555:
556:
1.1 dwinter 557: def manage_addMetadataForm(self):
558: """interface for adding the OSAS_add_Metadata"""
559: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMetadataForm.zpt')).__of__(self)
560: return pt()
561:
1.4 dwinter 562: def manage_addMetadata(self,id,shortDescription,description,fields,RESPONSE=None):
1.1 dwinter 563: """add the OSAS_root"""
1.4 dwinter 564: newObj=OSAS_Metadata(id,shortDescription,description,fields)
1.1 dwinter 565: self.Destination()._setObject(id,newObj)
566: if RESPONSE is not None:
567: RESPONSE.redirect('manage_main')
568:
569:
570: InitializeClass(OSAS_Metadata)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>