1: import re
2: import string
3: import socket
4: import urllib
5: import string
6: import xml.dom.minidom
7: import types
8: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
9: from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
10: from OFS.SimpleItem import SimpleItem
11: from Globals import package_home
12: import Globals
13: from AccessControl import ClassSecurityInfo
14: from Acquisition import aq_parent,aq_chain,aq_base
15: import os.path
16: from OFS.Folder import Folder
17: import ECHO_collection
18: import base64
19: import bz2
20: import xmlrpclib
21: import sys
22: import logging
23: #import amara
24:
25: #erstzt logging
26: def logger(txt,method,txt2):
27: """logging"""
28: logging.info(txt+ txt2)
29:
30: displayTypes = ['ZSQLExtendFolder','ZSQLBibliography','ECHO_group','ECHO_collection','ECHO_resource','ECHO_link','ECHO_sqlElement','ECHO_pageTemplate','ECHO_externalLink','ImageCollectionIFrame','VLP_resource','VLP_essay','ECHO_ZCatalogElement','ImageCollection','versionedFileFolder','extVersionedFileFolder','ECHO_movie']
31:
32: def normalizeCt(str):
33: """normalizes content_type"""
34: #str= str.replace(" ","_")
35: return str.replace("-"," ").lower()
36:
37: #decode and compress for xmlrpc communication with OSAS_server
38:
39: def encodeRPC(string):
40: return base64.encodestring(bz2.compress(string))
41: def decodeRPC(string):
42: return bz2.decompress(base64.decodestring(string))
43:
44: def unicodify(s):
45: """decode str (utf-8 or latin-1 representation) into unicode object"""
46: if not s:
47: return u""
48: if isinstance(s, str):
49: try:
50: return s.decode('utf-8')
51: except:
52: return s.decode('latin-1')
53: else:
54: return s
55:
56: def utf8ify(s):
57: """encode unicode object or string into byte string in utf-8 representation.
58: assumes string objects to be utf-8"""
59: if not s:
60: return ""
61: if isinstance(s, str):
62: return s
63: else:
64: return s.encode('utf-8')
65:
66:
67: def content_html(self,type):
68: """template fuer content"""
69: #templates = self.ZopeFind(self.aq_parent,obj_ids=[type+"_template"])
70: #
71: #if templates:
72: # return templates[0][1]()
73:
74: if hasattr(self,type+"_template"):
75:
76: obj=getattr(self,type+"_template")
77: return obj()
78: else:
79: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ECHO_%s_template_standard.zpt'%type)).__of__(self)
80: pt.content_type="text/html"
81: return pt()
82:
83:
84:
85: class ECHO_basis:
86: """basis eigenschaften fuer echo objekte"""
87: security=ClassSecurityInfo()
88: security.declarePublic('getImageTag')
89:
90: management_page_charset="utf-8"
91: isVisible = True
92:
93: # Managment for the PID
94: def setPID(self,pid):
95: """set the pid"""
96: logging.debug(self.getId()+" PID set to "+pid)
97: self.pid=pid
98: return True
99:
100: def getPID(self):
101: """get the pid"""
102:
103: pid =getattr(self,'pid',None)
104:
105: if pid == self.getParentPID():
106: return None
107: else:
108: return pid
109:
110:
111: def getParentPID(self):
112: """get the PID of the parent"""
113: parent = self.aq_parent
114:
115: pidF = getattr(parent,'getPID',None)
116:
117: if pidF is None:
118: return None
119:
120: else:
121: return pidF()
122:
123: def unicodify(self, s):
124: """return unicode object for string (utf-8 or latin1) or unicode object s"""
125: return unicodify(s)
126:
127: # compatibility of old decode method
128: decode = unicodify
129:
130:
131: def utf8ify(self, s):
132: """return utf-8 encoded string object for string or unicode object s"""
133: return utf8ify(s)
134:
135: def getBrowserType(self):
136: """returns browserType object"""
137: return browserType(self)
138:
139: def manage_addECHO_locale(self,lang,title,label,text=None,content_type=None,RESPONSE=None):
140: return ECHO_collection.manage_addECHO_locale(self,lang,title,label)
141:
142: def getImageTag(self):
143: """sollte uerberschrieben werden, falls von der Klasse eine imagetag zurueckkommt"""
144:
145: return ""
146:
147: def showRDF(self):
148: """showrdf"""
149: self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
150: ret="""<?xml version="1.0" encoding="utf-8"?>\n<rdf:rdf xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ECHONAVIGATION="http://www.echo.eu/rdf#"
151: xmlns:MPIWG="http://www.mpiwg-berlin.mpg.de/ns/mpiwg">\n"""
152:
153: ret+=self.getRDF(urn="echo:collectionroot")+"\n"
154:
155:
156: ret+="""</rdf:rdf>"""
157: return ret
158:
159:
160: def RDF(self):
161: """showrdf"""
162: self.REQUEST.RESPONSE.setHeader('Content-Type','text/xml')
163: ret="""<?xml version="1.0" encoding="utf-8"?>\n<rdf:rdf xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ECHONAVIGATION="http://www.echo.eu/rdf#">\n"""
164:
165: ret+=self.getRDF(urn=self.absolute_url())+"\n"
166:
167:
168: ret+="""</rdf:rdf>"""
169: return ret
170:
171:
172: def createSubElementRDF(self,urn=None):
173: """rdf list"""
174: if not urn:
175: urn=self.absolute_url()
176: ret=""
177:
178: rettemp="""<rdf:Seq rdf:about="%s">\n"""%urn
179: flag=0
180:
181: li="""<rdf:li rdf:resource="%s" />\n"""
182: if not ('<error>' in self.getFullTextXML(noredirect='Yes')):
183: nurn=self.absolute_url()+'/getFullTextXML'
184: rettemp+=li%nurn
185: flag=1
186: if not ('<error>' in self.getImageView(noredirect='Yes')):
187: nurn=self.absolute_url()+'/getImageView'
188: rettemp+=li%nurn
189: flag=1
190:
191:
192: if not ('<error>' in self.showMetaDataXML()):
193: nurn=self.absolute_url()+'/showMetaDataXML'
194: rettemp+=li%nurn
195: flag=1
196:
197: rettemp+="</rdf:Seq>"
198:
199: if flag==1:
200: ret+=rettemp
201:
202: if not ('<error>' in self.getFullTextXML(noredirect='Yes')):
203: nurn=self.absolute_url()+'/getFullTextXML'
204: ret+=getRDFDescription(self,self.absolute_url()+'/getFullTextXML',urn=nurn,nameDef="Fulltext",typeName="ECHO_fulltext")
205:
206: if not ('<error>' in self.getImageView(noredirect='Yes')):
207: nurn=self.absolute_url()+'/getImageView'
208: ret+=getRDFDescription(self,self.absolute_url()+'/getImageView',urn=nurn,nameDef="Image View",typeName="ECHO_imageview")
209:
210: if not ('<error>' in self.showMetaDataXML()):
211: nurn=self.absolute_url()+'/showMetaDataXML'
212: ret+=getRDFDescription(self,self.absolute_url()+'/showMetaDataXML',urn=nurn,nameDef="Metadata",typeName="ECHO_metaData")
213:
214:
215: return ret
216: def content_html_XMLRpc(self):
217: """xml_rpc_version"""
218: return encodeRPC(self.content_html())
219:
220: def content_html(self,type="collection"):
221: """template fuer content bei einbau und ECHO_Umgebung"""
222:
223: return content_html(self,type)
224:
225: def getIsVisible(self):
226: """return if object and all parents are visible"""
227:
228: # if object is not visible return False
229: if hasattr(self,'isVisible'):
230: if not self.isVisible : return False
231:
232: # else if parent of object is not ECHO_root, ECHO_basis or None
233: if not self.aq_parent.meta_type in ['ECHO_root','ECHO_basis',None] :
234: return self.aq_parent.getIsVisible()
235:
236: # else return True
237: return True
238:
239: def setIsVisible(self, isVisible):
240: """ set object attribute isVisible"""
241: self.isVisible = isVisible
242:
243: def getAttributeIsVisible(self):
244: """ return object attribute isVisible"""
245: if hasattr(self,'isVisible'):
246: return self.isVisible
247: return True
248:
249: def getDescription(self):
250: """get content of description field"""
251:
252:
253: return self.unicodify(getattr(self,'description',''));
254:
255: def getTitle(self):
256: """title"""
257: if hasattr(self,'getLanguage'):
258: lang=self.getLanguage()
259: else:
260: lang=None
261:
262: locale=None
263: if lang and not (lang =="de"):
264: locale=self.ZopeFind(self,obj_ids=["locale_"+lang])
265:
266: if locale:
267: return self.decode(locale[0][1].title)
268: else:
269: try:
270: return self.decode(self.title)
271: except:
272: return self.title
273:
274: def getLabel(self):
275: """title"""
276: if hasattr(self,'getLanguage'):
277: lang=self.getLanguage()
278: else:
279: lang=None
280:
281: locale=None
282:
283: if lang and not (lang=="de"):
284: locale=self.ZopeFind(self,obj_ids=["locale_"+lang])
285:
286: if locale:
287: return self.decode(locale[0][1].label)
288:
289:
290: if not hasattr(self,'label'):
291: self.label=""
292:
293: if self.label=="":
294: ret=self.getTitle()
295: if ret=="":
296: ret=self.getId()
297: return ret
298:
299: return self.decode(self.label)
300:
301: def changeECHOEntriesForm(self):
302: """change Entries for the ECHO Navigation environment"""
303: pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeECHOEntriesForm')).__of__(self)
304: return pt()
305:
306: def changeECHOEntries(self,label,weight,description,queryString,RESPONSE=None):
307: """change Entries for the ECHO Navigation environment
308: @param label: label fuer die Navigation"""
309: self.label=label
310: self.weight=weight
311: self.description=description
312: self.queryString=queryString
313:
314: if RESPONSE:
315: RESPONSE.redirect("manage_main")
316:
317: manage_options=({'label':'change ECHO Navigation Entries','action':'changeECHOEntriesForm'},)
318:
319:
320: def hasOverview(self):
321: """returns if there is an overview graphics"""
322: return hasattr(self, 'overview')
323:
324: def hasParentOverview(self):
325: """returns if the parent has an overview graphics"""
326: return hasattr(self.aq_parent, 'overview')
327:
328: def getOverview(self):
329: """map overview graphics"""
330: #return self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['overview'])[0][1]
331: return getattr(self, 'overview', None)
332:
333: def getMapAreas(self):
334: """returns the list of MapAreas"""
335: forcetypes = self.REQUEST.get('map_force_types', None)
336: if forcetypes:
337: typelist = forcetypes.split(',')
338: else:
339: typelist = None
340: areas = []
341: # get all contained MapAreas
342: for res in self.ZopeFind(self, obj_metatypes=('MapArea')):
343: area = res[1]
344: # check the allowed types
345: if typelist is not None and area.getType() not in typelist:
346: continue
347: areas.append(area)
348: return areas
349:
350: def addMapArea(self, newarea):
351: """add a map area to this object"""
352: if (newarea.id is None):
353: # create new id
354: ids = [a.id for a in self.getMapAreas()]
355: i = len(ids)
356: while ("a%02d"%i in ids):
357: # if it exists, try the next one
358: i += 1
359: newarea.id = "a%02d"%i
360: self._setObject(newarea.id, newarea)
361:
362: def getMapText(self):
363: """returns the MapText"""
364: # get (the first) contained MapText
365: #lang="en"
366: lang=self.getLanguage()
367: res=None
368: if lang and not (lang=="de"):
369: resTmp = self.ZopeFind(self, obj_metatypes=('ECHO_mapText'))
370: res = self.ZopeFind(resTmp[0][1])
371:
372: if not res:
373: res = self.ZopeFind(self, obj_metatypes=('ECHO_mapText'))
374: if len(res) > 0:
375: text = res[0][1]
376: return text
377: return None
378:
379: def ECHO_graphicEntry(self):
380: """change map coordinates"""
381: if self.hasParentOverview():
382: pt=zptFile(self, 'zpt/ECHO_draw.zpt')
383: return pt()
384: else:
385: return "NO OVERVIEW GRAPHICS"
386:
387: def ECHO_addCoords(self,RESPONSE=None):
388: """change or add MapArea"""
389: #return self.REQUEST
390: # change existing areas
391: for area in self.getMapAreas():
392: id = area.getId()
393: if self.REQUEST.has_key('del.'+id):
394: # delete this area
395: self._delObject(id)
396: # return to same menu
397: if RESPONSE is not None:
398: RESPONSE.redirect('ECHO_graphicEntry')
399: return
400: # modify this area
401: coordstring = self.REQUEST.get('coords.'+id, '')
402: coords = string.split(coordstring, ',')
403: angle = self.REQUEST.get('angle.'+id, '0')
404: type = self.REQUEST.get('type.'+id, 'area')
405: permanent = self.REQUEST.get('permanent.'+id, '')
406: if len(coords) == 4:
407: area.setCoordString(coordstring)
408: area.setAngle(angle)
409: area.setType(type)
410: area.setPermanent(permanent)
411: # add the "new" area
412: if self.REQUEST.has_key('add'):
413: coordstring = self.REQUEST.get('coords.new', '')
414: coords = string.split(coordstring, ',')
415: angle = self.REQUEST.get('angle.new', '0')
416: type = self.REQUEST.get('type.new', 'area')
417: permanent = self.REQUEST.get('permanent.new', '')
418: if len(coords) == 4:
419: coords.append(angle)
420: area = MapArea(None, coords, type=type, permanent=permanent)
421: self.addMapArea(area)
422: # return to edit area menu
423: if RESPONSE is not None:
424: RESPONSE.redirect('ECHO_graphicEntry')
425:
426: def createJSAreas(self, areas):
427: """create area calls for JavaScript"""
428: forceperm = self.REQUEST.get('map_force_permanent', None)
429: js="\n"
430: for ob in areas:
431: # check for force-permanent
432: if forceperm is not None:
433: perm = forceperm
434: else:
435: perm = ob.isPermanent()
436: js+="""addArea('%s', 'overview', %s, '%s', '%s');\n"""%(ob.getFullId(),ob.getCoordString(),ob.getType(),perm)
437: return js
438:
439: def createMapHead(self,mapColTypes=None):
440: """create javascript include and script tags for head"""
441: pt=zptFile(self, 'zpt/ECHO_content_map_frag_js')
442: return pt(mapColTypes=mapColTypes)
443:
444: def createMapImg(self):
445: """generate img-tag for map"""
446: bt = browserType(self)
447: tag = ""
448: src = self.getOverview().absolute_url()
449: if bt['isN4']:
450: # N4 needs ilayer to create an id
451: tag += '<ilayer id="overview" visibility="show"><img src="%s"></ilayer>'%src
452: else:
453: # img with id
454: tag += '<img id="overview" src="%s" />'%src
455: return tag
456:
457: def createParentMapImg(self):
458: """generate img-tag for map of parent"""
459: return self.aq_parent.createMapImg()
460:
461: def createMapLink(self, ob, text=None, target="_blank"):
462: """generate map link"""
463: bt = browserType(self)
464: id = ob.getFullId()
465: url = ob.getTargetUrl()
466: if url == "":
467: # ECHOResource with empty link -> no link
468: href = 'href="#" onclick="return false;"'
469: else:
470: href = 'href="%s"'%ob.getLinkId()
471:
472: if target is None:
473: targetattr = ""
474: else:
475: targetattr = 'target="%s"'%target
476:
477: if text is None:
478: text = ob.getLabel()
479:
480: if text is None:
481: text = "link"
482:
483: tiptext = ob.getTip()
484: tag = ""
485: if bt['isN4']:
486: # N4 needs layer for highlighting
487: tag += '<ilayer id="a.%s"><a class="maplink" onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)" %s %s'%(id,id,id,href,targetattr)
488: tag += ">" + text + "</a></ilayer>"
489: else:
490: # a-element
491: tag = '<a id="a.%s" class="maplink" onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)" %s %s'%(id,id,id,href,targetattr)
492: if tiptext:
493: tag += ' title="%s"'%tiptext
494: tag += ">" + text + "</a>"
495: return tag
496:
497: def createMapAux(self, ob, arrowsrc="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler/?dw=15&fn=icons/pfeil", circlesrc="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler/?dw=15&fn=icons/kreis", target="_blank",backLink=None,alternativArrowsrc="http://nausikaa2.rz-berlin.mpg.de/digitallibrary/servlet/Scaler/?dw=15&fn=icons/pfeil_blau"):
498: """generate map link image, text and other stuff"""
499: bt = browserType(self)
500: id = ob.getFullId()
501: link = ob.getLinkId()
502: url = ob.getTargetUrl()
503: if url == "":
504: # ECHOResource with empty link -> no link
505: href = 'href="#" onclick="return false;"'
506: else:
507: href = 'href="%s"'%ob.getLinkId()
508:
509: if target is None:
510: targetattr = ""
511: else:
512: targetattr = 'target="%s"'%target
513: tiptext = ob.getTip()
514: tag = ""
515:
516: if bt['isN4']:
517: #
518: # N4 needs layer and img elements
519: #
520: tag += '<layer id="i.%s" onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)">'%(id,id,id)
521: if ob.isTypeArrow():
522: # N4 - Arrow
523: rot = ob.angle
524:
525: if hasattr(getattr(self,link),'link'):
526: cLink=getattr(self,link).link
527: # if existing delete virtuell path
528: cLink=cLink.replace('/'.join(self.REQUEST['VirtualRootPhysicalPath']),'')
529:
530: if backLink and hasattr(getattr(self,link),'link') and backLink==self.REQUEST['SERVER_URL']+cLink.lstrip():
531: marksrc=alternativArrowsrc
532: else:
533: marksrc = arrowsrc
534:
535:
536: if float(rot) < 0:
537: marksrc = circlesrc
538: tag += '<a %s><img border="0" src="%s&rot=%s" /></a>'%(href,marksrc,rot)
539: elif ob.isTypeText():
540: # N4 - Text
541: tag += '<div id="t.%s" class="maptext"'%(id)
542: tag += 'style="visibility:hidden">'
543: tag += ob.getText()
544: tag += '</div>'
545: else:
546: # N4 - Area
547: tag += '<a %s><img border="0" width="1000" height="1000" src="trans_img"'%(href)
548: if tiptext:
549: tag += ' alt="%s"'%tiptext
550: tag += ' /></a>'
551: tag += '</layer>'
552: else:
553: #
554: # (more or less) DOM capable browser
555: #
556: tag = '<a id="b.%s" class="mapmarklink" onmouseover="highlightPair(\'%s\', true)" onmouseout="highlightPair(\'%s\', false)" %s %s>'%(id,id,id,href,targetattr)
557: if ob.isTypeArrow():
558: # DOM - Arrow
559: rot = ob.angle
560:
561: if hasattr(getattr(self,link),'link'):
562: cLink=getattr(self,link).link
563: # if existing delete virtuell path
564: if hasattr(self.REQUEST,'VirtualRootPhysicalPath'):
565: cLink=cLink.replace('/'.join(self.REQUEST['VirtualRootPhysicalPath']),'')
566:
567: if backLink and hasattr(getattr(self,link),'link') and backLink==self.REQUEST['SERVER_URL']+cLink.lstrip():
568: marksrc=alternativArrowsrc
569: else:
570: marksrc = arrowsrc
571:
572: try:
573: rot=float(rot)
574: except:
575: rot=0
576:
577: if float(rot) < 0:
578: marksrc = circlesrc
579: if bt['isIEWin'] and bt['versIE'] > 5:
580: # IE/Win 5.5 has "feature" for PNG transparency
581: tag += '<span id="i.%s" style="position:absolute; top:-100px; left:-100px; border-style:none; border-width=1px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'%s&rot=%s\');"><img style="visibility:hidden" src="%s&rot=%s" /></span>'%(id,marksrc,rot,marksrc,rot)
582: else:
583: # arrow image
584: tag += '<img id="i.%s" src="%s&rot=%s" border="1" style="position:absolute; top:-100px; left:-100px; border-style:none;" />'%(id,marksrc,rot)
585: elif ob.isTypeText():
586: # DOM - Text
587: tag += '<div id="i.%s" style="position:absolute; top:-100px; left:-100px;"'%(id)
588: tag += '><div id="t.%s" class="maptext"'%(id)
589: tag += 'style="visibility:hidden">'
590: tag += ob.getText()
591: tag += '</div></div>'
592: else:
593: # DOM - Area
594: if bt['isIE']:
595: # IE needs transparent img for area
596: tag += '<img id="i.%s" border="0" style="position:absolute; top:-100px; left:-100px;" src="trans_img"'%(id)
597: if tiptext:
598: tag += ' title="%s"'%tiptext
599: tag += " />"
600: else:
601: # empty div for area
602: tag += '<div id="i.%s" style="position:absolute; top:-100px; left:-100px;"'%(id)
603: if tiptext:
604: tag += ' title="%s"'%tiptext
605: tag += '> </div>'
606: tag += '</a>'
607: return tag
608:
609:
610: #ende der echo erweiterungen
611:
612:
613: def toList(field):
614: """Einzelfeld in Liste umwandeln"""
615: if type(field)==types.StringType:
616: return [field]
617: else:
618: return field
619:
620: def getText(nodelist):
621: rc = ""
622: for node in nodelist:
623: if node.nodeType == node.TEXT_NODE:
624: rc = rc + node.data
625: return rc
626:
627: def getTextFromNode(nodename):
628: nodelist=nodename.childNodes
629: rc = ""
630: for node in nodelist:
631: if node.nodeType == node.TEXT_NODE:
632: rc = rc + node.data
633: return rc
634:
635:
636: def readFieldFromXML(meta_url,parent,field):
637: """lesespezifisches metadatum"""
638:
639: try:
640: dom=xml.dom.minidom.parse(meta_url)
641:
642: except:
643: try:
644: fh=urllib.urlopen(meta_url)
645: dom=xml.dom.minidom.parse(fh)
646: except:
647: return None
648: if not dom: return None
649:
650: parent=dom.getElementsByTagName(parent)
651: if not parent: return None
652:
653: field=parent[0].getElementsByTagName(field)
654:
655: if not field: return None
656:
657: return getText(field[0].childNodes)
658:
659: def readFieldFromXML_xpath(meta_url,xpath):
660: """xpath auf meta_url"""
661: #logging.debug("try to parse:"+meta_url)
662: #logging.debug("Xtry to parse xpath:"+xpath)
663: doc = amara.parse(meta_url)
664: #logging.debug("have:"+doc.xml())
665: node= doc.xml_xpath(xpath)
666: if node is None:
667: return None
668:
669: return unicode(node[0])
670:
671: def urlopen(url):
672: """urlopen mit timeout"""
673: socket.setdefaulttimeout(10)
674: ret=urllib.urlopen(url)
675: socket.setdefaulttimeout(5)
676: return ret
677: # urlopener = urllib.URLopener()
678: #
679: # try:
680: # con = urlopener.open(url)
681: # return con
682: # except timeoutsocket.Timeout:
683: # return None
684:
685:
686:
687:
688:
689: def checkOnlyOneInGroup(object):
690: """check if object is a group and if it containt only one element it return this element"""
691: displayedObjects=object.ZopeFind(object,obj_metatypes=displayTypes)
692: if len(displayedObjects)==1: # nur ein Object dann redirect auf dieses Object
693:
694: return displayedObjects[0][1]
695: else: return object
696:
697:
698:
699: def getCrumb(self):
700: """returns breadcrumb for this object"""
701: # ignore this object if title is empty
702: if not self.title:
703: return None
704:
705: crumb = {'obj': self,
706: 'url': self.absolute_url(),
707: 'label': self.getLabel()}
708: return crumb
709:
710: # roots of the ECHO hierarchy
711: rootMetaTypes = ['ECHO_root', 'ECHO_main', 'ECHO_nav']
712:
713: def getHierCrumbs(self):
714: """returns a list of hierarchical breadcrumbs from self to the ECHO_root"""
715: crumbs = []
716: # walk the acquisition chain
717: for obj in aq_chain(self):
718: #logging.debug("getHiercrumbs: obj=%s"%(obj))
719: # test if the object really has a getCrumb method
720: if hasattr(aq_base(obj), 'getCrumb'):
721: crumb = obj.getCrumb()
722: #logging.debug("getHiercrumbs: got %s from %s"%(crumb,obj))
723: if crumb is not None:
724: crumbs.insert(0, crumb)
725:
726: if obj.meta_type in rootMetaTypes:
727: # stop when we reach the ECHO root
728: return crumbs
729:
730: return crumbs
731:
732:
733: def getSubCols(self, sortfield=None,
734: subColTypes=displayTypes,
735: sortFieldMD=None,
736: searchMD=None,
737: searchMD_modus='search',
738: searchSimple=None,
739: generic="yes",search_sub=0,
740: isVisible=True):
741:
742: def sort(x,y):
743: try:
744: if type(x[0])==type(y[0]):
745: return cmp(x[0],y[0])
746: else:
747: if type(x[0])==types.StringType:
748: tmpX=unicodify(x[0])
749: tmpY=y[0]
750: else:
751: tmpY=unicodify(y[0])
752: tmpX=x[0]
753: return cmp(tmpX,tmpY)
754:
755: except:
756: logging.error("Error at ECHO_helpers.sort:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
757: logging.error(" : %s %s"%sys.exc_info()[0:2])
758: logging.error("Error at ECHO_helpers.sort:"+repr(x)+"--"+repr(type(x[0])))
759: logging.error("Error at ECHO_helpers.sort:"+repr(y)+"--"+repr(type(y[0])))
760: logging.error("Error at ECHO_helpers.sort:BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")
761: return 0
762: def sortfnc(sortfield,x,y):
763: try:
764: xa=x[1].getMDValue(sortfield,generic=generic)
765: except:
766: xa=""
767: try:
768: ya=y[1].getMDValue(sortfield,generic=generic)
769: except:
770: ya=""
771: return cmp(xa,ya)
772:
773: sortWithMD = lambda sortfield : (lambda x,y : sortfnc(sortfield,x,y))
774: ids=[]
775: displayedObjects=self.ZopeFind(self,obj_metatypes=subColTypes,search_sub=search_sub)
776:
777: if searchSimple and (not (searchSimple==""))and hasattr(self,'resourceCatalog'):
778: searchString=" AND ".join(searchSimple.split())
779: ids=[x.getObject() for x in self.resourceCatalog({'getMDValueSimpleSearchField':searchString,'getIsVisible':True})]
780: else:
781: for entry in displayedObjects:
782: object=entry[1]
783: if searchMD:
784: if hasattr(object,'getMDValue'):
785: flag=0
786: for field in searchMD.keys():
787: #if object.getMDValue(field,generic=generic)==searchMD[field]:
788: #if re.match(searchMD[field],object.getMDValue(field,generic=generic)):
789: if searchMD_modus=='match':
790: searchResult=re.match(searchMD[field],object.getMDValue(field,generic=generic))
791: else:
792: searchResult=re.search(searchMD[field],object.getMDValue(field,generic=generic))
793: if searchResult:
794: flag=1
795: else:
796: flag=0
797: break
798: if flag==1:
799: ids.append(object)
800: else:
801: ids.append(object)
802: if not sortfield:
803: sortfield=getattr(self,'sortfield','weight')
804: tmplist=[]
805: for x in ids:
806: if hasattr(x,sortfield):
807: try:
808: tmp=int(getattr(x,sortfield))
809: except:
810: tmp=getattr(x,sortfield)
811:
812: else:
813: tmp=10000000
814:
815: tmplist.append((tmp,x))
816:
817: if not sortFieldMD:
818: tmplist.sort(sort)
819: else:
820: tmplist.sort(sortWithMD(sortFieldMD))
821:
822: ret=[x for (key,x) in tmplist]
823:
824: return ret
825:
826: def ECHO_rerenderLinksMD(self,obj=None,types=['title','label']):
827: """Rerender all Links"""
828: ret=""
829:
830: if not obj:
831: obj = self
832:
833: entries=obj.ZopeFind(obj,obj_metatypes=['ECHO_resource'],search_sub=1)
834:
835: for entry in entries:
836: if entry[1].meta_type == 'ECHO_resource':
837: try:
838: entry[1].ECHO_getResourceMD(template="no",overwrite="yes")
839: logging.debug("ECHO_rerenderLinksMD: gotMD")
840: if "title" in types:
841: entry[1].generate_title()
842: logging.debug("ECHO_rerenderLinksMD: generatedTitle")
843: if "label" in types:
844: entry[1].generate_label()
845: logging.debug("ECHO_rerenderLinksMD: generatedLabel")
846: ret+="OK:"+entry[0]+"-- "+self.unicodify(entry[1].getTitle())+"-- "+self.unicodify(entry[1].getTitle())+"<br>"
847: except:
848:
849: ret+="Error:"+entry[0]+"<br>"
850: logging.debug("ECHO_rerenderLinksMD: error")
851: logging.debug("%s %s"%(sys.exc_info()[0],sys.exc_info()[1]))
852:
853:
854:
855: return "<html><body>"+ret+"Rerenderd all links to resources in: "+self.title+"</html></body>"
856:
857:
858:
859: def getRDFDescription(self,linkURL,urn=None,nameDef=None,typeName=None,ap=""):
860: """rdf"""
861:
862: ret=""
863: about="""<rdf:Description rdf:about="%s">"""
864: name="""<echonavigation:name>%s</echonavigation:name>"""
865: link="""<echonavigation:link xlink:href="%s">%s</echonavigation:link>"""
866: clickable="""<echonavigation:linkClickable>%s</echonavigation:linkClickable>"""
867: #link="""<echonavigation:link rdf:about="%s"/>"""
868: type="""<echonavigation:type>%s</echonavigation:type>"""
869:
870: #xlink="""<echonavigation:xlink xlink:href="%s"/>"""
871:
872: if ap=="":
873: ap2=""
874: else:
875: ap2 = """<mpiwg:archive-path>%s</mpiwg:archive-path>"""%ap
876:
877: if not urn:
878: #urn="urn:"+re.sub('/',':',self.absolute_url())
879: urn=self.absolute_url()
880: about2=about%urn
881: if not nameDef:
882: if hasattr(self,'label') and not (self.label==""):
883: name2=name%self.label
884: elif not self.title=="":
885: name2=name%self.title
886: else:
887: name2=name%self.getId()
888:
889: name2=re.sub('&','&',name2)
890: else:
891: name2=name%nameDef
892:
893: linkURL=re.sub('http:','',linkURL)
894: linkURL2=re.sub('&','&',linkURL)
895: link2=link%(("http:"+linkURL2),("http:"+urllib.quote(linkURL)))
896: clickable2=clickable%"true"
897:
898: if not typeName:
899: type2=type%self.meta_type
900: else:
901: type2=type%typeName
902:
903:
904:
905: #ret=about2+"\n"+name2+"\n"+link2+"\n"+type2+"\n"+clickable2+"\n</rdf:Description>"
906: try:
907: ret=about2+"\n"+name2+"\n"+type2+"\n"+clickable2+"\n"+ap2+"\n</rdf:Description>"
908: except:
909: ret=self.unicodify(about2)+"\n"+self.unicodify(name2)+"\n"+self.unicodify(type2)+"\n"+self.unicodify(clickable2)+"\n"+self.unicodify(ap2)+"\n</rdf:Description>"
910:
911: return ret
912:
913: def getCopyrightsFromForm(self,argv):
914: medias={}
915: partners={}
916: copyrights={}
917:
918: copyrightsFinal=[]
919: for arg in argv.keys():
920:
921: if arg[0:5]=='media':
922: nm=int(arg[5:])
923: medias[nm]=argv[arg]
924: elif arg[0:5]=='partn':
925: nm=int(arg[5:])
926: partners[nm]=argv[arg]
927: elif arg[0:5]=='copyr':
928: nm=int(arg[5:])
929: copyrights[nm]=argv[arg]
930:
931:
932:
933: copyrightsList=[(medias[nm],partners[nm],copyrights[nm]) for nm in medias.keys()]
934: for copyright in copyrightsList:
935:
936: if copyright[2]=='institution0000':
937: copyrightsFinal.append((copyright[0],copyright[1],self.getPartnerCopyright(copyright[1],'')))
938: else:
939: if not copyright[0]=='':
940: copyrightsFinal.append(copyright)
941:
942:
943: return copyrightsFinal
944:
945: #List of different types for the graphical linking viewer
946: viewClassificationListMaster=['view point','area']
947:
948:
949: def checkDiffs(self,metadict):
950: """check differences"""
951:
952:
953:
954:
955: def NoneToEmpty(obj):
956: if obj:
957: return obj
958: else:
959: return ""
960:
961:
962:
963: diffs={}
964:
965: tags=self.findTagsFromMapping(self.contentType)
966: self.referencetypes=tags[2]
967: self.fields=tags[3]
968:
969:
970: for field in tags[1]:
971: try:
972: if (NoneToEmpty(self.getMDValue(self.getFieldTag(tags,field)))==metadict[self.getFieldTag(tags,field)]):
973: diffs[self.getFieldTag(tags,field)]=1
974: else:
975:
976: diffs[self.getFieldTag(tags,field)]=0
977: except:
978: diffs[self.getFieldTag(tags,field)]=0
979:
980: return diffs
981:
982:
983: def zptFile(self, path, orphaned=False):
984: """returns a page template file from the product"""
985: if orphaned:
986: # unusual case
987: pt=PageTemplateFile(os.path.join(package_home(globals()), path))
988: else:
989:
990: pt=PageTemplateFile(os.path.join(package_home(globals()), path)).__of__(self)
991: return pt
992:
993:
994: def findObjectPath(startobject, filename):
995: """returns the object with the name filename starting at startobject"""
996: if startobject is None:
997: return None
998: paths = filename.split('/')
999: object = startobject
1000: for path in paths:
1001:
1002: if hasattr(object, path):
1003: object = getattr(object, path)
1004: else:
1005: object = None
1006: break
1007: return object
1008:
1009:
1010: def zptObjectOrFile(self, filename, localdir='zpt', orphaned=False):
1011: """returns a page template instance or a file from the product"""
1012: # look for an object called path
1013: pt = findObjectPath(self, filename)
1014: # the object should also not be a python function
1015: if (pt is None) or isinstance(pt, types.FunctionType):
1016: # get a ZPT file
1017: pt = zptFile(self, localdir+'/'+filename, orphaned=orphaned)
1018: return pt
1019:
1020:
1021: def sendFile(self, filename, type):
1022: """sends an object or a local file (in the product) as response"""
1023: # look for an object called filename
1024: object = findObjectPath(self, filename)
1025: if object:
1026: # if the object exists then send it
1027: return object.index_html(self.REQUEST.REQUEST, self.REQUEST.RESPONSE)
1028: else:
1029: # send a local file with the given content-type
1030: fn = os.path.join(package_home(globals()), filename)
1031: self.REQUEST.RESPONSE.setHeader("Content-Type", type)
1032: self.REQUEST.RESPONSE.write(file(fn).read())
1033: return
1034:
1035:
1036: def browserType(zope):
1037: """check the browsers request to find out the browser type"""
1038: bt = {}
1039: ua = zope.REQUEST.get_header("HTTP_USER_AGENT")
1040: bt['ua'] = ua
1041: bt['isN4'] = False
1042: bt['isIE'] = False
1043: if string.find(ua, 'MSIE') > -1:
1044: bt['isIE'] = True
1045: else:
1046: bt['isN4'] = string.find(ua, 'Mozilla/4.') > -1
1047: try:
1048: nav = ua[string.find(ua, '('):]
1049: bt['nav'] = nav
1050: ie = string.split(nav, "; ")[1]
1051: if string.find(ie, "MSIE") > -1:
1052: bt['versIE'] = string.split(ie, " ")[1]
1053: except: pass
1054:
1055: bt['isMac'] = string.find(ua, 'Macintosh') > -1
1056: bt['isWin'] = string.find(ua, 'Windows') > -1
1057: bt['isIEWin'] = bt['isIE'] and bt['isWin']
1058: bt['isIEMac'] = bt['isIE'] and bt['isMac']
1059: return bt
1060:
1061:
1062: def writeMetadata(url,metadict,project=None,startpage=None,xslt=None,thumbtemplate=None,topbar=None,digiLibTemplate=None,xmlfrag=None,digiliburlprefix=None):
1063: """Einlesen der Metadaten und und erstellen des geaenderten XML file"""
1064:
1065: def updateTextToolNode(tag,value):
1066:
1067: metanode=dom.getElementsByTagName('texttool')[0]
1068: try:
1069: nodeOld=metanode.getElementsByTagName(tag)
1070: except:
1071: nodeOld=None
1072:
1073: if nodeOld:
1074: metanode.removeChild(nodeOld[0]).unlink()
1075:
1076: node=dom.createElement(tag)
1077: nodetext=dom.createTextNode(value)
1078: node.appendChild(nodetext)
1079: metanode.appendChild(node)
1080:
1081:
1082: if xmlfrag:
1083: geturl="""<?xml version="1.0" encoding="UTF-8" ?>
1084: <resource type="MPIWG">
1085: <meta>
1086: <bib type="Book">
1087: </bib>
1088: </meta>
1089: </resource>"""
1090: dom=xml.dom.minidom.parseString(geturl)
1091: else:
1092: try:
1093: geturl=""
1094: for line in urlopen(url).readlines():
1095: geturl=geturl+line
1096:
1097:
1098: except:
1099: logger("ECHO writeMetadata",logging.ERROR,"XCannot open: "+url)
1100: return (None,"XCannot open: "+url)
1101:
1102: try:
1103: dom=xml.dom.minidom.parseString(geturl)
1104: except:
1105: logger("ECHO writeMetadata",logging.ERROR,"Cannot parse: "+url+"<br>"+geturl)
1106: return (None,"Cannot parse: "+url+"<br>"+geturl)
1107:
1108:
1109:
1110: metanodes=dom.getElementsByTagName('bib')
1111:
1112: if not metanodes:
1113: metanodes=dom.getElementsByTagName('archimedes')
1114:
1115: metanode=metanodes[0]
1116:
1117: for metaData in metadict.keys():
1118: if metaData:
1119: try:
1120: nodeOld=metanode.getElementsByTagName(metaData)
1121: except:
1122: nodeOld=None
1123:
1124: if nodeOld:
1125: metanode.removeChild(nodeOld[0]).unlink()
1126: else:
1127: # try also old writing rule - instead of _:
1128: try:
1129: nodeOld=metanode.getElementsByTagName(re.sub('_','-',metaData))
1130: except:
1131: nodeOld=None
1132:
1133: if nodeOld:
1134: metanode.removeChild(nodeOld[0]).unlink()
1135:
1136:
1137: metanodeneu=dom.createElement(metaData)
1138: try:
1139: metanodetext=dom.createTextNode(metadict[metaData].decode('utf-8'))
1140: except:
1141: metanodetext=dom.createTextNode(metadict[metaData])
1142: #try:
1143:
1144: #metanodetext=dom.createTextNode(unicode(metadict[metaData],"utf-8"))
1145: #except:
1146: #metanodetext=dom.createTextNode(metadict[metaData].encode('utf-8'))
1147: metanodeneu.appendChild(metanodetext)
1148: metanode.appendChild(metanodeneu)
1149:
1150:
1151:
1152:
1153:
1154: if project:
1155: updateTextToolNode('project',project)
1156:
1157: if startpage:
1158: updateTextToolNode('startpage',startpage)
1159:
1160: if topbar:
1161: updateTextToolNode('toptemplate',topbar)
1162:
1163: if thumbtemplate:
1164: updateTextToolNode('thumbtemplate',thumbtemplate)
1165:
1166: if xslt:
1167: updateTextToolNode('xslt',xslt)
1168:
1169:
1170: if digiliburlprefix:
1171: updateTextToolNode('digiliburlprefix',digiliburlprefix)
1172:
1173: try:
1174:
1175: return dom.toxml(encoding='utf-8').encode('utf-8')
1176: except:
1177:
1178:
1179: return dom.toxml(encoding='utf-8')
1180:
1181:
1182:
1183:
1184: class MapArea(SimpleItem):
1185: """simple class to hold coordinates"""
1186:
1187: meta_type = 'MapArea'
1188: # Create a SecurityInfo for this class.
1189: security = ClassSecurityInfo()
1190: security.setDefaultAccess("allow")
1191: # type constants
1192: TYPE_AREA = 'area'
1193: TYPE_ARROW = 'arrow'
1194: TYPE_TEXT = 'text'
1195:
1196: def __init__(self, id, coords, label=None, type=None, tip=None, permanent=False):
1197: """init"""
1198: self.coords = coords[0:4]
1199: if len(coords) > 4:
1200: self.angle = coords[4]
1201: else:
1202: self.angle = 0
1203: self.id = id
1204: self.label = label
1205: self.setType(type)
1206: self.tip = tip
1207: self.permanent = permanent
1208:
1209: def setCoords(self, coords):
1210: """sets the coords"""
1211: self.coords = coords
1212:
1213: def getCoordString(self):
1214: """returns coordinates as a string"""
1215: return string.join(self.coords, ',')
1216:
1217: def setCoordString(self, coordstring):
1218: """sets coordinates from a string"""
1219: coords = string.split(coordstring, ',')
1220: self.coords = [c.strip() for c in coords]
1221:
1222: def getFullId(self, prefix=None):
1223: """returns the id with prefixed parent id"""
1224: if prefix is None:
1225: if hasattr(self, 'aq_parent'):
1226: prefix = self.aq_parent.id
1227: else:
1228: prefix = "id"
1229: fid = prefix + "." + self.id
1230: return fid
1231:
1232: def getType(self):
1233: """returns the type"""
1234: return self.type
1235:
1236: def setType(self, type):
1237: """sets the type"""
1238: if type == MapArea.TYPE_ARROW:
1239: self.type = MapArea.TYPE_ARROW
1240: elif type == MapArea.TYPE_AREA:
1241: self.type = MapArea.TYPE_AREA
1242: elif type == MapArea.TYPE_TEXT:
1243: self.type = MapArea.TYPE_TEXT
1244: else:
1245: self.type = MapArea.TYPE_AREA
1246:
1247: def isTypeArea(self):
1248: """returns if the type is area"""
1249: return self.type == MapArea.TYPE_AREA
1250:
1251: def isTypeArrow(self):
1252: """returns if the type is arrow"""
1253: return self.type == MapArea.TYPE_ARROW
1254:
1255: def isTypeText(self):
1256: """returns if the type is text"""
1257: return self.type == MapArea.TYPE_TEXT
1258:
1259: def getAngle(self):
1260: """returns the angle"""
1261: return self.angle
1262:
1263: def setAngle(self, angle):
1264: """sets the angle"""
1265: self.angle = angle
1266:
1267: def getTip(self):
1268: """returns the popup text"""
1269: # patch old version
1270: if not hasattr(self, 'tip'):
1271: self.tip = self.text
1272:
1273: if self.tip is None:
1274: if hasattr(self, 'aq_parent'):
1275: parent = self.aq_parent
1276: if parent.contentType == 'text-popup':
1277: return parent.description
1278: return self.tip
1279:
1280: def setTip(self, text):
1281: """sets the text"""
1282: self.tiptext = text
1283:
1284: def getText(self):
1285: """returns the text fpr the area"""
1286: if hasattr(self, 'aq_parent'):
1287: parent = self.aq_parent
1288: text = parent.getMapText()
1289: if text is not None:
1290: #return text.document_src()
1291: return text()
1292: return ""
1293:
1294: def getLabel(self):
1295: """returns the link label"""
1296: if self.label is None:
1297: if hasattr(self, 'aq_parent'):
1298: return self.aq_parent.label or self.aq_parent.id
1299: return self.label
1300:
1301: def getTargetUrl(self):
1302: """returns the URL of the linked object"""
1303: if hasattr(self, 'aq_parent'):
1304: p = self.aq_parent
1305: # ECHOResource and ECHOLink have 'link' attribute
1306: if hasattr(p, 'link'):
1307: if p.link is None:
1308: # return empty string for empty link
1309: return ""
1310: else:
1311: return p.link
1312:
1313: # return None for unknown type
1314: return None
1315:
1316: def setLabel(self, label):
1317: """sets the label"""
1318: self.label = label
1319:
1320: def isPermanent(self):
1321: """returns the permanent state"""
1322: # patch old objects
1323: if not hasattr(self, 'permanent'):
1324: self.permanent = False
1325: return self.permanent
1326:
1327: def setPermanent(self, state):
1328: """sets the permanent state"""
1329: if state:
1330: self.permanent = True
1331: else:
1332: self.permanent = False
1333:
1334: def getLinkId(self):
1335: if hasattr(self, 'aq_parent'):
1336: return self.aq_parent.id
1337: return self.id
1338:
1339: # call this to initialize framework classes, which
1340: # does the right thing with the security assertions.
1341: Globals.InitializeClass(MapArea)
1342:
1343:
1344: class MapText(Folder,ZopePageTemplate):
1345: """class to hold text for map areas"""
1346:
1347: meta_type = 'ECHO_mapText'
1348: # Create a SecurityInfo for this class.
1349: security = ClassSecurityInfo()
1350: security.setDefaultAccess("allow")
1351:
1352:
1353: _default_content_fn = os.path.join(package_home(globals()),
1354: 'html', 'ECHO_mapText_default.html')
1355:
1356: def __init__(self, id, text=None, content_type=None):
1357: self.id = str(id)
1358: self.ZBindings_edit(self._default_bindings)
1359: if text is None:
1360: text = open(self._default_content_fn).read()
1361: if content_type is None:
1362: content_type = self.content_type
1363: self.pt_edit(text, content_type)
1364:
1365: def createLocale(self):
1366: """create locale"""
1367: return ECHO_collection.manage_addECHO_localeForm(self)
1368:
1369: manage_main=ZopePageTemplate.pt_editForm
1370:
1371: def manage_addECHO_locale(self,lang,title,label,text=None,content_type=None,RESPONSE=None):
1372: """manage add echo locale in map"""
1373: ECHO_collection.manage_addECHO_locale(self,lang,title,label,text,content_type)
1374: if RESPONSE is not None:
1375: RESPONSE.redirect('manage_main')
1376:
1377:
1378: def changeLocale(self):
1379: """change locale"""
1380: return self.locale_en.change_ECHO_localeForm()
1381:
1382: def change_ECHO_locale(self,lang,title,label,text=None,content_type=None,RESPONSE=None):
1383: """change echo locale"""
1384:
1385: obj= self.locale_en.change_ECHO_locale(lang,title,label,text,content_type,RESPONSE)
1386:
1387:
1388:
1389: if RESPONSE is not None:
1390: RESPONSE.redirect('manage_main')
1391:
1392:
1393: # Product registration and Add support
1394: manage_addMapTextForm = PageTemplateFile(
1395: 'zpt/AddECHO_mapText', globals(), __name__='manage_addMapTextForm')
1396:
1397: def manage_addMapText(self, id, title=None, text=None,
1398: REQUEST=None, submit=None):
1399: "Add a Map Text with optional file content."
1400:
1401: id = str(id)
1402: if REQUEST is None:
1403: self._setObject(id, MapText(id, text))
1404: ob = getattr(self, id)
1405: if title:
1406: ob.pt_setTitle(title)
1407: return ob
1408: else:
1409: file = REQUEST.form.get('file')
1410: headers = getattr(file, 'headers', None)
1411: if headers is None or not file.filename:
1412: zpt = MapText(id, text)
1413: else:
1414: zpt = MapText(id, file, headers.get('content_type'))
1415:
1416: self._setObject(id, zpt)
1417: if title:
1418: ob = getattr(self, id)
1419: ob.pt_setTitle(title)
1420:
1421: try:
1422: u = self.DestinationURL()
1423: except AttributeError:
1424: u = REQUEST['URL1']
1425:
1426: if submit == " Add and Edit ":
1427: u = "%s/%s" % (u, urllib.quote(id))
1428: REQUEST.RESPONSE.redirect(u+'/manage_main')
1429: return ''
1430:
1431: # call this to initialize framework classes, which
1432: # does the right thing with the security assertions.
1433: Globals.InitializeClass(MapText)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>