Annotation of OSA_system2/OSAS_metadata.py, revision 1.5
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.5 ! dwinter 266: if indexMeta and not (indexMeta==""):
! 267: dom=xml.dom.pulldom.parseString(indexMeta)
1.4 dwinter 268:
1.5 ! dwinter 269: for (event,node) in dom:
1.4 dwinter 270:
1.5 ! dwinter 271: if event == xml.dom.pulldom.START_ELEMENT and node.tagName=="bib":
! 272: dom.expandNode(node)
1.4 dwinter 273:
1.5 ! dwinter 274: try:
! 275: type=node.getAttribute('type')
! 276: mapping=getattr(self,type).generateMappingHash()
! 277: except:
! 278: type='generic'
! 279: mapping=getattr(self,type).generateMappingHash()
1.4 dwinter 280:
1.5 ! dwinter 281: for field in self.displayFields:
! 282: try:
! 283: ret.append(OSAS_helpers.getText(node.getElementsByTagName(mapping[field][0])[0].childNodes))
! 284: except:
! 285: """nothing"""
1.4 dwinter 286:
1.5 ! dwinter 287: return "; ".join(ret)
! 288: else:
! 289: return ""
1.4 dwinter 290:
291: def getDisplayFieldsAsStrOLD(self,indexMeta):
1.1 dwinter 292: """Gebe display fields als string zurück
293: @param path: Pfad zum Object
294: """
295: ret=[]
296: try:
1.3 dwinter 297: dom=xml.dom.minidom.parseString(indexMeta)
1.1 dwinter 298: except:
1.3 dwinter 299: zLOG.LOG("OSAS_metadata (getDisplayFieldsAsStr)",zLOG.INFO,"Cannot parse: %s"%indexMeta)
1.1 dwinter 300: try:
301: bib = dom.getElementsByTagName("meta")[0].getElementsByTagName("bib")[0]
302: except:
303: return ""
304: try:
305: type=bib.getAttribute('type')
306: mapping=getattr(self,type).generateMappingHash()
307: except:
308: type='generic'
309: mapping=getattr(self,type).generateMappingHash()
310:
311: for field in self.displayFields:
312: try:
313: ret.append(OSAS_helpers.getText(bib.getElementsByTagName(mapping[field][0])[0].childNodes))
314: except:
315: """nothing"""
316:
317: return "; ".join(ret)
318:
319: security.declarePublic('changeMetadataForm')
320: def changeMetadataForm(self):
321: """Main configuration"""
322: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeMetadata.zpt')).__of__(self)
323: return pt()
324:
325: security.declarePublic('changeMetadata')
1.4 dwinter 326: def changeMetadata(self,shortDescription,description,fields,RESPONSE=None):
1.1 dwinter 327: """Change Metadata"""
1.4 dwinter 328: self.shortDescription=shortDescription
1.1 dwinter 329: self.description=description
330: self.fieldList=fields.split(",")[0:]
331: if RESPONSE is not None:
332: RESPONSE.redirect('manage_main')
333:
334: security.declarePublic('index_html')
335:
336: def importXMLSchemaForm(self):
337: """form"""
338: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','importXMLSchemaForm.zpt')).__of__(self)
339: return pt()
340:
1.4 dwinter 341:
1.1 dwinter 342: def importXMLSchema(self,file,RESPONSE=None):
343: """import xmlschema, Metadatenschema wird eingelesen und entsprechende Metadatenmappings angelegt."""
344:
345: dom=xml.dom.minidom.parse(file)
346: sets=dom.getElementsByTagName('set')
347: #erster schritt: anlegen der fieldlist
348: for set in sets:
349: if set.getAttribute('name')=='generic':
350: list=[]
351: for entry in set.getElementsByTagName('entry'):
352: list.append(entry.getAttribute('genericName'))
353: self.fieldList=list[0:]
354:
355: #zweiter schritt: anlegen der mapping
356: for set in sets:
357: id=set.getAttribute('name').encode('utf-8')
358: list=[]
359: argList={}
360: for entry in set.getElementsByTagName('entry'):
361: genericName=entry.getAttribute('genericName')
362: tag=entry.getAttribute('tag')
363: label=entry.getAttribute('label')
364: description=OSAS_helpers.getText(entry.childNodes)
365: argList[genericName]=(tag,label,description)
366: self._setObject(id,OSAS_MetadataMapping(id,id,argList))
367: if RESPONSE:
368: RESPONSE.write("Wrote: %s"%id)
1.4 dwinter 369:
370:
371: def createMetadataFragment(self,type,path,prefix="",presets={}):
372: """fragment"""
373: self.REQUEST.SESSION['MDF_type']=type
374: self.REQUEST.SESSION['MDF_path']=path
375: self.REQUEST.SESSION['MDF_prefix']=prefix
376: self.REQUEST.SESSION['MDF_presets']=presets
377:
378: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMetadataForm_fragment.zpt')).__of__(self)
379: return pt()
380:
381: def createMetadataForm(self,type="",path=""):
382: """createMetadataForm"""
383: self.REQUEST.SESSION['MDF_type']=type
384: self.REQUEST.SESSION['MDF_path']=path
385:
386:
387: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMetadataForm_template.zpt')).__of__(self)
388: return pt()
389:
390: def writeMetadata(self,MDF_path,MDF_type,form,MDF_prefix="",MDF_xpathStart="", MDF_addPath=None,MDF_identifyFields=None,newdoc=None,actualNode=None):
391: """writeMetadata"""
392: #MDF_path="/tmp/index.meta"
393: if type(MDF_path)==ListType:
394: MDF_path=MDF_path[0]
395:
396: indexFile=os.path.join(MDF_path,'index.meta')
1.5 ! dwinter 397:
1.4 dwinter 398: server=xmlrpclib.Server(self.serverUrl)
399: if newdoc:
400: if not actualNode: actualNode=newdoc
401: dom=newdoc
402: else:
403: documentStr=server.getFile(indexFile)
1.5 ! dwinter 404:
1.4 dwinter 405: if documentStr:
1.5 ! dwinter 406:
1.4 dwinter 407: newdoc=xml.dom.minidom.parseString(documentStr)
408: dom=newdoc.documentElement
409: actualNode=dom
410:
411:
412: else:
1.5 ! dwinter 413:
1.4 dwinter 414: impl=xml.dom.minidom.getDOMImplementation()
415: newdoc=None
416:
417:
418: if self.containerTag=="":
419: containerTag="doc"
420: else:
421: containerTag=self.containerTag
422:
423: create=None
424: if MDF_xpathStart=="":
425: if not newdoc:
426: newdoc=impl.createDocument(None,containerTag,None)
427: dom=newdoc.documentElement
428: actualNode=dom
429: else:
430:
431: #try to find xpath
432: if MDF_identifyFields:
433: query=[]
434: for field in MDF_identifyFields:
435:
436: query.append("""(%s="%s")"""%(field,form[MDF_prefix+"MD_"+field]))
437: querystr=" and ".join(query)
438: xpathStr=MDF_xpathStart+"[%s]"%querystr
439:
440: else:
441: xpathStr=MDF_xpathStart
442:
1.5 ! dwinter 443:
1.4 dwinter 444: xpathNodes=xml.xpath.Evaluate(xpathStr,actualNode)
445:
446:
447:
448:
449: if len(xpathNodes)>0:
450: actualNode=xpathNodes[0]
451:
452: else:
453: #existiert nicht dann neue erzeugen
454:
455: if len(xml.xpath.Evaluate(MDF_xpathStart,dom))>0:
456:
457: create=True
458:
459: splitted=MDF_xpathStart.split("/")
460: base=""
461: for element in splitted:
462:
463: if not (element=="") and not (element==containerTag):
464: base="/".join([base,element])
465:
466: if not newdoc:
467: newdoc=impl.createDocument(None,element,None)
468: actualNode=newdoc.documentElement
469: dom=actualNode
470: else:
471: changed=None
472:
473: if not (MDF_addPath==base):
474:
475:
476: for childNode in actualNode.childNodes:
477: if getattr(childNode,'tagName','')==element:
478: actualNode=childNode
479: changed=1
480:
481: if (os.path.normpath("/".join(["",containerTag,base]))==MDF_xpathStart) and create:
482: actualNode=actualNode.parentNode
483: changed=None
484:
485: if not changed:
486: namenode=newdoc.createElement(element)
487:
488: actualNode.appendChild(namenode)
489: actualNode=namenode
490:
491:
492:
493:
494: for name in self.REQUEST.form.keys():
495: length=len(MDF_prefix)
496: if MDF_type and not (MDF_type == ""):
497: actualNode.setAttribute("type",MDF_type)
498: if name[0:3+length]==MDF_prefix+"MD_":
499: tagName=name[3+length:]
500:
501: #CHECK if element exists
502: for childNode in actualNode.childNodes:
503: if getattr(childNode,'tagName','')==tagName:
504: actualNode.removeChild(childNode).unlink()
505:
506: namenode=newdoc.createElement(tagName)
507: namenodetext=newdoc.createTextNode(self.REQUEST.form[name])
508: namenode.appendChild(namenodetext)
509: actualNode.appendChild(namenode)
510:
511: ret=newdoc.toxml(encoding='utf-8')
512:
513: server.writeMetaDataFile(indexFile,ret)
514:
515:
516: return newdoc,actualNode
517:
518: def writeMetadataFile(self,MDF_path,MDF_type,MDF_xpathStart="",newdoc=None,actualNode=None):
519: """writeMetaFile"""
520:
521: return self.writeMetadata(MDF_path,MDF_type,self.REQUEST.form,MDF_xpathStart=MDF_xpathStart,newdoc=newdoc,actualNode=actualNode)
522:
1.1 dwinter 523:
1.4 dwinter 524: def isEmptyValue(self,fieldName):
525: """im generischen fall stets falsch"""
526: return 1
527:
528: def getValue(self,fieldName):
529: """im generischen fall gleich fieldname"""
530: return fieldName,fieldName,"","",""
531:
532: def getList(self,list):
533: """return list"""
534:
535: if list=="":
536: return None
537: listsplit=list.split("\n")
538: return listsplit
539:
540: def showHelp(self,refType,genericTag):
541: """helptext"""
542: for reference in self.ZopeFind(self):
543: if reference[1].title==refType:
544: text=getattr(reference[1],'md_'+genericTag)[2]
545: return text
546: return "NO EXPLANATION"
547:
548: def showHelpTag(self,url,reftype,item):
549: """gen javascript for showhelp"""
550: url2=url+'/showHelp?refType=%s&genericTag=%s'%(reftype,item)
551: ret="""javascript:wd=window.open(\'%s\',\'Help\',\'width=300,height=250\');void(\'\');wd.focus();"""%url2
552: return ret
553:
554:
1.1 dwinter 555: def manage_addMetadataForm(self):
556: """interface for adding the OSAS_add_Metadata"""
557: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMetadataForm.zpt')).__of__(self)
558: return pt()
559:
1.4 dwinter 560: def manage_addMetadata(self,id,shortDescription,description,fields,RESPONSE=None):
1.1 dwinter 561: """add the OSAS_root"""
1.4 dwinter 562: newObj=OSAS_Metadata(id,shortDescription,description,fields)
1.1 dwinter 563: self.Destination()._setObject(id,newObj)
564: if RESPONSE is not None:
565: RESPONSE.redirect('manage_main')
566:
567:
568: InitializeClass(OSAS_Metadata)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>