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